Skip to content

Commit 3c1e92f

Browse files
committed
Atrick's corrections
1 parent 0c71b72 commit 3c1e92f

File tree

1 file changed

+25
-14
lines changed

1 file changed

+25
-14
lines changed

proposals/NNNN-non-escapable.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -289,33 +289,44 @@ We expect to publish a sample implementation and proposal for that type very soo
289289

290290
#### Initializers and Lifetime Dependencies
291291

292-
All values come into existence within the body of some initializer and are returned to the caller of that initializer.
293-
Since nonescapable types cannot be returned,
294-
it follows that nonescapable types cannot have initializers without some additional language affordance.
295-
296-
A subsequent proposal will provide such an affordance.
297-
This will allow values to be returned subject to the requirement that they not outlive some other specific value.
298-
For example, a nonescapable iterator might be initialized so as to not outlive the container that created it:
292+
Nonescapable function parameters may not outlive the function scope.
293+
Consequently, nonescapable values can never be returned from a function.
294+
Nonescapable values come into existence within the body of the initializer.
295+
Naturally, the initializer must return its value, and this creates an exception to the rule.
296+
Without further language support, implementing a nonescapable initializer requires an unsafe construct.
297+
That unsafe handling is not covered by this proposal because we don't want to surface unnecessary unsafety in the language.
298+
Instead, a subsequent proposal will support safe initialization by allowing the initializer to specify lifetime dependencies on its parameters.
299+
The parameters to the initializer typically indicate a lifetime that the nonescapable value cannot outlive.
300+
An initializer may, for example, create a nonescapable value that depends on a container variable that is bound to an object with its own lifetime:
299301
```swift
300302
struct Iterator: ~Escapable {
301-
// ⚠️️ Returned Iterator will not be allowed to outlive `container`
302-
// Details in a future proposal: This may involve
303-
// additional syntax or default inference rules.
304303
init(container: borrowing Container) { ... }
305304
}
306305

306+
let container = ...
307+
let iterator = Iterator(container)
308+
consume container
309+
use(iterator) // 🛑 'iterator' outlives the source of its dependency
310+
```
311+
312+
Lifetime dependencies will make this use of iterator a compile-time error.
313+
Or, as part of implementing data type internals, a nonescapable initializer may depend on a variable that is bound to a value that is only valid within that variable's local scope.
314+
Subsequent uses of the initialized nonescapable object are exactly as safe or unsafe as it would be to use the variable that the initializer depends at the same point:
315+
316+
```swift
307317
let iterator: Iterator
308318
do {
309319
let container = Container(...)
310320
let buffer = container.buffer
311321
iterator = Iterator(buffer)
312-
// `container` lifetime ends here
322+
// `iterator` is safe as long as `buffer` is safe to use.
313323
}
314-
use(iterator) // 🛑 'iterator' outlives `container`
324+
use(iterator) // 🛑 'iterator' outlives the source of its dependency
315325
```
316326

317-
These lifetime dependencies will be enforced entirely at compile time without any runtime overhead.
318-
Invalid uses such as the one above will produce compiler errors.
327+
Again, lifetime dependencies will make this use of iterator a compile-time error.
328+
Typically, a pointer is valid for the duration of its variable binding.
329+
So, in practice, nonescapable value that depends on the pointer to be available within the same scope.
319330

320331
#### Expanding standard library types
321332

0 commit comments

Comments
 (0)