@@ -5,9 +5,11 @@ pub mod diagnostics;
55mod item;
66mod stack;
77
8- use log:: trace;
98use std:: cmp;
109use std:: fmt:: Write ;
10+ use std:: mem;
11+
12+ use log:: trace;
1113
1214use rustc_data_structures:: fx:: FxHashSet ;
1315use rustc_middle:: mir:: { Mutability , RetagKind } ;
@@ -19,12 +21,12 @@ use rustc_middle::ty::{
1921use rustc_target:: abi:: { Abi , Size } ;
2022
2123use crate :: borrow_tracker:: {
22- stacked_borrows:: diagnostics:: { AllocHistory , DiagnosticCx , DiagnosticCxBuilder , TagHistory } ,
24+ stacked_borrows:: diagnostics:: { AllocHistory , DiagnosticCx , DiagnosticCxBuilder } ,
2325 AccessKind , GlobalStateInner , ProtectorKind , RetagFields ,
2426} ;
2527use crate :: * ;
2628
27- use diagnostics:: RetagCause ;
29+ use diagnostics:: { RetagCause , RetagInfo } ;
2830pub use item:: { Item , Permission } ;
2931pub use stack:: Stack ;
3032
@@ -168,15 +170,6 @@ impl NewPermission {
168170 }
169171}
170172
171- /// Error reporting
172- pub fn err_sb_ub < ' tcx > (
173- msg : String ,
174- help : Option < String > ,
175- history : Option < TagHistory > ,
176- ) -> InterpError < ' tcx > {
177- err_machine_stop ! ( TerminationInfo :: StackedBorrowsUb { msg, help, history } )
178- }
179-
180173// # Stacked Borrows Core Begin
181174
182175/// We need to make at least the following things true:
@@ -623,7 +616,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
623616 size : Size ,
624617 new_perm : NewPermission ,
625618 new_tag : BorTag ,
626- retag_cause : RetagCause , // What caused this retag, for diagnostics only
619+ retag_info : RetagInfo , // diagnostics info about this retag
627620 ) -> InterpResult < ' tcx , Option < AllocId > > {
628621 let this = self . eval_context_mut ( ) ;
629622
@@ -670,7 +663,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
670663 // FIXME: can this be done cleaner?
671664 let dcx = DiagnosticCxBuilder :: retag (
672665 & this. machine ,
673- retag_cause ,
666+ retag_info ,
674667 new_tag,
675668 orig_tag,
676669 alloc_range ( base_offset, size) ,
@@ -761,7 +754,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
761754 let global = machine. borrow_tracker . as_ref ( ) . unwrap ( ) . borrow ( ) ;
762755 let dcx = DiagnosticCxBuilder :: retag (
763756 machine,
764- retag_cause ,
757+ retag_info ,
765758 new_tag,
766759 orig_tag,
767760 alloc_range ( base_offset, size) ,
@@ -804,7 +797,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
804797 let global = this. machine . borrow_tracker . as_ref ( ) . unwrap ( ) . borrow ( ) ;
805798 let dcx = DiagnosticCxBuilder :: retag (
806799 & this. machine ,
807- retag_cause ,
800+ retag_info ,
808801 new_tag,
809802 orig_tag,
810803 alloc_range ( base_offset, size) ,
@@ -834,7 +827,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
834827 & mut self ,
835828 val : & ImmTy < ' tcx , Provenance > ,
836829 new_perm : NewPermission ,
837- cause : RetagCause , // What caused this retag, for diagnostics only
830+ info : RetagInfo , // diagnostics info about this retag
838831 ) -> InterpResult < ' tcx , ImmTy < ' tcx , Provenance > > {
839832 let this = self . eval_context_mut ( ) ;
840833 // We want a place for where the ptr *points to*, so we get one.
@@ -852,7 +845,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
852845 let new_tag = this. machine . borrow_tracker . as_mut ( ) . unwrap ( ) . get_mut ( ) . new_ptr ( ) ;
853846
854847 // Reborrow.
855- let alloc_id = this. sb_reborrow ( & place, size, new_perm, new_tag, cause ) ?;
848+ let alloc_id = this. sb_reborrow ( & place, size, new_perm, new_tag, info ) ?;
856849
857850 // Adjust pointer.
858851 let new_place = place. map_provenance ( |p| {
@@ -886,12 +879,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
886879 ) -> InterpResult < ' tcx , ImmTy < ' tcx , Provenance > > {
887880 let this = self . eval_context_mut ( ) ;
888881 let new_perm = NewPermission :: from_ref_ty ( val. layout . ty , kind, this) ;
889- let retag_cause = match kind {
882+ let cause = match kind {
890883 RetagKind :: TwoPhase { .. } => RetagCause :: TwoPhase ,
891884 RetagKind :: FnEntry => unreachable ! ( ) ,
892885 RetagKind :: Raw | RetagKind :: Default => RetagCause :: Normal ,
893886 } ;
894- this. sb_retag_reference ( val, new_perm, retag_cause )
887+ this. sb_retag_reference ( val, new_perm, RetagInfo { cause , in_field : false } )
895888 }
896889
897890 fn sb_retag_place_contents (
@@ -906,7 +899,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
906899 RetagKind :: FnEntry => RetagCause :: FnEntry ,
907900 RetagKind :: Default => RetagCause :: Normal ,
908901 } ;
909- let mut visitor = RetagVisitor { ecx : this, kind, retag_cause, retag_fields } ;
902+ let mut visitor =
903+ RetagVisitor { ecx : this, kind, retag_cause, retag_fields, in_field : false } ;
910904 return visitor. visit_value ( place) ;
911905
912906 // The actual visitor.
@@ -915,17 +909,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
915909 kind : RetagKind ,
916910 retag_cause : RetagCause ,
917911 retag_fields : RetagFields ,
912+ in_field : bool ,
918913 }
919914 impl < ' ecx , ' mir , ' tcx > RetagVisitor < ' ecx , ' mir , ' tcx > {
920915 #[ inline( always) ] // yes this helps in our benchmarks
921916 fn retag_ptr_inplace (
922917 & mut self ,
923918 place : & PlaceTy < ' tcx , Provenance > ,
924919 new_perm : NewPermission ,
925- retag_cause : RetagCause ,
926920 ) -> InterpResult < ' tcx > {
927921 let val = self . ecx . read_immediate ( & self . ecx . place_to_op ( place) ?) ?;
928- let val = self . ecx . sb_retag_reference ( & val, new_perm, retag_cause) ?;
922+ let val = self . ecx . sb_retag_reference (
923+ & val,
924+ new_perm,
925+ RetagInfo { cause : self . retag_cause , in_field : self . in_field } ,
926+ ) ?;
929927 self . ecx . write_immediate ( * val, place) ?;
930928 Ok ( ( ) )
931929 }
@@ -943,7 +941,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
943941 fn visit_box ( & mut self , place : & PlaceTy < ' tcx , Provenance > ) -> InterpResult < ' tcx > {
944942 // Boxes get a weak protectors, since they may be deallocated.
945943 let new_perm = NewPermission :: from_box_ty ( place. layout . ty , self . kind , self . ecx ) ;
946- self . retag_ptr_inplace ( place, new_perm, self . retag_cause )
944+ self . retag_ptr_inplace ( place, new_perm)
947945 }
948946
949947 fn visit_value ( & mut self , place : & PlaceTy < ' tcx , Provenance > ) -> InterpResult < ' tcx > {
@@ -960,7 +958,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
960958 ty:: Ref ( ..) => {
961959 let new_perm =
962960 NewPermission :: from_ref_ty ( place. layout . ty , self . kind , self . ecx ) ;
963- self . retag_ptr_inplace ( place, new_perm, self . retag_cause ) ?;
961+ self . retag_ptr_inplace ( place, new_perm) ?;
964962 }
965963 ty:: RawPtr ( ..) => {
966964 // We do *not* want to recurse into raw pointers -- wide raw pointers have
@@ -984,7 +982,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
984982 }
985983 } ;
986984 if recurse {
985+ let in_field = mem:: replace ( & mut self . in_field , true ) ; // remember and restore old value
987986 self . walk_value ( place) ?;
987+ self . in_field = in_field;
988988 }
989989 }
990990 }
@@ -1011,7 +1011,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10111011 access : Some ( AccessKind :: Write ) ,
10121012 protector : Some ( ProtectorKind :: StrongProtector ) ,
10131013 } ;
1014- let _new_ptr = this. sb_retag_reference ( & ptr, new_perm, RetagCause :: InPlaceFnPassing ) ?;
1014+ let _new_ptr = this. sb_retag_reference (
1015+ & ptr,
1016+ new_perm,
1017+ RetagInfo { cause : RetagCause :: InPlaceFnPassing , in_field : false } ,
1018+ ) ?;
10151019 // We just throw away `new_ptr`, so nobody can access this memory while it is protected.
10161020
10171021 Ok ( ( ) )
0 commit comments