@@ -14,14 +14,18 @@ use rustc_middle::ty::{
14
14
self ,
15
15
layout:: { HasParamEnv , LayoutOf } ,
16
16
} ;
17
+ use rustc_span:: Span ;
17
18
use rustc_span:: DUMMY_SP ;
18
- use rustc_span:: { Span , SpanData } ;
19
19
use rustc_target:: abi:: Size ;
20
20
use std:: collections:: HashSet ;
21
21
22
- use crate :: helpers:: HexRange ;
23
22
use crate :: * ;
24
23
24
+ pub mod diagnostics;
25
+ use diagnostics:: { AllocHistory , GlobalStateExt , StackExt } ;
26
+
27
+ use diagnostics:: TagHistory ;
28
+
25
29
pub type PtrId = NonZeroU64 ;
26
30
pub type CallId = NonZeroU64 ;
27
31
pub type AllocExtra = Stacks ;
@@ -120,47 +124,6 @@ pub struct GlobalStateInner {
120
124
pub ( crate ) current_span : Span ,
121
125
}
122
126
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
-
164
127
/// We need interior mutable access to the global state.
165
128
pub type GlobalState = RefCell < GlobalStateInner > ;
166
129
@@ -269,144 +232,10 @@ impl GlobalStateInner {
269
232
self . base_ptr_ids . try_insert ( id, tag) . unwrap ( ) ;
270
233
tag
271
234
}
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
- }
406
235
}
407
236
408
237
/// Error reporting
409
- fn err_sb_ub (
238
+ pub fn err_sb_ub (
410
239
msg : String ,
411
240
help : Option < String > ,
412
241
history : Option < TagHistory > ,
@@ -498,7 +327,7 @@ impl<'tcx> Stack {
498
327
/// `None` during a deallocation.
499
328
fn check_protector (
500
329
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
502
331
global : & GlobalStateInner ,
503
332
) -> InterpResult < ' tcx > {
504
333
if let SbTag :: Tagged ( id) = item. tag {
@@ -600,7 +429,7 @@ impl<'tcx> Stack {
600
429
fn dealloc (
601
430
& mut self ,
602
431
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
604
433
global : & GlobalStateInner ,
605
434
) -> InterpResult < ' tcx > {
606
435
// Step 1: Find granting item.
@@ -681,75 +510,6 @@ impl<'tcx> Stack {
681
510
682
511
Ok ( ( ) )
683
512
}
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
- }
753
513
}
754
514
// # Stacked Borrows Core End
755
515
0 commit comments