Allowing explicit @escaping for optional closures in function parameters

Any other suggestions on how to change the proposal ?
Which would be the next step to get it implemented? Should I partner with someone from the core team? It doesn't seem to be something that could be implemented by a beginner in swift code base. :frowning:

You don't want someone from the "core team", which is the project design/leadership group; you want someone with implementation expertise. If you're willing to do the implementation work yourself, @Andrew_Trick knows the mandatory-escape-analysis code and told me he was willing to guide you through what you'd need to do.

2 Likes

I'm absolutely more than happy to do the work myself under the supervision of @Andrew_Trick , if it's ok for him.

Thank you so much @John_McCall and @Andrew_Trick

I do think this is a serious usability flaw that should be fixed. Unfortunately implementing the diagnostic is involved. Let me know if this makes sense @Slava_Pestov @xedin ...

My intuition is that the existing diagnostics can be extended to handle optional function types. Most of those diagnostics are in the type checker's constraint solver (see MarkExplicitlyEscaping). Currently, whenever the type system unwraps an optional function type, it assumes an escaping type. Instead, we need to give the optional a noescape type (see TVO_CanBindToNoEscape) and infer a noescape function type when unwraps the optional type. Then, the actual diagnostics within MarkExplicitlyEscaping need to be generalized for non-function types.

A secondary round of diagnostics in SIL ensures that nonescaping functions don't aren't captured by escaping closures. This is the part I'm familiar with. It's the DiagnoseInvalidEscapingCaptures pass.

It checks that @noescape types aren't captured by an escaping closure:

And that @noescape function parameters aren't passed into other @noescape functions

Both of these would also need to be extended for optionals. checkNoEscapePartialApplyUse also needs to be fixed to recognized that nonescaping closures can be stored a nonescaping optional. Since optionals don't have a special representation in SIL, it needs to look for an 'enum' instruction. These extensions to the pass should not be too hard as long as optional's AST type can be marked "noescape". See TypeBase::isNoEscape().

6 Likes

One thing to note is that SILGen and the SIL optimizer passes already have some minimal support for optionals of no-escape type, because even though you cannot write such a type in source, it comes up in the signatures of imported Objective-C methods, and therefore, bridging thunks emitted by SIL.

4 Likes

@Andrew_Trick Yes, what you have mentioned is exactly what needs to be done. We'd just need to special case optional function type case where Wrapped generic parameter should be opened into a type variable with TVO_CanBindToNoEscape flag, or (most likely) add a new TVO_CanBindToNoEscapeFunction flag to make it more distinct, and adjust diagnostics related to MarkExplicitlyEscaping accordingly. It seems like this should be feasible for beginners. @GLanza if you need any help with implementation please let me know.

2 Likes