@@ -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,17 @@ 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+ Rust | Miri | C | Mmap => true ,
144+ Machine | Global | ExternStatic | Tls | WinHeap | Runtime => false ,
145+ }
146+ }
147+ }
148+
138149impl fmt:: Display for MiriMemoryKind {
139150 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
140151 use self :: MiriMemoryKind :: * ;
@@ -497,6 +508,10 @@ pub struct MiriMachine<'mir, 'tcx> {
497508
498509 /// Whether to collect a backtrace when each allocation is created, just in case it leaks.
499510 pub ( crate ) collect_leak_backtraces : bool ,
511+
512+ /// The spans we will use to report where an allocation was created and deallocated in
513+ /// diagnostics.
514+ pub ( crate ) allocation_spans : RefCell < FxHashMap < AllocId , ( Option < Span > , Option < Span > ) > > ,
500515}
501516
502517impl < ' mir , ' tcx > MiriMachine < ' mir , ' tcx > {
@@ -621,6 +636,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
621636 stack_addr,
622637 stack_size,
623638 collect_leak_backtraces : config. collect_leak_backtraces ,
639+ allocation_spans : RefCell :: new ( FxHashMap :: default ( ) ) ,
624640 }
625641 }
626642
@@ -742,6 +758,22 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
742758 pub ( crate ) fn page_align ( & self ) -> Align {
743759 Align :: from_bytes ( self . page_size ) . unwrap ( )
744760 }
761+
762+ pub ( crate ) fn allocated_span ( & self , alloc_id : AllocId ) -> Option < SpanData > {
763+ self . allocation_spans
764+ . borrow ( )
765+ . get ( & alloc_id)
766+ . and_then ( |( allocated, _deallocated) | * allocated)
767+ . map ( Span :: data)
768+ }
769+
770+ pub ( crate ) fn deallocated_span ( & self , alloc_id : AllocId ) -> Option < SpanData > {
771+ self . allocation_spans
772+ . borrow ( )
773+ . get ( & alloc_id)
774+ . and_then ( |( _allocated, deallocated) | * deallocated)
775+ . map ( Span :: data)
776+ }
745777}
746778
747779impl VisitTags for MiriMachine < ' _ , ' _ > {
@@ -791,6 +823,7 @@ impl VisitTags for MiriMachine<'_, '_> {
791823 stack_addr : _,
792824 stack_size : _,
793825 collect_leak_backtraces : _,
826+ allocation_spans : _,
794827 } = self ;
795828
796829 threads. visit_tags ( visit) ;
@@ -1051,6 +1084,16 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10511084 } ,
10521085 |ptr| ecx. global_base_pointer ( ptr) ,
10531086 ) ?;
1087+
1088+ if let MemoryKind :: Machine ( kind) = kind {
1089+ if kind. should_save_allocation_span ( ) {
1090+ ecx. machine
1091+ . allocation_spans
1092+ . borrow_mut ( )
1093+ . insert ( id, ( Some ( ecx. machine . current_span ( ) ) , None ) ) ;
1094+ }
1095+ }
1096+
10541097 Ok ( Cow :: Owned ( alloc) )
10551098 }
10561099
@@ -1181,6 +1224,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11811224 if let Some ( borrow_tracker) = & mut alloc_extra. borrow_tracker {
11821225 borrow_tracker. before_memory_deallocation ( alloc_id, prove_extra, range, machine) ?;
11831226 }
1227+ if let Some ( ( _, deallocated_at) ) = machine. allocation_spans . borrow_mut ( ) . get_mut ( & alloc_id)
1228+ {
1229+ * deallocated_at = Some ( machine. current_span ( ) ) ;
1230+ }
11841231 Ok ( ( ) )
11851232 }
11861233
0 commit comments