Skip to content

Commit b3058a5

Browse files
committed
---
yaml --- r: 224491 b: refs/heads/beta c: 29e71b9 h: refs/heads/master i: 224489: 7cfeef0 224487: e2c8663 v: v3
1 parent cd2269c commit b3058a5

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: fcf4a7e5c87cf80ff8d7c142fbdfd8fd398ad3a7
26+
refs/heads/beta: 29e71b92bc5992dd2bf85dc4b27b60aaf0dcead8
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: 938f5d7af401e2d8238522fed4a612943b6e77fd
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/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

branches/beta/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)