11use rustc:: hir;
22use rustc:: mir:: ProjectionElem ;
3- use rustc:: mir:: { Local , Mir , Place , Mutability } ;
3+ use rustc:: mir:: { Mir , Place , PlaceBase , Mutability } ;
4+ use rustc:: mir:: tcx:: PlaceTy ;
45use rustc:: ty:: { self , TyCtxt } ;
56use borrow_check:: borrow_set:: LocalsStateAtExit ;
67
@@ -16,10 +17,6 @@ crate trait PlaceExt<'tcx> {
1617 mir : & Mir < ' tcx > ,
1718 locals_state_at_exit : & LocalsStateAtExit ,
1819 ) -> bool ;
19-
20- /// If this is a place like `x.f.g`, returns the local
21- /// `x`. Returns `None` if this is based in a static.
22- fn root_local ( & self ) -> Option < Local > ;
2320}
2421
2522impl < ' tcx > PlaceExt < ' tcx > for Place < ' tcx > {
@@ -29,9 +26,8 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
2926 mir : & Mir < ' tcx > ,
3027 locals_state_at_exit : & LocalsStateAtExit ,
3128 ) -> bool {
32- match self {
33- Place :: Promoted ( _) => false ,
34-
29+ let neo_place = tcx. as_new_place ( self ) ;
30+ let mut is_unsafe_place = match & neo_place. base {
3531 // If a local variable is immutable, then we only need to track borrows to guard
3632 // against two kinds of errors:
3733 // * The variable being dropped while still borrowed (e.g., because the fn returns
@@ -40,7 +36,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
4036 //
4137 // In particular, the variable cannot be mutated -- the "access checks" will fail --
4238 // so we don't have to worry about mutation while borrowed.
43- Place :: Local ( index) => {
39+ PlaceBase :: Local ( index) => {
4440 match locals_state_at_exit {
4541 LocalsStateAtExit :: AllAreInvalidated => false ,
4642 LocalsStateAtExit :: SomeAreInvalidated { has_storage_dead_or_moved } => {
@@ -50,48 +46,33 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
5046 ignore
5147 }
5248 }
53- }
54- Place :: Static ( static_) => {
49+ } ,
50+ PlaceBase :: Promoted ( _) => false ,
51+ PlaceBase :: Static ( static_) => {
5552 tcx. is_static ( static_. def_id ) == Some ( hir:: Mutability :: MutMutable )
5653 }
57- Place :: Projection ( proj) => match proj. elem {
58- ProjectionElem :: Field ( ..)
59- | ProjectionElem :: Downcast ( ..)
60- | ProjectionElem :: Subslice { .. }
61- | ProjectionElem :: ConstantIndex { .. }
62- | ProjectionElem :: Index ( _) => proj. base . ignore_borrow (
63- tcx, mir, locals_state_at_exit) ,
54+ } ;
6455
65- ProjectionElem :: Deref => {
66- let ty = proj. base . ty ( mir, tcx) . to_ty ( tcx) ;
67- match ty. sty {
68- // For both derefs of raw pointers and `&T`
69- // references, the original path is `Copy` and
70- // therefore not significant. In particular,
71- // there is nothing the user can do to the
72- // original path that would invalidate the
73- // newly created reference -- and if there
74- // were, then the user could have copied the
75- // original path into a new variable and
76- // borrowed *that* one, leaving the original
77- // path unborrowed.
78- ty:: RawPtr ( ..) | ty:: Ref ( _, _, hir:: MutImmutable ) => true ,
79- _ => proj. base . ignore_borrow ( tcx, mir, locals_state_at_exit) ,
80- }
56+ let mut base_ty = neo_place. base . ty ( mir) ;
57+ for elem in neo_place. elems . iter ( ) {
58+ if let ProjectionElem :: Deref = elem {
59+ if let ty:: RawPtr ( ..) | ty:: Ref ( _, _, hir:: MutImmutable ) = base_ty. sty {
60+ // For both derefs of raw pointers and `&T`
61+ // references, the original path is `Copy` and
62+ // therefore not significant. In particular,
63+ // there is nothing the user can do to the
64+ // original path that would invalidate the
65+ // newly created reference -- and if there
66+ // were, then the user could have copied the
67+ // original path into a new variable and
68+ // borrowed *that* one, leaving the original
69+ // path unborrowed.
70+ is_unsafe_place = true ;
8171 }
82- } ,
83- }
84- }
85-
86- fn root_local ( & self ) -> Option < Local > {
87- let mut p = self ;
88- loop {
89- match p {
90- Place :: Projection ( pi) => p = & pi. base ,
91- Place :: Promoted ( _) |
92- Place :: Static ( _) => return None ,
93- Place :: Local ( l) => return Some ( * l) ,
9472 }
73+ base_ty = PlaceTy :: from ( base_ty) . projection_ty ( tcx, elem) . to_ty ( tcx) ;
9574 }
75+
76+ is_unsafe_place
9677 }
9778}
0 commit comments