@@ -2414,27 +2414,55 @@ Variable Lifetimes
24142414In order for programmer intended lifetimes to be maintained under optimization,
24152415the lifetimes of SIL values which correspond to named source-level values can
24162416only 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:
24222444
242324451: `begin_borrow [lexical] `
242424462: `move_value [lexical] `
2425- 3: @owned function arguments
2447+ 3: function arguments
242624484: `alloc_stack [lexical] `
24272449
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 `).
2456+
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.
24302460
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.
2461+ When a function is inlined into its caller, a lexical borrow scope is added for
2462+ each of its @guaranteed arguments, and a lexical move is added for each of its
2463+ @owned arguments, (unless the values being passed are already lexical
2464+ themselves) ensuring that the lifetimes of the corresponding source-level
2465+ values are not shortened in a way that doesn't respect deinit barriers.
24382466
24392467Unlike the other sorts, `alloc_stack [lexical] ` isn't a SILValue. Instead, it
24402468constrains the lifetime of an addressable variable. Since the constraint is
0 commit comments