@@ -77,6 +77,32 @@ pub struct Event {
7777 pub span : Span ,
7878}
7979
80+ /// Diagnostics data about the current access and the location we are accessing.
81+ /// Used to create history events and errors.
82+ #[ derive( Clone , Debug ) ]
83+ pub struct DiagnosticInfo {
84+ pub alloc_id : AllocId ,
85+ pub span : Span ,
86+ /// The range the diagnostic actually applies to.
87+ /// This is always a subset of `access_range`.
88+ pub transition_range : Range < u64 > ,
89+ /// The range the access is happening to. Is `None` if this is the protector release access
90+ pub access_range : Option < AllocRange > ,
91+ pub access_cause : AccessCause ,
92+ }
93+ impl DiagnosticInfo {
94+ /// Creates a history event.
95+ pub fn create_event ( & self , transition : PermTransition , is_foreign : bool ) -> Event {
96+ Event {
97+ transition,
98+ is_foreign,
99+ access_cause : self . access_cause ,
100+ access_range : self . access_range ,
101+ transition_range : self . transition_range . clone ( ) ,
102+ span : self . span ,
103+ }
104+ }
105+ }
80106/// List of all events that affected a tag.
81107/// NOTE: not all of these events are relevant for a particular location,
82108/// the events should be filtered before the generation of diagnostics.
@@ -280,32 +306,29 @@ impl History {
280306pub ( super ) struct TbError < ' node > {
281307 /// What failure occurred.
282308 pub error_kind : TransitionError ,
283- /// The allocation in which the error is happening.
284- pub alloc_id : AllocId ,
285- /// The offset (into the allocation) at which the conflict occurred.
286- pub error_offset : u64 ,
309+ /// Diagnostic data about the access that caused the error.
310+ pub access_info : & ' node DiagnosticInfo ,
287311 /// The tag on which the error was triggered.
288312 /// On protector violations, this is the tag that was protected.
289313 /// On accesses rejected due to insufficient permissions, this is the
290314 /// tag that lacked those permissions.
291- pub conflicting_info : & ' node NodeDebugInfo ,
292- // What kind of access caused this error (read, write, reborrow, deallocation)
293- pub access_cause : AccessCause ,
315+ pub conflicting_node_info : & ' node NodeDebugInfo ,
294316 /// Which tag, if any, the access that caused this error was made through, i.e.
295317 /// which tag was used to read/write/deallocate.
296318 /// Not set on wildcard accesses.
297- pub accessed_info : Option < & ' node NodeDebugInfo > ,
319+ pub accessed_node_info : Option < & ' node NodeDebugInfo > ,
298320}
299321
300322impl TbError < ' _ > {
301323 /// Produce a UB error.
302324 pub fn build < ' tcx > ( self ) -> InterpErrorKind < ' tcx > {
303325 use TransitionError :: * ;
304- let cause = self . access_cause ;
305- let accessed = self . accessed_info ;
326+ let cause = self . access_info . access_cause ;
327+ let error_offset = self . access_info . transition_range . start ;
328+ let accessed = self . accessed_node_info ;
306329 let accessed_str =
307- self . accessed_info . map ( |v| format ! ( "{v}" ) ) . unwrap_or_else ( || "<wildcard>" . into ( ) ) ;
308- let conflicting = self . conflicting_info ;
330+ self . accessed_node_info . map ( |v| format ! ( "{v}" ) ) . unwrap_or_else ( || "<wildcard>" . into ( ) ) ;
331+ let conflicting = self . conflicting_node_info ;
309332 // An access is considered conflicting if it happened through a
310333 // different tag than the one who caused UB.
311334 // When doing a wildcard access (where `accessed` is `None`) we
@@ -316,9 +339,8 @@ impl TbError<'_> {
316339 // all tags through which an access would cause UB.
317340 let accessed_is_conflicting = accessed. map ( |a| a. tag ) == Some ( conflicting. tag ) ;
318341 let title = format ! (
319- "{cause} through {accessed_str} at {alloc_id:?}[{offset:#x}] is forbidden" ,
320- alloc_id = self . alloc_id,
321- offset = self . error_offset
342+ "{cause} through {accessed_str} at {alloc_id:?}[{error_offset:#x}] is forbidden" ,
343+ alloc_id = self . access_info. alloc_id
322344 ) ;
323345 let ( title, details, conflicting_tag_name) = match self . error_kind {
324346 ChildAccessForbidden ( perm) => {
@@ -362,13 +384,13 @@ impl TbError<'_> {
362384 }
363385 } ;
364386 let mut history = HistoryData :: default ( ) ;
365- if let Some ( accessed_info) = self . accessed_info
387+ if let Some ( accessed_info) = self . accessed_node_info
366388 && !accessed_is_conflicting
367389 {
368390 history. extend ( accessed_info. history . forget ( ) , "accessed" , false ) ;
369391 }
370392 history. extend (
371- self . conflicting_info . history . extract_relevant ( self . error_offset , self . error_kind ) ,
393+ self . conflicting_node_info . history . extract_relevant ( error_offset, self . error_kind ) ,
372394 conflicting_tag_name,
373395 true ,
374396 ) ;
@@ -379,12 +401,12 @@ impl TbError<'_> {
379401/// Cannot access this allocation with wildcard provenance, as there are no
380402/// valid exposed references for this access kind.
381403pub fn no_valid_exposed_references_error < ' tcx > (
382- alloc_id : AllocId ,
383- offset : u64 ,
384- access_cause : AccessCause ,
404+ DiagnosticInfo { alloc_id, transition_range, access_cause, .. } : & DiagnosticInfo ,
385405) -> InterpErrorKind < ' tcx > {
386- let title =
387- format ! ( "{access_cause} through <wildcard> at {alloc_id:?}[{offset:#x}] is forbidden" ) ;
406+ let title = format ! (
407+ "{access_cause} through <wildcard> at {alloc_id:?}[{offset:#x}] is forbidden" ,
408+ offset = transition_range. start
409+ ) ;
388410 let details = vec ! [ format!( "there are no exposed tags which may perform this access here" ) ] ;
389411 let history = HistoryData :: default ( ) ;
390412 err_machine_stop ! ( TerminationInfo :: TreeBorrowsUb { title, details, history } )
0 commit comments