You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: wip/tree-borrows.md
+12-6Lines changed: 12 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,7 @@ Changes since publication of the paper:
8
8
9
9
* Interior-Mutable shared references are no longer treated like raw pointers, instead they use the new `Cell` permission. This permission allows all foreign and local accesses.
10
10
* Mirroring Stacked Borrows, structs which contain an UnsafeCell now have that UnsafeCell's position tracked more finely-grained. It is no longer sufficient to just have an UnsafeCell somewhere in a struct to mark this as being interior-mutable everywhere.
11
+
* The state machine was refactored to eliminate the `accessed` bit. This mostly affects the protected state machine. This changed no behavior but makes it less obvious how the current MiniRust implementation relates to the paper. See [this PR](https://github.com/minirust/minirust/pull/276) and also [this rendering of the new state machine(s)](https://github.com/user-attachments/files/23404334/figures2.pdf).
11
12
12
13
## MiniRust
13
14
@@ -22,9 +23,9 @@ Tree Borrows maintains a tree for each allocation. Each pointer has a tag, that
22
23
Each node, for each offset/byte in the allocation, tracks a permission. The permission is per-byte, i.e. each byte has its own independent permission.
23
24
The permission evolves according to a state machine, which depends on the access (read/write), the relation between accessed and affected node (local/foreign), the current state, and whether the current node is protected by a protector.
24
25
25
-
There is also an "accessed" bit in each node for each byte, tracking whether this byte has already been accessed by a pointer tagged with this node.
26
-
This is relevant for protectors, because only "accessed" nodes are being protected.
27
-
These differences are not reflected in the state machines in the paper, we refer to the MiniRust implementation for the full details.
26
+
The state machine differs for protected and unprotected nodes.
27
+
For protected nodes, some states additionally track whether this byte was "accessed" which formally means that the state exists twice (e.g. `Frozen` and `FrozenL`).
28
+
The protected state machine of Figure 3 in the paper only shows those that are considered accessed; we refer to the MiniRust implementation for the full details.
28
29
29
30
30
31
### Differences between MiniRust and Miri
@@ -37,6 +38,10 @@ Besides this representation difference, Miri also includes a number of optimizat
37
38
* garbage collection of unused references, which allows shrinking trees
38
39
* skipping nodes based on the permissions found therein
39
40
41
+
Additionally, the above-mentioned "refactor to eliminate the `accessed` bit" has not yet happened in Miri.
42
+
43
+
Furthermore, Miri now has experimental support for `-Zmiri-permissive-provenance` with Tree Borrows.
44
+
40
45
## Concepts Inherited From Stacked Borrows
41
46
42
47
### Retags
@@ -49,7 +54,7 @@ Like Stacked Borrows, Tree Borrows has protectors. These serve to ensure that re
49
54
50
55
### Implicit Reads and Writes
51
56
52
-
Like Stacked Borrows, Tree Borrows performs implicit accesses as part of retags. Unlike Stacked Borrows, these are always reads, even for `&mut` references.
57
+
Like Stacked Borrows, Tree Borrows performs implicit accesses as part of retags. Unlike Stacked Borrows, these are always reads, even for `&mut` references. (But this might change, see below.)
53
58
54
59
A new concept in TB are implicit protector end accesses. These can be writes. See the section on "protector end semantics" in the paper for more info.
55
60
@@ -67,8 +72,9 @@ The following is a list of things that are _not_ UB in Tree Borrows. Some people
67
72
68
73
* Tree Borrows does _not_ have subobject provenance, meaning that retags do not shrink the set of offsets that a reference can be used to access.
69
74
* Tree Borrows does not initially consider `&mut` references writable, it only does so after the first write. In practice, this might mean that optimizations moving writes up above the first write are forbidden.
75
+
Note that there is work currently happening to make this a configurable option, and this option could become the default depending on the fallout of this change. See [#584](https://github.com/rust-lang/unsafe-code-guidelines/issues/584)
70
76
71
77
## Other problems
72
78
73
-
* The interaction of protector end writes with the data race model is not fully resolved.
74
-
*Finding a good model of exposed provenance in Tree Borrows (that does not use angelic nondeterminism) is an open research question. Until then, Tree Borrows does not support `-Zmiri-permissive-provenance`.
79
+
* The interaction of protector end writes with the data race model is not fully resolved. See [#585](https://github.com/rust-lang/unsafe-code-guidelines/issues/585).
80
+
*In Miri, there is experimental support for Tree Borros with `-Zmiri-permissive-provenance`, but the semantics are not yet fixed and likely to evolve in the future.
0 commit comments