@@ -5,9 +5,11 @@ pub mod diagnostics;
5
5
mod item;
6
6
mod stack;
7
7
8
- use log:: trace;
9
8
use std:: cmp;
10
9
use std:: fmt:: Write ;
10
+ use std:: mem;
11
+
12
+ use log:: trace;
11
13
12
14
use rustc_data_structures:: fx:: FxHashSet ;
13
15
use rustc_middle:: mir:: { Mutability , RetagKind } ;
@@ -19,12 +21,12 @@ use rustc_middle::ty::{
19
21
use rustc_target:: abi:: { Abi , Size } ;
20
22
21
23
use crate :: borrow_tracker:: {
22
- stacked_borrows:: diagnostics:: { AllocHistory , DiagnosticCx , DiagnosticCxBuilder , TagHistory } ,
24
+ stacked_borrows:: diagnostics:: { AllocHistory , DiagnosticCx , DiagnosticCxBuilder } ,
23
25
AccessKind , GlobalStateInner , ProtectorKind , RetagFields ,
24
26
} ;
25
27
use crate :: * ;
26
28
27
- use diagnostics:: RetagCause ;
29
+ use diagnostics:: { RetagCause , RetagInfo } ;
28
30
pub use item:: { Item , Permission } ;
29
31
pub use stack:: Stack ;
30
32
@@ -168,15 +170,6 @@ impl NewPermission {
168
170
}
169
171
}
170
172
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
-
180
173
// # Stacked Borrows Core Begin
181
174
182
175
/// We need to make at least the following things true:
@@ -623,7 +616,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
623
616
size : Size ,
624
617
new_perm : NewPermission ,
625
618
new_tag : BorTag ,
626
- retag_cause : RetagCause , // What caused this retag, for diagnostics only
619
+ retag_info : RetagInfo , // diagnostics info about this retag
627
620
) -> InterpResult < ' tcx , Option < AllocId > > {
628
621
let this = self . eval_context_mut ( ) ;
629
622
@@ -670,7 +663,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
670
663
// FIXME: can this be done cleaner?
671
664
let dcx = DiagnosticCxBuilder :: retag (
672
665
& this. machine ,
673
- retag_cause ,
666
+ retag_info ,
674
667
new_tag,
675
668
orig_tag,
676
669
alloc_range ( base_offset, size) ,
@@ -761,7 +754,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
761
754
let global = machine. borrow_tracker . as_ref ( ) . unwrap ( ) . borrow ( ) ;
762
755
let dcx = DiagnosticCxBuilder :: retag (
763
756
machine,
764
- retag_cause ,
757
+ retag_info ,
765
758
new_tag,
766
759
orig_tag,
767
760
alloc_range ( base_offset, size) ,
@@ -804,7 +797,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
804
797
let global = this. machine . borrow_tracker . as_ref ( ) . unwrap ( ) . borrow ( ) ;
805
798
let dcx = DiagnosticCxBuilder :: retag (
806
799
& this. machine ,
807
- retag_cause ,
800
+ retag_info ,
808
801
new_tag,
809
802
orig_tag,
810
803
alloc_range ( base_offset, size) ,
@@ -834,7 +827,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
834
827
& mut self ,
835
828
val : & ImmTy < ' tcx , Provenance > ,
836
829
new_perm : NewPermission ,
837
- cause : RetagCause , // What caused this retag, for diagnostics only
830
+ info : RetagInfo , // diagnostics info about this retag
838
831
) -> InterpResult < ' tcx , ImmTy < ' tcx , Provenance > > {
839
832
let this = self . eval_context_mut ( ) ;
840
833
// 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<'
852
845
let new_tag = this. machine . borrow_tracker . as_mut ( ) . unwrap ( ) . get_mut ( ) . new_ptr ( ) ;
853
846
854
847
// 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 ) ?;
856
849
857
850
// Adjust pointer.
858
851
let new_place = place. map_provenance ( |p| {
@@ -886,12 +879,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
886
879
) -> InterpResult < ' tcx , ImmTy < ' tcx , Provenance > > {
887
880
let this = self . eval_context_mut ( ) ;
888
881
let new_perm = NewPermission :: from_ref_ty ( val. layout . ty , kind, this) ;
889
- let retag_cause = match kind {
882
+ let cause = match kind {
890
883
RetagKind :: TwoPhase { .. } => RetagCause :: TwoPhase ,
891
884
RetagKind :: FnEntry => unreachable ! ( ) ,
892
885
RetagKind :: Raw | RetagKind :: Default => RetagCause :: Normal ,
893
886
} ;
894
- this. sb_retag_reference ( val, new_perm, retag_cause )
887
+ this. sb_retag_reference ( val, new_perm, RetagInfo { cause , in_field : false } )
895
888
}
896
889
897
890
fn sb_retag_place_contents (
@@ -906,7 +899,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
906
899
RetagKind :: FnEntry => RetagCause :: FnEntry ,
907
900
RetagKind :: Default => RetagCause :: Normal ,
908
901
} ;
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 } ;
910
904
return visitor. visit_value ( place) ;
911
905
912
906
// The actual visitor.
@@ -915,17 +909,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
915
909
kind : RetagKind ,
916
910
retag_cause : RetagCause ,
917
911
retag_fields : RetagFields ,
912
+ in_field : bool ,
918
913
}
919
914
impl < ' ecx , ' mir , ' tcx > RetagVisitor < ' ecx , ' mir , ' tcx > {
920
915
#[ inline( always) ] // yes this helps in our benchmarks
921
916
fn retag_ptr_inplace (
922
917
& mut self ,
923
918
place : & PlaceTy < ' tcx , Provenance > ,
924
919
new_perm : NewPermission ,
925
- retag_cause : RetagCause ,
926
920
) -> InterpResult < ' tcx > {
927
921
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
+ ) ?;
929
927
self . ecx . write_immediate ( * val, place) ?;
930
928
Ok ( ( ) )
931
929
}
@@ -943,7 +941,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
943
941
fn visit_box ( & mut self , place : & PlaceTy < ' tcx , Provenance > ) -> InterpResult < ' tcx > {
944
942
// Boxes get a weak protectors, since they may be deallocated.
945
943
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)
947
945
}
948
946
949
947
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> {
960
958
ty:: Ref ( ..) => {
961
959
let new_perm =
962
960
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) ?;
964
962
}
965
963
ty:: RawPtr ( ..) => {
966
964
// 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> {
984
982
}
985
983
} ;
986
984
if recurse {
985
+ let in_field = mem:: replace ( & mut self . in_field , true ) ; // remember and restore old value
987
986
self . walk_value ( place) ?;
987
+ self . in_field = in_field;
988
988
}
989
989
}
990
990
}
@@ -1011,7 +1011,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1011
1011
access : Some ( AccessKind :: Write ) ,
1012
1012
protector : Some ( ProtectorKind :: StrongProtector ) ,
1013
1013
} ;
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
+ ) ?;
1015
1019
// We just throw away `new_ptr`, so nobody can access this memory while it is protected.
1016
1020
1017
1021
Ok ( ( ) )
0 commit comments