You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- New example: Escapable properties in a nonescapable type
44
44
45
+
**Edited** (July 31, 2024)
46
+
47
+
- New alternative considered: @lifetime annotation
48
+
- New alternative considered: where clause
49
+
45
50
#### See Also
46
51
47
52
*[Forum discussion of Non-Escapable Types and Lifetime Dependency](https://forums.swift.org/t/pitch-non-escapable-types-and-lifetime-dependency)
@@ -878,14 +883,75 @@ The currently proposed `dependsOn` spelling was chosen to convey the direction o
878
883
879
884
func foo(a: A, b: B) -> dependsOn(a) R
880
885
881
-
This does, however, introduce compound keyword. Alternatively, we could use a simpler `lifetime` keyword, which better matches the feature description. The general syntax would then be:
886
+
This does, however, introduce a keyword with a compound name. Alternatively, we could use a simpler `lifetime` keyword, which better matches the feature description. The general syntax would then be:
882
887
883
888
> **lifetime**(*target*: [scoped]*source*)
884
889
885
890
APIs with ambiguous depenencies would then typically be spelled:
886
891
887
892
func foo(a: A, b: B) -> lifetime(a) R
888
893
894
+
### @lifetime annotation
895
+
896
+
Instead of committing to a final, lightweight syntax, we can start with a single `@lifetime` annotation. It would take this form:
`target` can be `self`, any parameter name, or, most commonly an empty string which implies the function result. `source` can be `self` or any parameter name. The most common usage would be:
905
+
906
+
```
907
+
@lifetime(copy arg)
908
+
func foo(arg: Arg1) -> R {}
909
+
```
910
+
911
+
The `.component` qualifier is only relevant once we have component lifetimes. See the "Component lifetime" section below.
912
+
913
+
An annotation has some advantages over a lighter-weight type modifier sytax:
914
+
915
+
The `@` sigil is helpful to distinguish lifetime dependence information from regular function syntax.
916
+
917
+
A position-independent annotation has an advantage that the fully expressive syntax is more self-evident. This makes it easier to educate reviewers about what is possible with the syntax.
918
+
919
+
The type modifier can occur in any type position within a function signature, in including before the `func` keyword for the 'self' type. This has potential readability problems when it comes to more complicated cases. Nested parentheses (`dependsOn(...)`) that can occur anywhere in the signature are visually confusing.
920
+
921
+
In the future, the single `@lifetime` annotation could be a useful modifier for other kinds declarations such as types and properties:
922
+
923
+
```
924
+
// Allow two components to have distinct lifetimes...
925
+
struct Pair<T: ~Escapable> {
926
+
@lifetime
927
+
var x: T
928
+
929
+
@lifetime
930
+
var y: T
931
+
}
932
+
933
+
// Allow two components to have dependent lifetimes...
934
+
struct Node: ~Escapable {
935
+
@lifetime
936
+
var parent: Node
937
+
938
+
@lifetime(parent)
939
+
var child: Node
940
+
}
941
+
942
+
// Declare an abstract lifetime and alias it with another lifetime.
943
+
@lifetime(elements: storage.elements)
944
+
struct Container {
945
+
var storage: Storage
946
+
}
947
+
```
948
+
949
+
### `where` clause
950
+
951
+
Some have advocated for a `where` clause on the function declaration. The function name could stand-in for its result, and directionality could be indicated with a comparison operator:
952
+
953
+
`func foo(arg: Arg) -> R where lifetime(foo) < lifetime([copy|borrow|mutate] arg)`
954
+
889
955
### dependsOn(unchecked) to disable lifetime dependence checking
890
956
891
957
A `dependsOn(unchecked)` annotation could allow programmers to disable lifetime dependence checking for a function result or argument. For example, the programmer may want to compose a nonescapable result from an immortal value that isn't visible to the compiler:
0 commit comments