1
1
//! Implements "Stacked Borrows". See <https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md>
2
2
//! for further information.
3
3
4
+ mod item;
5
+ mod stack;
6
+ pub mod diagnostics;
7
+
4
8
use log:: trace;
5
9
use std:: cmp;
6
10
use std:: fmt:: { self , Write } ;
@@ -15,15 +19,13 @@ use rustc_target::abi::{Abi, Size};
15
19
16
20
use crate :: borrow_tracker:: {
17
21
stacked_borrows:: diagnostics:: { AllocHistory , DiagnosticCx , DiagnosticCxBuilder , TagHistory } ,
18
- AccessKind , GlobalStateInner , ProtectorKind , RetagCause , RetagFields ,
22
+ AccessKind , GlobalStateInner , ProtectorKind , RetagFields ,
19
23
} ;
20
24
use crate :: * ;
21
25
22
- mod item;
23
26
pub use item:: { Item , Permission } ;
24
- mod stack;
25
27
pub use stack:: Stack ;
26
- pub mod diagnostics;
28
+ use diagnostics:: RetagCause ;
27
29
28
30
pub type AllocState = Stacks ;
29
31
@@ -807,17 +809,44 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
807
809
808
810
impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriInterpCx < ' mir , ' tcx > { }
809
811
pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriInterpCxExt < ' mir , ' tcx > {
810
- fn sb_retag (
812
+ fn sb_retag_ptr_value (
813
+ & mut self ,
814
+ kind : RetagKind ,
815
+ val : & ImmTy < ' tcx , Provenance > ,
816
+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , Provenance > > {
817
+ let this = self . eval_context_mut ( ) ;
818
+ let ref_kind = match val. layout . ty . kind ( ) {
819
+ ty:: Ref ( _, _, mutbl) => {
820
+ match mutbl {
821
+ Mutability :: Mut =>
822
+ RefKind :: Unique { two_phase : kind == RetagKind :: TwoPhase } ,
823
+ Mutability :: Not => RefKind :: Shared ,
824
+ }
825
+ }
826
+ ty:: RawPtr ( tym) => {
827
+ RefKind :: Raw { mutable : tym. mutbl == Mutability :: Mut }
828
+ }
829
+ _ => unreachable ! ( ) ,
830
+ } ;
831
+ let retag_cause = match kind {
832
+ RetagKind :: TwoPhase { .. } => RetagCause :: TwoPhase ,
833
+ RetagKind :: FnEntry => unreachable ! ( ) ,
834
+ RetagKind :: Raw | RetagKind :: Default => RetagCause :: Normal ,
835
+ } ;
836
+ this. sb_retag_reference ( & val, ref_kind, retag_cause, None )
837
+ }
838
+
839
+ fn sb_retag_place_contents (
811
840
& mut self ,
812
841
kind : RetagKind ,
813
842
place : & PlaceTy < ' tcx , Provenance > ,
814
843
) -> InterpResult < ' tcx > {
815
844
let this = self . eval_context_mut ( ) ;
816
845
let retag_fields = this. machine . borrow_tracker . as_mut ( ) . unwrap ( ) . get_mut ( ) . retag_fields ;
817
846
let retag_cause = match kind {
818
- RetagKind :: TwoPhase { .. } => RetagCause :: TwoPhase ,
847
+ RetagKind :: Raw | RetagKind :: TwoPhase { .. } => unreachable ! ( ) ,
819
848
RetagKind :: FnEntry => RetagCause :: FnEntry ,
820
- RetagKind :: Raw | RetagKind :: Default => RetagCause :: Normal ,
849
+ RetagKind :: Default => RetagCause :: Normal ,
821
850
} ;
822
851
let mut visitor = RetagVisitor { ecx : this, kind, retag_cause, retag_fields } ;
823
852
return visitor. visit_value ( place) ;
@@ -831,7 +860,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
831
860
}
832
861
impl < ' ecx , ' mir , ' tcx > RetagVisitor < ' ecx , ' mir , ' tcx > {
833
862
#[ inline( always) ] // yes this helps in our benchmarks
834
- fn retag_place (
863
+ fn retag_ptr_inplace (
835
864
& mut self ,
836
865
place : & PlaceTy < ' tcx , Provenance > ,
837
866
ref_kind : RefKind ,
@@ -856,7 +885,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
856
885
857
886
fn visit_box ( & mut self , place : & PlaceTy < ' tcx , Provenance > ) -> InterpResult < ' tcx > {
858
887
// Boxes get a weak protectors, since they may be deallocated.
859
- self . retag_place (
888
+ self . retag_ptr_inplace (
860
889
place,
861
890
RefKind :: Box ,
862
891
self . retag_cause ,
@@ -879,10 +908,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
879
908
ty:: Ref ( _, _, mutbl) => {
880
909
let ref_kind = match mutbl {
881
910
Mutability :: Mut =>
882
- RefKind :: Unique { two_phase : self . kind == RetagKind :: TwoPhase } ,
911
+ RefKind :: Unique { two_phase : false } ,
883
912
Mutability :: Not => RefKind :: Shared ,
884
913
} ;
885
- self . retag_place (
914
+ self . retag_ptr_inplace (
886
915
place,
887
916
ref_kind,
888
917
self . retag_cause ,
@@ -891,21 +920,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
891
920
. then_some ( ProtectorKind :: StrongProtector ) ,
892
921
) ?;
893
922
}
894
- ty:: RawPtr ( tym) => {
895
- // We definitely do *not* want to recurse into raw pointers -- wide raw
896
- // pointers have fields, and for dyn Trait pointees those can have reference
897
- // type!
898
- if self . kind == RetagKind :: Raw {
899
- // Raw pointers need to be enabled.
900
- self . retag_place (
901
- place,
902
- RefKind :: Raw { mutable : tym. mutbl == Mutability :: Mut } ,
903
- self . retag_cause ,
904
- /*protector*/ None ,
905
- ) ?;
906
- }
923
+ ty:: RawPtr ( ..) => {
924
+ // We do *not* want to recurse into raw pointers -- wide raw pointers have
925
+ // fields, and for dyn Trait pointees those can have reference type!
907
926
}
908
- _ if place . layout . ty . ty_adt_def ( ) . is_some_and ( | adt| adt . is_box ( ) ) => {
927
+ ty :: Adt ( adt , _ ) if adt. is_box ( ) => {
909
928
// Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
910
929
// (Yes this means we technically also recursively retag the allocator itself
911
930
// even if field retagging is not enabled. *shrug*)
0 commit comments