1
1
use std:: cell:: Cell ;
2
- use std:: fmt:: Write ;
3
2
use std:: mem;
4
3
5
4
use rustc_data_structures:: fx:: FxHashMap ;
@@ -728,7 +727,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
728
727
if let Some ( return_place) = frame. return_place {
729
728
let op = self . access_local ( & frame, mir:: RETURN_PLACE , None ) ?;
730
729
self . copy_op_transmute ( op, return_place) ?;
731
- self . dump_place ( * return_place) ;
730
+ trace ! ( "{:?}" , self . dump_place( * return_place) ) ;
732
731
} else {
733
732
throw_ub ! ( Unreachable ) ;
734
733
}
@@ -823,9 +822,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
823
822
// All locals have a backing allocation, even if the allocation is empty
824
823
// due to the local having ZST type.
825
824
let ptr = ptr. assert_ptr ( ) ;
826
- if log_enabled ! ( :: log:: Level :: Trace ) {
827
- self . memory . dump_alloc ( ptr. alloc_id ) ;
828
- }
825
+ trace ! ( "{:?}" , self . memory. dump_alloc( ptr. alloc_id) ) ;
829
826
self . memory . deallocate_local ( ptr) ?;
830
827
} ;
831
828
Ok ( ( ) )
@@ -881,47 +878,77 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
881
878
self . raw_const_to_mplace ( val)
882
879
}
883
880
884
- pub fn dump_place ( & self , place : Place < M :: PointerTag > ) {
885
- // Debug output
886
- if !log_enabled ! ( :: log:: Level :: Trace ) {
887
- return ;
881
+ #[ must_use]
882
+ pub fn dump_place ( & ' a self , place : Place < M :: PointerTag > ) -> PlacePrinter < ' a , ' mir , ' tcx , M > {
883
+ PlacePrinter { ecx : self , place }
884
+ }
885
+
886
+ #[ must_use]
887
+ pub fn generate_stacktrace ( & self ) -> Vec < FrameInfo < ' tcx > > {
888
+ let mut frames = Vec :: new ( ) ;
889
+ for frame in self . stack ( ) . iter ( ) . rev ( ) {
890
+ let source_info = frame. current_source_info ( ) ;
891
+ let lint_root = source_info. and_then ( |source_info| {
892
+ match & frame. body . source_scopes [ source_info. scope ] . local_data {
893
+ mir:: ClearCrossCrate :: Set ( data) => Some ( data. lint_root ) ,
894
+ mir:: ClearCrossCrate :: Clear => None ,
895
+ }
896
+ } ) ;
897
+ let span = source_info. map_or ( DUMMY_SP , |source_info| source_info. span ) ;
898
+
899
+ frames. push ( FrameInfo { span, instance : frame. instance , lint_root } ) ;
888
900
}
889
- match place {
901
+ trace ! ( "generate stacktrace: {:#?}" , frames) ;
902
+ frames
903
+ }
904
+ }
905
+
906
+ #[ doc( hidden) ]
907
+ /// Helper struct for the `dump_place` function.
908
+ pub struct PlacePrinter < ' a , ' mir , ' tcx , M : Machine < ' mir , ' tcx > > {
909
+ ecx : & ' a InterpCx < ' mir , ' tcx , M > ,
910
+ place : Place < M :: PointerTag > ,
911
+ }
912
+
913
+ impl < ' a , ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > std:: fmt:: Debug
914
+ for PlacePrinter < ' a , ' mir , ' tcx , M >
915
+ {
916
+ fn fmt ( & self , fmt : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
917
+ match self . place {
890
918
Place :: Local { frame, local } => {
891
919
let mut allocs = Vec :: new ( ) ;
892
- let mut msg = format ! ( "{:?}" , local) ;
893
- if frame != self . frame_idx ( ) {
894
- write ! ( msg , " ({} frames up)" , self . frame_idx( ) - frame) . unwrap ( ) ;
920
+ write ! ( fmt , "{:?}" , local) ? ;
921
+ if frame != self . ecx . frame_idx ( ) {
922
+ write ! ( fmt , " ({} frames up)" , self . ecx . frame_idx( ) - frame) ? ;
895
923
}
896
- write ! ( msg , ":" ) . unwrap ( ) ;
924
+ write ! ( fmt , ":" ) ? ;
897
925
898
- match self . stack ( ) [ frame] . locals [ local] . value {
899
- LocalValue :: Dead => write ! ( msg , " is dead" ) . unwrap ( ) ,
900
- LocalValue :: Uninitialized => write ! ( msg , " is uninitialized" ) . unwrap ( ) ,
926
+ match self . ecx . stack ( ) [ frame] . locals [ local] . value {
927
+ LocalValue :: Dead => write ! ( fmt , " is dead" ) ? ,
928
+ LocalValue :: Uninitialized => write ! ( fmt , " is uninitialized" ) ? ,
901
929
LocalValue :: Live ( Operand :: Indirect ( mplace) ) => match mplace. ptr {
902
930
Scalar :: Ptr ( ptr) => {
903
931
write ! (
904
- msg ,
932
+ fmt ,
905
933
" by align({}){} ref:" ,
906
934
mplace. align. bytes( ) ,
907
935
match mplace. meta {
908
936
MemPlaceMeta :: Meta ( meta) => format!( " meta({:?})" , meta) ,
909
937
MemPlaceMeta :: Poison | MemPlaceMeta :: None => String :: new( ) ,
910
938
}
911
- )
912
- . unwrap ( ) ;
939
+ ) ?;
913
940
allocs. push ( ptr. alloc_id ) ;
914
941
}
915
- ptr => write ! ( msg , " by integral ref: {:?}" , ptr) . unwrap ( ) ,
942
+ ptr => write ! ( fmt , " by integral ref: {:?}" , ptr) ? ,
916
943
} ,
917
944
LocalValue :: Live ( Operand :: Immediate ( Immediate :: Scalar ( val) ) ) => {
918
- write ! ( msg , " {:?}" , val) . unwrap ( ) ;
945
+ write ! ( fmt , " {:?}" , val) ? ;
919
946
if let ScalarMaybeUninit :: Scalar ( Scalar :: Ptr ( ptr) ) = val {
920
947
allocs. push ( ptr. alloc_id ) ;
921
948
}
922
949
}
923
950
LocalValue :: Live ( Operand :: Immediate ( Immediate :: ScalarPair ( val1, val2) ) ) => {
924
- write ! ( msg , " ({:?}, {:?})" , val1, val2) . unwrap ( ) ;
951
+ write ! ( fmt , " ({:?}, {:?})" , val1, val2) ? ;
925
952
if let ScalarMaybeUninit :: Scalar ( Scalar :: Ptr ( ptr) ) = val1 {
926
953
allocs. push ( ptr. alloc_id ) ;
927
954
}
@@ -931,36 +958,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
931
958
}
932
959
}
933
960
934
- trace ! ( "{}" , msg) ;
935
- self . memory . dump_allocs ( allocs) ;
961
+ write ! ( fmt, ": {:?}" , self . ecx. memory. dump_allocs( allocs) )
936
962
}
937
963
Place :: Ptr ( mplace) => match mplace. ptr {
938
- Scalar :: Ptr ( ptr) => {
939
- trace ! ( "by align({}) ref:" , mplace. align. bytes( ) ) ;
940
- self . memory . dump_alloc ( ptr. alloc_id ) ;
941
- }
942
- ptr => trace ! ( " integral by ref: {:?}" , ptr) ,
964
+ Scalar :: Ptr ( ptr) => write ! (
965
+ fmt,
966
+ "by align({}) ref: {:?}" ,
967
+ mplace. align. bytes( ) ,
968
+ self . ecx. memory. dump_alloc( ptr. alloc_id)
969
+ ) ,
970
+ ptr => write ! ( fmt, " integral by ref: {:?}" , ptr) ,
943
971
} ,
944
972
}
945
973
}
946
-
947
- pub fn generate_stacktrace ( & self ) -> Vec < FrameInfo < ' tcx > > {
948
- let mut frames = Vec :: new ( ) ;
949
- for frame in self . stack ( ) . iter ( ) . rev ( ) {
950
- let source_info = frame. current_source_info ( ) ;
951
- let lint_root = source_info. and_then ( |source_info| {
952
- match & frame. body . source_scopes [ source_info. scope ] . local_data {
953
- mir:: ClearCrossCrate :: Set ( data) => Some ( data. lint_root ) ,
954
- mir:: ClearCrossCrate :: Clear => None ,
955
- }
956
- } ) ;
957
- let span = source_info. map_or ( DUMMY_SP , |source_info| source_info. span ) ;
958
-
959
- frames. push ( FrameInfo { span, instance : frame. instance , lint_root } ) ;
960
- }
961
- trace ! ( "generate stacktrace: {:#?}" , frames) ;
962
- frames
963
- }
964
974
}
965
975
966
976
impl < ' ctx , ' mir , ' tcx , Tag , Extra > HashStable < StableHashingContext < ' ctx > >
0 commit comments