@@ -25,7 +25,7 @@ use rustc_middle::{
2525 } ,
2626} ;
2727use rustc_span:: def_id:: { CrateNum , DefId } ;
28- use rustc_span:: Symbol ;
28+ use rustc_span:: { Span , SpanData , Symbol } ;
2929use rustc_target:: abi:: { Align , Size } ;
3030use rustc_target:: spec:: abi:: Abi ;
3131
@@ -135,6 +135,19 @@ impl MayLeak for MiriMemoryKind {
135135 }
136136}
137137
138+ impl MiriMemoryKind {
139+ /// Whether we have a useful allocation span for an allocation of this kind.
140+ fn should_save_allocation_span ( self ) -> bool {
141+ use self :: MiriMemoryKind :: * ;
142+ match self {
143+ // Heap allocations are fine since the `Allocation` is created immediately.
144+ Rust | Miri | C | WinHeap | Mmap => true ,
145+ // Everything else is unclear, let's not show potentially confusing spans.
146+ Machine | Global | ExternStatic | Tls | Runtime => false ,
147+ }
148+ }
149+ }
150+
138151impl fmt:: Display for MiriMemoryKind {
139152 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
140153 use self :: MiriMemoryKind :: * ;
@@ -497,6 +510,10 @@ pub struct MiriMachine<'mir, 'tcx> {
497510
498511 /// Whether to collect a backtrace when each allocation is created, just in case it leaks.
499512 pub ( crate ) collect_leak_backtraces : bool ,
513+
514+ /// The spans we will use to report where an allocation was created and deallocated in
515+ /// diagnostics.
516+ pub ( crate ) allocation_spans : RefCell < FxHashMap < AllocId , ( Span , Option < Span > ) > > ,
500517}
501518
502519impl < ' mir , ' tcx > MiriMachine < ' mir , ' tcx > {
@@ -621,6 +638,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
621638 stack_addr,
622639 stack_size,
623640 collect_leak_backtraces : config. collect_leak_backtraces ,
641+ allocation_spans : RefCell :: new ( FxHashMap :: default ( ) ) ,
624642 }
625643 }
626644
@@ -742,6 +760,21 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
742760 pub ( crate ) fn page_align ( & self ) -> Align {
743761 Align :: from_bytes ( self . page_size ) . unwrap ( )
744762 }
763+
764+ pub ( crate ) fn allocated_span ( & self , alloc_id : AllocId ) -> Option < SpanData > {
765+ self . allocation_spans
766+ . borrow ( )
767+ . get ( & alloc_id)
768+ . map ( |( allocated, _deallocated) | allocated. data ( ) )
769+ }
770+
771+ pub ( crate ) fn deallocated_span ( & self , alloc_id : AllocId ) -> Option < SpanData > {
772+ self . allocation_spans
773+ . borrow ( )
774+ . get ( & alloc_id)
775+ . and_then ( |( _allocated, deallocated) | * deallocated)
776+ . map ( Span :: data)
777+ }
745778}
746779
747780impl VisitTags for MiriMachine < ' _ , ' _ > {
@@ -791,6 +824,7 @@ impl VisitTags for MiriMachine<'_, '_> {
791824 stack_addr : _,
792825 stack_size : _,
793826 collect_leak_backtraces : _,
827+ allocation_spans : _,
794828 } = self ;
795829
796830 threads. visit_tags ( visit) ;
@@ -1051,6 +1085,14 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10511085 } ,
10521086 |ptr| ecx. global_base_pointer ( ptr) ,
10531087 ) ?;
1088+
1089+ if matches ! ( kind, MemoryKind :: Machine ( kind) if kind. should_save_allocation_span( ) ) {
1090+ ecx. machine
1091+ . allocation_spans
1092+ . borrow_mut ( )
1093+ . insert ( id, ( ecx. machine . current_span ( ) , None ) ) ;
1094+ }
1095+
10541096 Ok ( Cow :: Owned ( alloc) )
10551097 }
10561098
@@ -1181,6 +1223,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11811223 if let Some ( borrow_tracker) = & mut alloc_extra. borrow_tracker {
11821224 borrow_tracker. before_memory_deallocation ( alloc_id, prove_extra, range, machine) ?;
11831225 }
1226+ if let Some ( ( _, deallocated_at) ) = machine. allocation_spans . borrow_mut ( ) . get_mut ( & alloc_id)
1227+ {
1228+ * deallocated_at = Some ( machine. current_span ( ) ) ;
1229+ }
11841230 Ok ( ( ) )
11851231 }
11861232
0 commit comments