@@ -14,14 +14,18 @@ use rustc_middle::ty::{
1414 self ,
1515 layout:: { HasParamEnv , LayoutOf } ,
1616} ;
17+ use rustc_span:: Span ;
1718use rustc_span:: DUMMY_SP ;
18- use rustc_span:: { Span , SpanData } ;
1919use rustc_target:: abi:: Size ;
2020use std:: collections:: HashSet ;
2121
22- use crate :: helpers:: HexRange ;
2322use crate :: * ;
2423
24+ pub mod diagnostics;
25+ use diagnostics:: { AllocHistory , GlobalStateExt , StackExt } ;
26+
27+ use diagnostics:: TagHistory ;
28+
2529pub type PtrId = NonZeroU64 ;
2630pub type CallId = NonZeroU64 ;
2731pub type AllocExtra = Stacks ;
@@ -120,47 +124,6 @@ pub struct GlobalStateInner {
120124 pub ( crate ) current_span : Span ,
121125}
122126
123- #[ derive( Debug , Default ) ]
124- struct AllocHistory {
125- // The time tags can be compressed down to one bit per event, by just storing a Vec<u8>
126- // where each bit is set to indicate if the event was a creation or a retag
127- current_time : usize ,
128- creations : smallvec:: SmallVec < [ Event ; 2 ] > ,
129- invalidations : smallvec:: SmallVec < [ Event ; 1 ] > ,
130- protectors : smallvec:: SmallVec < [ Protection ; 1 ] > ,
131- }
132-
133- #[ derive( Debug ) ]
134- struct Protection {
135- orig_tag : SbTag ,
136- tag : SbTag ,
137- span : Span ,
138- }
139-
140- #[ derive( Debug ) ]
141- struct Event {
142- time : usize ,
143- parent : Option < SbTag > ,
144- tag : SbTag ,
145- range : AllocRange ,
146- span : Span ,
147- }
148-
149- pub enum TagHistory {
150- Tagged {
151- tag : SbTag ,
152- created : ( AllocRange , SpanData ) ,
153- invalidated : Option < ( AllocRange , SpanData ) > ,
154- protected : Option < ( SbTag , SpanData , SpanData ) > ,
155- } ,
156- Untagged {
157- recently_created : Option < ( AllocRange , SpanData ) > ,
158- recently_invalidated : Option < ( AllocRange , SpanData ) > ,
159- matching_created : Option < ( AllocRange , SpanData ) > ,
160- protected : Option < ( SbTag , SpanData , SpanData ) > ,
161- } ,
162- }
163-
164127/// We need interior mutable access to the global state.
165128pub type GlobalState = RefCell < GlobalStateInner > ;
166129
@@ -269,144 +232,10 @@ impl GlobalStateInner {
269232 self . base_ptr_ids . try_insert ( id, tag) . unwrap ( ) ;
270233 tag
271234 }
272-
273- fn add_creation (
274- & mut self ,
275- parent : Option < SbTag > ,
276- tag : SbTag ,
277- alloc : AllocId ,
278- range : AllocRange ,
279- ) {
280- let extras = self . extras . entry ( alloc) . or_default ( ) ;
281- extras. creations . push ( Event {
282- parent,
283- tag,
284- range,
285- span : self . current_span ,
286- time : extras. current_time ,
287- } ) ;
288- extras. current_time += 1 ;
289- }
290-
291- fn add_invalidation ( & mut self , tag : SbTag , alloc : AllocId , range : AllocRange ) {
292- let extras = self . extras . entry ( alloc) . or_default ( ) ;
293- extras. invalidations . push ( Event {
294- parent : None ,
295- tag,
296- range,
297- span : self . current_span ,
298- time : extras. current_time ,
299- } ) ;
300- extras. current_time += 1 ;
301- }
302-
303- fn add_protector ( & mut self , orig_tag : SbTag , tag : SbTag , alloc : AllocId ) {
304- let extras = self . extras . entry ( alloc) . or_default ( ) ;
305- extras. protectors . push ( Protection { orig_tag, tag, span : self . current_span } ) ;
306- extras. current_time += 1 ;
307- }
308-
309- fn get_stack_history (
310- & self ,
311- tag : SbTag ,
312- alloc : AllocId ,
313- alloc_range : AllocRange ,
314- offset : Size ,
315- protector_tag : Option < SbTag > ,
316- ) -> Option < TagHistory > {
317- let extras = self . extras . get ( & alloc) ?;
318- let protected = protector_tag
319- . and_then ( |protector| {
320- extras. protectors . iter ( ) . find_map ( |protection| {
321- if protection. tag == protector {
322- Some ( ( protection. orig_tag , protection. span . data ( ) ) )
323- } else {
324- None
325- }
326- } )
327- } )
328- . and_then ( |( tag, call_span) | {
329- extras. creations . iter ( ) . rev ( ) . find_map ( |event| {
330- if event. tag == tag {
331- Some ( ( event. parent ?, event. span . data ( ) , call_span) )
332- } else {
333- None
334- }
335- } )
336- } ) ;
337- if let SbTag :: Tagged ( _) = tag {
338- let get_matching = |events : & [ Event ] | {
339- events. iter ( ) . rev ( ) . find_map ( |event| {
340- if event. tag == tag { Some ( ( event. range , event. span . data ( ) ) ) } else { None }
341- } )
342- } ;
343- Some ( TagHistory :: Tagged {
344- tag,
345- created : get_matching ( & extras. creations ) ?,
346- invalidated : get_matching ( & extras. invalidations ) ,
347- protected,
348- } )
349- } else {
350- let mut created_time = 0 ;
351- // Find the most recently created tag that satsfies this offset
352- let recently_created = extras. creations . iter ( ) . rev ( ) . find_map ( |event| {
353- if event. tag == tag && offset >= event. range . start && offset < event. range . end ( ) {
354- created_time = event. time ;
355- Some ( ( event. range , event. span . data ( ) ) )
356- } else {
357- None
358- }
359- } ) ;
360-
361- // Find a different recently created tag that satisfies this whole operation, predates
362- // the recently created tag, and has a different span.
363- // We're trying to make a guess at which span the user wanted to provide the tag that
364- // they're using.
365- let matching_created = if let Some ( ( _created_range, created_span) ) = recently_created {
366- extras. creations . iter ( ) . rev ( ) . find_map ( |event| {
367- if event. tag == tag
368- && alloc_range. start >= event. range . start
369- && alloc_range. end ( ) <= event. range . end ( )
370- && event. span . data ( ) != created_span
371- && event. time != created_time
372- {
373- Some ( ( event. range , event. span . data ( ) ) )
374- } else {
375- None
376- }
377- } )
378- } else {
379- None
380- } ;
381-
382- let recently_invalidated = if recently_created. is_some ( ) {
383- // Find the most recent invalidation of this tag which post-dates the creation
384- let mut found = None ;
385- for event in extras. invalidations . iter ( ) . rev ( ) {
386- if event. time < created_time {
387- break ;
388- }
389- if event. tag == tag && offset >= event. range . start && offset < event. range . end ( )
390- {
391- found = Some ( ( event. range , event. span . data ( ) ) )
392- }
393- }
394- found
395- } else {
396- None
397- } ;
398- Some ( TagHistory :: Untagged {
399- recently_created,
400- matching_created,
401- recently_invalidated,
402- protected,
403- } )
404- }
405- }
406235}
407236
408237/// Error reporting
409- fn err_sb_ub (
238+ pub fn err_sb_ub (
410239 msg : String ,
411240 help : Option < String > ,
412241 history : Option < TagHistory > ,
@@ -498,7 +327,7 @@ impl<'tcx> Stack {
498327 /// `None` during a deallocation.
499328 fn check_protector (
500329 item : & Item ,
501- provoking_access : Option < ( SbTag , AllocId , AllocRange , Size ) > , // just for debug printing amd error messages
330+ provoking_access : Option < ( SbTag , AllocId , AllocRange , Size ) > , // just for debug printing and error messages
502331 global : & GlobalStateInner ,
503332 ) -> InterpResult < ' tcx > {
504333 if let SbTag :: Tagged ( id) = item. tag {
@@ -600,7 +429,7 @@ impl<'tcx> Stack {
600429 fn dealloc (
601430 & mut self ,
602431 tag : SbTag ,
603- ( alloc_id, alloc_range, offset) : ( AllocId , AllocRange , Size ) , // just for debug printing amd error messages
432+ ( alloc_id, alloc_range, offset) : ( AllocId , AllocRange , Size ) , // just for debug printing and error messages
604433 global : & GlobalStateInner ,
605434 ) -> InterpResult < ' tcx > {
606435 // Step 1: Find granting item.
@@ -681,75 +510,6 @@ impl<'tcx> Stack {
681510
682511 Ok ( ( ) )
683512 }
684-
685- /// Report a descriptive error when `new` could not be granted from `derived_from`.
686- fn grant_error (
687- & self ,
688- derived_from : SbTag ,
689- new : Item ,
690- alloc_id : AllocId ,
691- alloc_range : AllocRange ,
692- error_offset : Size ,
693- global : & GlobalStateInner ,
694- ) -> InterpError < ' static > {
695- let action = format ! (
696- "trying to reborrow {:?} for {:?} permission at {}[{:#x}]" ,
697- derived_from,
698- new. perm,
699- alloc_id,
700- error_offset. bytes( ) ,
701- ) ;
702- err_sb_ub (
703- format ! ( "{}{}" , action, self . error_cause( derived_from) ) ,
704- Some ( Self :: operation_summary ( "a reborrow" , alloc_id, alloc_range) ) ,
705- global. get_stack_history ( derived_from, alloc_id, alloc_range, error_offset, None ) ,
706- )
707- }
708-
709- /// Report a descriptive error when `access` is not permitted based on `tag`.
710- fn access_error (
711- & self ,
712- access : AccessKind ,
713- tag : SbTag ,
714- alloc_id : AllocId ,
715- alloc_range : AllocRange ,
716- error_offset : Size ,
717- global : & GlobalStateInner ,
718- ) -> InterpError < ' static > {
719- let action = format ! (
720- "attempting a {} using {:?} at {}[{:#x}]" ,
721- access,
722- tag,
723- alloc_id,
724- error_offset. bytes( ) ,
725- ) ;
726- err_sb_ub (
727- format ! ( "{}{}" , action, self . error_cause( tag) ) ,
728- Some ( Self :: operation_summary ( "an access" , alloc_id, alloc_range) ) ,
729- global. get_stack_history ( tag, alloc_id, alloc_range, error_offset, None ) ,
730- )
731- }
732-
733- fn operation_summary (
734- operation : & ' static str ,
735- alloc_id : AllocId ,
736- alloc_range : AllocRange ,
737- ) -> String {
738- format ! (
739- "this error occurs as part of {} at {:?}{}" ,
740- operation,
741- alloc_id,
742- HexRange ( alloc_range)
743- )
744- }
745-
746- fn error_cause ( & self , tag : SbTag ) -> & ' static str {
747- if self . borrows . iter ( ) . any ( |item| item. tag == tag && item. perm != Permission :: Disabled ) {
748- ", but that tag only grants SharedReadOnly permission for this location"
749- } else {
750- ", but that tag does not exist in the borrow stack for this location"
751- }
752- }
753513}
754514// # Stacked Borrows Core End
755515
0 commit comments