@@ -2414,27 +2414,49 @@ Variable Lifetimes
2414
2414
In order for programmer intended lifetimes to be maintained under optimization,
2415
2415
the lifetimes of SIL values which correspond to named source-level values can
2416
2416
only be modified in limited ways. Generally, the behavior is that the lifetime
2417
- of a named source-level value cannot _observably_ end before the end of the
2418
- lexical scope in which that value is defined. Specifically, code motion may
2419
- not move the ends of these lifetimes across a **deinit barrier **.
2420
-
2421
- A few sorts of SIL value have lifetimes that are constrained that way:
2417
+ of a named source-level value is anchored to the variable's lexical scope and
2418
+ confined by **deinit barriers **. Specifically, code motion may not move the
2419
+ ends of these lifetimes across a deinit barrier.
2420
+
2421
+ Source level variables (lets, vars, ...) and function arguments will result in
2422
+ SIL-level lexical lifetimes if either of the two sets of circumstances apply:
2423
+ (1) Inferred lexicality.
2424
+ - the type is non-trivial
2425
+ - the type is not eager-move
2426
+ - the variable or argument is not annotated to be eager-move
2427
+ OR
2428
+ (2) Explicit lexicality.
2429
+ - the type, variable, or argument is annotated `@_lexical `
2430
+
2431
+ A type is eager-move by satisfying one of two conditions:
2432
+ (1) Inferred: An aggregate is inferred to be eager-move if all of its fields are
2433
+ eager-move.
2434
+ (2) Annotated: Any type can be eager-move if it is annotated with an attribute
2435
+ that explicitly specifies it to be: `@_eagerMove `, `@_noImplicitCopy `.
2436
+
2437
+ A variable or argument is eager-move by satisfying one of two conditions:
2438
+ (1) Inferred: Its type is eager-move.
2439
+ (2) Annotated: The variable or argument is annotated with an attribute that
2440
+ specifies it to be: `@_eagerMove `, `@_noImplicitCopy `.
2441
+
2442
+ These source-level rules result in a few sorts of SIL value whose destroys must
2443
+ not be moved across deinit barriers:
2422
2444
2423
2445
1: `begin_borrow [lexical] `
2424
2446
2: `move_value [lexical] `
2425
- 3: @owned function arguments
2447
+ 3: function arguments
2426
2448
4: `alloc_stack [lexical] `
2427
2449
2428
- That these three have constrained lifetimes is encoded in ValueBase::isLexical,
2429
- which should be checked before changing the lifetime of a value.
2450
+ To translate from the source-level representation of lexicality to the
2451
+ SIL-level representation, for source-level variables (vars, lets, ...) SILGen
2452
+ generates `begin_borrow [lexical] `, `move_value [lexical] `, `alloc_stack
2453
+ [lexical] ` . For function arguments, there is no work to do:
2454
+ a `SILFunctionArgument ` itself can be lexical
2455
+ (`SILFunctionArgument::isLexical `).
2430
2456
2431
- The reason that only @owned function arguments are constrained is that a
2432
- @guaranteed function argument is guaranteed by the function's caller to live for
2433
- the full duration of the function already. Optimization of the function alone
2434
- can't shorten it. When such a function is inlined into its caller, though, a
2435
- lexical borrow scope is added for each of its @guaranteed arguments, ensuring
2436
- that the lifetime of the corresponding source-level value is not shortened in a
2437
- way that doesn't respect deinit barriers.
2457
+ That the first three have constrained lifetimes is encoded in
2458
+ ValueBase::isLexical, which should be checked before changing the lifetime of a
2459
+ value.
2438
2460
2439
2461
Unlike the other sorts, `alloc_stack [lexical] ` isn't a SILValue. Instead, it
2440
2462
constrains the lifetime of an addressable variable. Since the constraint is
0 commit comments