@@ -952,6 +952,90 @@ func f(a: A, b: B) -> (dependsOn(a) C, B)
952952```
953953We expect to address this in the near future in a separate proposal.
954954
955+ ### Function type syntax
956+
957+ A function that returns a nonescapable type cannot currently be passed as a nonescaping closure because its dependence information would be lost.
958+
959+ ``` swift
960+ func f (arg : ArgType) -> dependsOn(arg) NEType
961+
962+ func g1 (closure : (ArgType) -> NEType)
963+
964+ {
965+ g1 (closure : f) // 🛑 ERROR: function type mismatch
966+ }
967+ ```
968+
969+ To address this shortcoming, we plan to extend the ` dependsOn(...) ` modifier for use in function types. Since function
970+ types have no parameter names, the parameter position will be identified by an integer literal:
971+
972+ ``` swift
973+ func g2 (closure : (ArgType) -> dependsOn(0) NE)
974+
975+ {
976+ g2 (closure : f) // ✅ OK
977+ }
978+ ```
979+
980+ The parameter index syntax is consistent with how dependencies are already represented internally and in mangled names.
981+
982+ We expect most closures that return nonescapable types to be dependent on the closure context rather than a closure
983+ parameter--this will be the normal case for passing methods as nonescaping closures. A closure context dependence will
984+ not affect the spelling of the function type.
985+
986+ ### Lifetime dependence for closures
987+
988+ In "Function type syntax", we propose that function types can have explicit ` dependsOn ` modifiers. When a function type
989+ returns a nonescapable value but has no explicit ` dependsOn ` modifier, we plan to infer a dependence on the closure
990+ context:
991+
992+ ``` swift
993+ func g1 (closure : () -> NEType) // Inferred: NEType depends on 'closure'
994+ ```
995+
996+ For closure declarations, lifetime dependencies can be inferred on the combined list of captures and closure parameters
997+ following the same rule as free standing functions. We can infer a lifetime dependence if the closure's return value is
998+ nonescapable, and exactly one closure capture or closure parameter satisfies any of the following:
999+
1000+ - is nonescapable, or
1001+ - is non-BitwiseCopyable and has an explicit ` borrowing ` , or ` inout ` convention
1002+
1003+ A dependence can be inferred on a closure capture as follows:
1004+
1005+ ``` swift
1006+ func f (arg : borrowing ArgType) -> dependsOn(arg) NEType
1007+
1008+ func foo (source : borrowing ArgType) {
1009+ g1 { f (arg : source) } // ✅ Inferred: 'closure' result depends on captured 'source'
1010+ }
1011+ ```
1012+
1013+ An explicit dependence on a closure capture can be spelled:
1014+
1015+ ``` swift
1016+ func foo (source : borrowing ArgType) {
1017+ g1 { () -> dependsOn (source) NEType in f (arg : source) }
1018+ }
1019+ ```
1020+
1021+ Similarly, a dependence can be inferred on a closure parameter:
1022+
1023+ ``` swift
1024+ func g2 (closure : (borrowing ArgType) -> dependsOn(0) NEType)
1025+
1026+ {
1027+ g2 { (source : borrowing ArgType) in f (arg : source) } // ✅ Inferred: 'closure' result depends on 'source' parameter
1028+ }
1029+ ```
1030+
1031+ An explicit dependence on a closure parameter can be spelled:
1032+
1033+ ``` swift
1034+ {
1035+ g2 { (source : borrowing ArgType) -> dependsOn (source) NEType in f (arg : source) } // ✅ Inferred: 'closure' result depends on 'source' parameter
1036+ }
1037+ ```
1038+
9551039### Component lifetime
9561040
9571041In the current design, aggregating multiple values merges their scopes.
0 commit comments