Skip to content

Commit fcafd6c

Browse files
committed
glossary: define place, value, representation
1 parent d86d39c commit fcafd6c

File tree

1 file changed

+37
-59
lines changed

1 file changed

+37
-59
lines changed

reference/src/glossary.md

Lines changed: 37 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,5 @@
11
## Glossary
22

3-
#### Aliasing
4-
5-
*Aliasing* occurs when one pointer or reference points to a "span" of memory
6-
that overlaps with the span of another pointer or reference. A span of memory is
7-
similar to how a slice works: there's a base byte address as well as a length in
8-
bytes.
9-
10-
**Note**: a full aliasing model for Rust, defining when aliasing is allowed
11-
and when not, has not yet been defined. The purpose of this definition is to
12-
define when aliasing *happens*, not when it is *allowed*. The most developed
13-
potential aliasing model so far is known as "Stacked Borrows", and can be found
14-
[here](https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md).
15-
16-
Consider the following example:
17-
18-
```rust
19-
fn main() {
20-
let u: u64 = 7_u64;
21-
let r: &u64 = &u;
22-
let s: &[u8] = unsafe {
23-
core::slice::from_raw_parts(&u as *const u64 as *const u8, 8)
24-
};
25-
let (head, tail) = s.split_first().unwrap();
26-
}
27-
```
28-
29-
In this case, both `r` and `s` alias each other, since they both point to all of
30-
the bytes of `u`.
31-
32-
However, `head` and `tail` do not alias each other: `head` points to the first
33-
byte of `u` and `tail` points to the other seven bytes of `u` after it. Both `head`
34-
and `tail` alias `s`, any overlap is sufficient to count as an alias.
35-
36-
The span of a pointer or reference is the size of the value being pointed to or referenced.
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-
593
#### Interior mutability
604

615
*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.
@@ -129,10 +73,44 @@ niches. For example, the "all bits uninitialized" is an invalid bit-pattern for
12973
`&mut T`, but this bit-pattern cannot be used by layout optimizations, and is not a
13074
niche.
13175

76+
#### Place
77+
78+
A *place* (called "lvalue" in C and "glvalue" in C++) is the result of computing a [*place expression*][place-value-expr].
79+
A place is basically a pointer (pointing to some location in memory, potentially carrying [provenance](#pointer-provenance)), but might contain more information such as size or alignment (the details will have to be determined as the Rust Abstract Machine gets specified more precisely).
80+
A place has a type.
81+
Places cannot be "stored" in memory, only [values](#value) can.
82+
83+
The key operations on a place are:
84+
* storing a [value](#value) of the same type in it (when it is used on the left-hand side of an assignment),
85+
* turning it into a [pointer value](#value) (when it is used inside `&expr`),
86+
* and loading a [value](#value) of the same type from it (through the place-to-value coercion).
87+
88+
89+
#### Value
90+
91+
A *value* (called "value of the expression" or "rvalue" in C and "prvalue" in C++) is what gets stored in a [place](#place), and also the result of computing a [*value expression*][place-value-expr].
92+
A value has a type, and it denotes the abstract mathematical concept that is represented by data in our programs.
93+
For example, a value of type `u8` is a mathematical integer in the range `0..256`.
94+
Values can be (according to their type) turned into a list of bytes, which is called a [representation](#representation) of the value.
95+
Values are ephemeral; they arise during the computation of an instruction but are only ever persisted in memory through their representation.
96+
(This is comparable to how run-time data in a program is ephemeral and is only ever persisted in serialized form.)
97+
98+
#### Representation (relation)
99+
100+
A *representation* of a [value](#value) is a list of bytes that is used to store or "represent" that value in memory.
101+
102+
We also sometimes speak of the *representation of a type*; this should more correctly be called the *representation relation* as it relates values of this type to lists of bytes that represent this value.
103+
The term "relation" here is used in the mathematical sense: the representation relation is a predicate that, given a value and a list of bytes, says whether this value is represented by that list of bytes (`val -> list byte -> Prop`).
104+
105+
The relation should be functional for a fixed list of bytes (i.e., every list of bytes has at most one associated representation).
106+
It is partial in both directions: not all values have a representation (e.g. the mathematical integer `300` has no representation at type `u8`), and not all lists of bytes correspond to a value of a specific type (e.g. lists of the wrong size correspond to no value, and the list consisting of the single byte `0x10` corresponds to no value of type `bool`).
107+
For a fixed value, there can be many representations (e.g., when considering type `#[repr(C)] Pair(u8, u16)`, the second byte is a padding byte so changing it does not affect the value represented by a list of bytes).
108+
109+
See the [value domain][value-domain] for an example how values and representation relations can be made more precise.
132110

133111
### TODO
134112

135113
* *tag*
136-
* *rvalue*
137-
* *lvalue*
138-
* *representation*
114+
115+
[value-domain]: https://github.com/rust-lang/unsafe-code-guidelines/tree/master/wip/value-domain.md
116+
[place-value-expr]: https://doc.rust-lang.org/reference/expressions.html#place-expressions-and-value-expressions

0 commit comments

Comments
 (0)