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
Auto merge of rust-lang#2828 - Vanille-N:tb-diags, r=RalfJung
Tree Borrows: improved diagnostics
Better diagnostics for Tree Borrows violations.
- Shows where the conflicting tags (the one that was accessed and the one that had a permission or protector that caused UB) were reborrowed, which is more readable than only `<TAG>`
- Shows a small history of what happened for the faulty tag to get there (which lines caused it to lose read/write permissions)
- Explains permissions and transitions in natural language (e.g. "does not have read permissions" instead of "is Disabled")
Not perfect, but at least testing TB will be less confusing.
Lack of range information from `RangeMap` makes selection of relevant events nontrivial: we reconstruct history from knowledge of `(initial, final)` and `(offset, pi, p'i)` so that `initial -> final = p1 -> p1' = p2 -> p2' = p3 -> ... = final `
// NOTE: `offset` is explicitly absent from the error message, it has no significance
81
+
// to the user. The meaningful one is `access_range`.
82
+
self.events.push((Some(span.data()),format!("{this} then transitioned {transition} due to a {rel} {access_kind} at offsets {access_range:?}", rel = if is_foreign {"foreign"} else {"child"})));
83
+
self.events.push((None,format!("this corresponds to {}", transition.summary())));
84
+
}
85
+
}
86
+
}
87
+
12
88
/// Some information that is irrelevant for the algorithm but very
13
89
/// convenient to know about a tag for debugging and testing.
14
90
#[derive(Clone,Debug)]
@@ -20,18 +96,29 @@ pub struct NodeDebugInfo {
20
96
/// pointer in the source code.
21
97
/// Helps match tag numbers to human-readable names.
22
98
pubname:Option<String>,
99
+
/// Notable events in the history of this tag, used for
100
+
/// diagnostics.
101
+
///
102
+
/// NOTE: by virtue of being part of `NodeDebugInfo`,
103
+
/// the history is automatically cleaned up by the GC.
104
+
/// NOTE: this is `!Send`, it needs to be converted before displaying
105
+
/// the actual diagnostics because `src/diagnostics.rs` requires `Send`.
106
+
pubhistory:History,
23
107
}
108
+
24
109
implNodeDebugInfo{
25
-
/// New node info with a name.
26
-
pubfnnew(tag:BorTag) -> Self{
27
-
Self{ tag,name:None}
110
+
/// Information for a new node. By default it has no
"{kind} through {initial} is forbidden because it is a child of {current} which is {perm}.",
132
-
kind=self.access_kind,
133
-
initial=self.tag_of_access,
134
-
current=self.faulty_tag,
135
-
perm=perm,
136
-
)
271
+
let conflicting_tag_name =
272
+
if accessed_is_conflicting {"accessed"}else{"conflicting"};
273
+
let title = format!("{kind} through {accessed} is forbidden");
274
+
letmut details = Vec::new();
275
+
if !accessed_is_conflicting {
276
+
details.push(format!(
277
+
"the accessed tag {accessed} is a child of the conflicting tag {conflicting}"
278
+
));
279
+
}
280
+
details.push(format!(
281
+
"the {conflicting_tag_name} tag {conflicting} has state {perm} which forbids child {kind}es"
282
+
));
283
+
(perm, title, details, conflicting_tag_name)
137
284
}
138
-
ProtectedTransition(start, end) => {
139
-
format!(
140
-
"{kind} through {initial} is forbidden because it is a foreign tag for {current}, which would hence change from {start} to {end}, but {current} is protected",
141
-
current=self.faulty_tag,
142
-
start=start,
143
-
end=end,
144
-
kind=self.access_kind,
145
-
initial=self.tag_of_access,
146
-
)
285
+
ProtectedTransition(transition) => {
286
+
let conflicting_tag_name = "protected";
287
+
let title = format!("{kind} through {accessed} is forbidden");
288
+
let details = vec![
289
+
format!(
290
+
"the accessed tag {accessed} is foreign to the {conflicting_tag_name} tag {conflicting} (i.e., it is not a child)"
291
+
),
292
+
format!(
293
+
"the access would cause the {conflicting_tag_name} tag {conflicting} to transition {transition}"
294
+
),
295
+
format!(
296
+
"this is {loss}, which is not allowed for protected tags",
0 commit comments