Skip to content

Commit eb1d88e

Browse files
committed
Update Future component syntax.
1 parent 5555ee6 commit eb1d88e

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

proposals/NNNN-lifetime-dependency.md

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,27 @@ We've discussed how a nonescapable result must be destroyed before the source of
324324
// 'span' now depends on both 'a1' and 'a2'.
325325
```
326326

327+
The general form of the `dependsOn` syntax is:
328+
329+
> **dependsOn**(*target*: *source*)
330+
331+
where `target` can be inferred from context:
332+
333+
- Result modifiers go before the result type (after the `->` sigil)
334+
335+
- Parameter modifiers go before the parameter type
336+
337+
- `self` modifiers always go in front of the `func` declaration.
338+
339+
Although `self` could be inferred, it must be spelled explicitly to avoid confusion with the common case of a result
340+
dependence.
341+
342+
Example:
343+
344+
```
345+
dependsOn(self: arg1) func foo<T, R>(arg1: dependsOn(arg2) T, arg2: T) -> dependsOn(arg2) R
346+
```
347+
327348
### Dependent properties
328349

329350
Structural composition is an important use case for nonescapable types. Getting or setting a nonescapable property requires lifetime dependence, just like a function result or an 'inout' parameter. There's no need for explicit annotation in these cases, because only one dependence is possible. A getter returns a value that depends on `self`. A setter replaces the current dependence from `self` with a dependence on `newValue`.
@@ -845,7 +866,7 @@ This was changed after we realized that there was in practice almost always a si
845866
It should be possible to return a tuple where one part has a lifetime dependency.
846867
For example:
847868
```swift
848-
func f(a: consume A, b: B) -> (consume(a) C, B)
869+
func f(a: A, b: B) -> (dependsOn(a) C, B)
849870
```
850871
We expect to address this in the near future in a separate proposal.
851872

@@ -867,7 +888,7 @@ This could be exposed as an alternate spelling if there were sufficient demand.
867888
func f(arg1: Type1, arg2: Type2, arg3: Type3) -> dependsOn(0) ReturnType
868889
```
869890

870-
### Value component lifetime
891+
### Component lifetime
871892

872893
In the current design, aggregating multiple values merges their scopes.
873894

@@ -900,12 +921,29 @@ struct Container<Element>: ~Escapable {
900921
@lifetime
901922
var b: /*dependsOn(self.b)*/ Element
902923

903-
init(a: Element, b: Element) -> dependsOn(a -> .a, b -> .b) Self {...}
924+
init(arg1: Element, arg2: Element) -> dependsOn(a: arg1, b: arg2) Self {...}
904925
}
905926
```
906927

907928
The nesting level of a component is the inverse of the nesting level of its lifetime. `a` and `b` are nested components of `Container`, but the lifetime of a `Container` instance is nested within both lifetimes of `a` and `b`.
908929

930+
The general form of the `dependsOn` syntax should be thought of as:
931+
932+
> **dependsOn**(*target*.*component*: *source*.*component*)
933+
934+
where the `target` can be inferred from context, but not its component:
935+
936+
Example:
937+
938+
```
939+
struct S: ~Escapable {
940+
@lifetime
941+
let a: T
942+
943+
dependsOn(self.a: arg1) func foo(arg1: dependsOn(a: arg2) S, arg2: T) -> dependsOn(a: arg2) S
944+
}
945+
```
946+
909947
### Abstract lifetime components
910948

911949
Lifetime dependence is not always neatly tied to stored properties. Say that our `Container` now holds multiple elements within its own storage. We can use a top-level `@lifetime` annotation to name an abstract lifetime for all the elements:

0 commit comments

Comments
 (0)