@@ -952,6 +952,90 @@ func f(a: A, b: B) -> (dependsOn(a) C, B)
952
952
```
953
953
We expect to address this in the near future in a separate proposal.
954
954
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
+
955
1039
### Component lifetime
956
1040
957
1041
In the current design, aggregating multiple values merges their scopes.
0 commit comments