Skip to content

Initial Glossary entry for Aliasing #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jul 25, 2019
Merged
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions reference/src/glossary.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,57 @@
## 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/Lokathor/unsafe-code-guidelines/blob/lokathor/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.
* For some 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::<T>()`.
* 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 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.
Expand Down