Skip to content

Commit 29e71b9

Browse files
committed
niko discussion affects
1 parent fcf4a7e commit 29e71b9

File tree

2 files changed

+23
-12
lines changed

2 files changed

+23
-12
lines changed

atomics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ do exactly what we said but, you know, *fast*. Wouldn't that be great?
2424
# Compiler Reordering
2525

2626
Compilers fundamentally want to be able to do all sorts of crazy transformations
27-
to reduce data dependencies and eleminate dead code. In particular, they may
27+
to reduce data dependencies and eliminate dead code. In particular, they may
2828
radically change the actual order of events, or make events never occur! If we
2929
write something like
3030

references.md

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@ as its direct children. Each variable's direct children would be their fields
2525

2626
From this view, every value in Rust has a unique *path* in the tree of ownership.
2727
References to a value can subsequently be interpreted as a path in this tree.
28-
Of particular interest are *prefixes*: `x` is a prefix of `y` if `x` owns `y`
28+
Of particular interest are *ancestors* and *descendants*: if `x` owns `y`, then
29+
`x` is an *ancestor* of `y`, and `y` is a *descendant* of `x`. Note that this is
30+
an inclusive relationship: `x` is a descendant and ancestor of itself.
2931

30-
However much data doesn't reside on the stack, and we must also accommodate this.
32+
Tragically, plenty of data doesn't reside on the stack, and we must also accommodate this.
3133
Globals and thread-locals are simple enough to model as residing at the bottom
3234
of the stack (though we must be careful with mutable globals). Data on
3335
the heap poses a different problem.
3436

35-
If all Rust had on the heap was data uniquely by a pointer on the stack,
37+
If all Rust had on the heap was data uniquely owned by a pointer on the stack,
3638
then we can just treat that pointer as a struct that owns the value on
3739
the heap. Box, Vec, String, and HashMap, are examples of types which uniquely
3840
own data on the heap.
@@ -51,6 +53,10 @@ types provide exclusive access through runtime restrictions. However it is also
5153
possible to establish unique ownership without interior mutability. For instance,
5254
if an Rc has refcount 1, then it is safe to mutate or move its internals.
5355

56+
In order to correctly communicate to the type system that a variable or field of
57+
a struct can have interior mutability, it must be wrapped in an UnsafeCell. This
58+
does not in itself make it safe to perform interior mutability operations on that
59+
value. You still must yourself ensure that mutual exclusion is upheld.
5460

5561

5662

@@ -61,9 +67,9 @@ dereferenced. Shared references are always live unless they are literally unreac
6167
(for instance, they reside in freed or leaked memory). Mutable references can be
6268
reachable but *not* live through the process of *reborrowing*.
6369

64-
A mutable reference can be reborrowed to either a shared or mutable reference.
65-
Further, the reborrow can produce exactly the same reference, or point to a
66-
path it is a prefix of. For instance, a mutable reference can be reborrowed
70+
A mutable reference can be reborrowed to either a shared or mutable reference to
71+
one of its descendants. A reborrowed reference will only be live again once all
72+
reborrows derived from it expire. For instance, a mutable reference can be reborrowed
6773
to point to a field of its referent:
6874

6975
```rust
@@ -79,7 +85,7 @@ let x = &mut (1, 2);
7985
```
8086

8187
It is also possible to reborrow into *multiple* mutable references, as long as
82-
they are *disjoint*: no reference is a prefix of another. Rust
88+
they are *disjoint*: no reference is an ancestor of another. Rust
8389
explicitly enables this to be done with disjoint struct fields, because
8490
disjointness can be statically proven:
8591

@@ -89,6 +95,7 @@ let x = &mut (1, 2);
8995
// reborrow x to two disjoint subfields
9096
let y = &mut x.0;
9197
let z = &mut x.1;
98+
9299
// y and z are now live, but x isn't
93100
*y = 3;
94101
*z = 4;
@@ -105,14 +112,14 @@ To simplify things, we can model variables as a fake type of reference: *owned*
105112
references. Owned references have much the same semantics as mutable references:
106113
they can be re-borrowed in a mutable or shared manner, which makes them no longer
107114
live. Live owned references have the unique property that they can be moved
108-
out of (though mutable references *can* be swapped out of). This is
115+
out of (though mutable references *can* be swapped out of). This power is
109116
only given to *live* owned references because moving its referent would of
110117
course invalidate all outstanding references prematurely.
111118

112119
As a local lint against inappropriate mutation, only variables that are marked
113120
as `mut` can be borrowed mutably.
114121

115-
It is also interesting to note that Box behaves exactly like an owned
122+
It is interesting to note that Box behaves exactly like an owned
116123
reference. It can be moved out of, and Rust understands it sufficiently to
117124
reason about its paths like a normal variable.
118125

@@ -123,8 +130,12 @@ reason about its paths like a normal variable.
123130

124131
With liveness and paths defined, we can now properly define *aliasing*:
125132

126-
**A mutable reference is aliased if there exists another live reference to it or
127-
one of its prefixes.**
133+
**A mutable reference is aliased if there exists another live reference to one of
134+
its ancestors or descendants.**
135+
136+
(If you prefer, you may also say the two live references alias *each other*.
137+
This has no semantic consequences, but is probably a more useful notion when
138+
verifying the soundness of a construct.)
128139

129140
That's it. Super simple right? Except for the fact that it took us two pages
130141
to define all of the terms in that defintion. You know: Super. Simple.

0 commit comments

Comments
 (0)