diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index a11e67aec..abd814e02 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -43,22 +43,18 @@ r[undefined.place-projection] [array/slice index expression][project-slice]. r[undefined.alias] -* Breaking the [pointer aliasing rules]. `Box`, `&mut T` and `&T` follow - LLVM’s scoped [noalias] model, except if the `&T` contains an - [`UnsafeCell`]. References and boxes must not be [dangling] while they are - live. The exact liveness duration is not specified, but some bounds exist: +* Breaking the pointer aliasing rules. The exact aliasing rules are not determined yet, but here is an outline of the general principles: + `&T` must point to memory that is not mutated while they are live (except for data inside an [`UnsafeCell`]), + and `&mut T` must point to memory that is not read or written by any pointer not derived from the reference and that no other reference points to while they are live. + `Box` is treated similar to `&'static mut T` for the purpose of these rules. + The exact liveness duration is not specified, but some bounds exist: * For references, the liveness duration is upper-bounded by the syntactic - lifetime assigned by the borrow checker; it cannot be live any *longer* than - that lifetime. - * Each time a reference or box is passed to or returned from a function, it is - considered live. - * When a reference (but not a `Box`!) is passed to a function, it is live at - least as long as that function call, again except if the `&T` contains an - [`UnsafeCell`]. - - All this also applies when values of these - types are passed in a (nested) field of a compound type, but not behind - pointer indirections. + lifetime assigned by the borrow checker; it cannot be live any *longer* than that lifetime. + * Each time a reference or box is dereferenced or reborrowed, it is considered live. + * Each time a reference or box is passed to or returned from a function, it is considered live. + * When a reference (but not a `Box`!) is passed to a function, it is live at least as long as that function call, again except if the `&T` contains an [`UnsafeCell`]. + + All this also applies when values of these types are passed in a (nested) field of a compound type, but not behind pointer indirections. r[undefined.immutable] * Mutating immutable bytes. @@ -201,7 +197,7 @@ r[undefined.validity.never] r[undefined.validity.scalar] * An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer must be - initialized, i.e., must not be obtained from [uninitialized memory][undef]. + initialized, i.e., must not be obtained from uninitialized memory. r[undefined.validity.str] * A `str` value is treated like `[u8]`, i.e. it must be initialized. @@ -248,10 +244,7 @@ reading uninitialized memory is permitted are inside `union`s and in "padding" [`bool`]: types/boolean.md [`const`]: items/constant-items.md -[noalias]: http://llvm.org/docs/LangRef.html#noalias -[pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules [abi]: items/external-blocks.md#abi -[undef]: http://llvm.org/docs/LangRef.html#undefined-values [`target_feature`]: attributes/codegen.md#the-target_feature-attribute [`UnsafeCell`]: std::cell::UnsafeCell [Rustonomicon]: ../nomicon/index.html