diff --git a/reference/src/glossary.md b/reference/src/glossary.md index 3b9cf4f7..ba1d0f93 100644 --- a/reference/src/glossary.md +++ b/reference/src/glossary.md @@ -1,5 +1,61 @@ ## Glossary +#### Aliasing + +(Please note: a full aliasing model for Rust has not yet been constructed, but +at the moment we can give the following definition. The most developed potential +aliasing model so far is known as "Stacked Borrows", and can be found +[here](https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md).) + +*Aliasing* is any time one pointer or reference points to a "span" of memory +that overlaps with the span of another pointer or reference. A span of memory is +similar to how a slice works: there's a base byte address as well as a length in +bytes. + +Consider the following example: + +```rust +fn main() { + let u: u64 = 7_u64; + let r: &u64 = &u; + let s: &[u8] = unsafe { + core::slice::from_raw_parts(&u as *const u64 as *const u8, 8) + }; + let (head, tail) = s.split_first().unwrap(); +} +``` + +In this case, both `r` and `s` alias each other, since they both point to all of +the bytes of `u`. + +However, `head` and `tail` do not alias each other: `head` points to the first +byte of `u` and `tail` points to the other seven bytes of `u` after it. Both `head` +and `tail` alias `s`, any overlap is sufficient to count as an alias. + +The span of a pointer or reference is the size of the value being pointed to or referenced. + +Depending on the type, you can determine the size as follows: + +* For a type `T` that is [`Sized`](https://doc.rust-lang.org/core/marker/trait.Sized.html) + The span length of a pointer or reference to `T` is found with `size_of::()`. +* When `T` is not `Sized` the story is a little tricker: + * If you have a reference `r` you can use `size_of_val(r)` to determine the + span of the reference. + * If you have a pointer `p` you must unsafely convert that to a reference before + you can use `size_of_val`. There is not currently a safe way to determine the + span of a pointer to an unsized type. + +The [Data layout](./layout.md) chapter also has more information on the sizes of different types. + +One interesting side effect of these rules is that references and pointers to +Zero Sized Types _never_ alias each other, because their span length is always 0 +bytes. + +It is also important to know that LLVM IR has a `noalias` attribute that works +somewhat differently from this definition. However, that's considered a low +level detail of a particular Rust implementation. When programming Rust, the +Abstract Rust Machine is intended to operate according to the definition here. + #### Interior mutability *Interior Mutation* means mutating memory where there also exists a live shared reference pointing to the same memory; or mutating memory through a pointer derived from a shared reference.