|
1 | 1 | ## Glossary
|
2 | 2 |
|
| 3 | +#### Aliasing |
| 4 | + |
| 5 | +(Please note: a full aliasing model for Rust has not yet been constructed, but |
| 6 | +at the moment we can give the following definition. The most developed potential |
| 7 | +aliasing model so far is known as "Stacked Borrows", and can be found |
| 8 | +[here](https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md).) |
| 9 | + |
| 10 | +*Aliasing* is any time one pointer or reference points to a "span" of memory |
| 11 | +that overlaps with the span of another pointer or reference. A span of memory is |
| 12 | +similar to how a slice works: there's a base byte address as well as a length in |
| 13 | +bytes. |
| 14 | + |
| 15 | +Consider the following example: |
| 16 | + |
| 17 | +```rust |
| 18 | +fn main() { |
| 19 | + let u: u64 = 7_u64; |
| 20 | + let r: &u64 = &u; |
| 21 | + let s: &[u8] = unsafe { |
| 22 | + core::slice::from_raw_parts(&u as *const u64 as *const u8, 8) |
| 23 | + }; |
| 24 | + let (head, tail) = s.split_first().unwrap(); |
| 25 | +} |
| 26 | +``` |
| 27 | + |
| 28 | +In this case, both `r` and `s` alias each other, since they both point to all of |
| 29 | +the bytes of `u`. |
| 30 | + |
| 31 | +However, `head` and `tail` do not alias each other: `head` points to the first |
| 32 | +byte of `u` and `tail` points to the other seven bytes of `u` after it. Both `head` |
| 33 | +and `tail` alias `s`, any overlap is sufficient to count as an alias. |
| 34 | + |
| 35 | +The span of a pointer or reference is the size of the value being pointed to or referenced. |
| 36 | + |
| 37 | +Depending on the type, you can determine the size as follows: |
| 38 | + |
| 39 | +* For a type `T` that is [`Sized`](https://doc.rust-lang.org/core/marker/trait.Sized.html) |
| 40 | + The span length of a pointer or reference to `T` is found with `size_of::<T>()`. |
| 41 | +* When `T` is not `Sized` the story is a little tricker: |
| 42 | + * If you have a reference `r` you can use `size_of_val(r)` to determine the |
| 43 | + span of the reference. |
| 44 | + * If you have a pointer `p` you must unsafely convert that to a reference before |
| 45 | + you can use `size_of_val`. There is not currently a safe way to determine the |
| 46 | + span of a pointer to an unsized type. |
| 47 | + |
| 48 | +The [Data layout](./layout.md) chapter also has more information on the sizes of different types. |
| 49 | + |
| 50 | +One interesting side effect of these rules is that references and pointers to |
| 51 | +Zero Sized Types _never_ alias each other, because their span length is always 0 |
| 52 | +bytes. |
| 53 | + |
| 54 | +It is also important to know that LLVM IR has a `noalias` attribute that works |
| 55 | +somewhat differently from this definition. However, that's considered a low |
| 56 | +level detail of a particular Rust implementation. When programming Rust, the |
| 57 | +Abstract Rust Machine is intended to operate according to the definition here. |
| 58 | + |
3 | 59 | #### Interior mutability
|
4 | 60 |
|
5 | 61 | *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.
|
|
0 commit comments