11//! Implements "Stacked Borrows". See <https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md>
22//! for further information.
33
4+ mod item;
5+ mod stack;
6+ pub mod diagnostics;
7+
48use log:: trace;
59use std:: cmp;
610use std:: fmt:: { self , Write } ;
@@ -15,15 +19,13 @@ use rustc_target::abi::{Abi, Size};
1519
1620use crate :: borrow_tracker:: {
1721 stacked_borrows:: diagnostics:: { AllocHistory , DiagnosticCx , DiagnosticCxBuilder , TagHistory } ,
18- AccessKind , GlobalStateInner , ProtectorKind , RetagCause , RetagFields ,
22+ AccessKind , GlobalStateInner , ProtectorKind , RetagFields ,
1923} ;
2024use crate :: * ;
2125
22- mod item;
2326pub use item:: { Item , Permission } ;
24- mod stack;
2527pub use stack:: Stack ;
26- pub mod diagnostics;
28+ use diagnostics:: RetagCause ;
2729
2830pub type AllocState = Stacks ;
2931
@@ -807,17 +809,44 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
807809
808810impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriInterpCx < ' mir , ' tcx > { }
809811pub 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 (
811840 & mut self ,
812841 kind : RetagKind ,
813842 place : & PlaceTy < ' tcx , Provenance > ,
814843 ) -> InterpResult < ' tcx > {
815844 let this = self . eval_context_mut ( ) ;
816845 let retag_fields = this. machine . borrow_tracker . as_mut ( ) . unwrap ( ) . get_mut ( ) . retag_fields ;
817846 let retag_cause = match kind {
818- RetagKind :: TwoPhase { .. } => RetagCause :: TwoPhase ,
847+ RetagKind :: Raw | RetagKind :: TwoPhase { .. } => unreachable ! ( ) ,
819848 RetagKind :: FnEntry => RetagCause :: FnEntry ,
820- RetagKind :: Raw | RetagKind :: Default => RetagCause :: Normal ,
849+ RetagKind :: Default => RetagCause :: Normal ,
821850 } ;
822851 let mut visitor = RetagVisitor { ecx : this, kind, retag_cause, retag_fields } ;
823852 return visitor. visit_value ( place) ;
@@ -831,7 +860,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
831860 }
832861 impl < ' ecx , ' mir , ' tcx > RetagVisitor < ' ecx , ' mir , ' tcx > {
833862 #[ inline( always) ] // yes this helps in our benchmarks
834- fn retag_place (
863+ fn retag_ptr_inplace (
835864 & mut self ,
836865 place : & PlaceTy < ' tcx , Provenance > ,
837866 ref_kind : RefKind ,
@@ -856,7 +885,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
856885
857886 fn visit_box ( & mut self , place : & PlaceTy < ' tcx , Provenance > ) -> InterpResult < ' tcx > {
858887 // Boxes get a weak protectors, since they may be deallocated.
859- self . retag_place (
888+ self . retag_ptr_inplace (
860889 place,
861890 RefKind :: Box ,
862891 self . retag_cause ,
@@ -879,10 +908,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
879908 ty:: Ref ( _, _, mutbl) => {
880909 let ref_kind = match mutbl {
881910 Mutability :: Mut =>
882- RefKind :: Unique { two_phase : self . kind == RetagKind :: TwoPhase } ,
911+ RefKind :: Unique { two_phase : false } ,
883912 Mutability :: Not => RefKind :: Shared ,
884913 } ;
885- self . retag_place (
914+ self . retag_ptr_inplace (
886915 place,
887916 ref_kind,
888917 self . retag_cause ,
@@ -891,21 +920,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
891920 . then_some ( ProtectorKind :: StrongProtector ) ,
892921 ) ?;
893922 }
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!
907926 }
908- _ if place . layout . ty . ty_adt_def ( ) . is_some_and ( | adt| adt . is_box ( ) ) => {
927+ ty :: Adt ( adt , _ ) if adt. is_box ( ) => {
909928 // Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
910929 // (Yes this means we technically also recursively retag the allocator itself
911930 // even if field retagging is not enabled. *shrug*)
0 commit comments