Skip to content

Commit

Permalink
Clarify definition of "immutable bytes"
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Sep 29, 2024
1 parent 9c21bee commit cd966df
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/behavior-considered-undefined.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<U>`].

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.
Expand Down Expand Up @@ -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
12 changes: 12 additions & 0 deletions src/destructors.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<i32> = &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
Expand Down

0 comments on commit cd966df

Please sign in to comment.