Skip to content

Commit 71f8b1c

Browse files
authored
Merge pull request rust-lang#170 from Lokathor/lokathor
Initial Glossary entry for Aliasing
2 parents 3b5a851 + 37b3055 commit 71f8b1c

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

reference/src/glossary.md

+56
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,61 @@
11
## Glossary
22

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+
359
#### Interior mutability
460

561
*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

Comments
 (0)