diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 63fa28f63..2d252ed1f 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -40,7 +40,8 @@ undefined behavior, it is *unsound*. All this also applies when values of these types are passed in a (nested) field of a compound type, but not behind pointer indirections. -* Mutating immutable bytes. All bytes inside a [`const`] item or within an implicitly [const-promoted] expression are immutable. +* Mutating immutable bytes. + All bytes reachable through a [const-promoted] expression are immutable, as well as bytes reachable through borrows in `static` and `const` initializers that have been [lifetime-extended] to `'static`. The bytes owned by an immutable binding or immutable `static` are immutable, unless those bytes are part of an [`UnsafeCell`]. Moreover, the bytes [pointed to] by a shared reference, including transitively through other references (both shared and mutable) and `Box`es, are immutable; transitivity includes those references stored in fields of compound types. @@ -179,3 +180,4 @@ reading uninitialized memory is permitted are inside `union`s and in "padding" [project-tuple]: expressions/tuple-expr.md#tuple-indexing-expressions [project-slice]: expressions/array-expr.md#array-and-slice-indexing-expressions [const-promoted]: destructors.md#constant-promotion +[lifetime-extended]: destructors.md#temporary-lifetime-extension diff --git a/src/destructors.md b/src/destructors.md index a536221f4..7cdfaee0f 100644 --- a/src/destructors.md +++ b/src/destructors.md @@ -325,6 +325,18 @@ let x = &mut 0; println!("{}", x); ``` +r[destructors.scope.lifetime-extension.static] +Lifetime extension also applies to `static` and `const` items, where it +makes temporaries live until the end of the program. For example: + +```rust +const C: &Vec = &Vec::new(); +// Usually this would be a dangling reference as the `Vec` would only +// exist inside the initializer expression of `C`, but instead the +// borrow gets lifetime-extended so it effectively has `'static` lifetime. +println!("{:?}", C); +``` + r[destructors.scope.lifetime-extension.sub-expressions] If a [borrow][borrow expression], [dereference][dereference expression], [field][field expression], or [tuple indexing expression] has an extended