1
1
use rustc:: hir;
2
2
use 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 ;
4
5
use rustc:: ty:: { self , TyCtxt } ;
5
6
use borrow_check:: borrow_set:: LocalsStateAtExit ;
6
7
@@ -16,10 +17,6 @@ crate trait PlaceExt<'tcx> {
16
17
mir : & Mir < ' tcx > ,
17
18
locals_state_at_exit : & LocalsStateAtExit ,
18
19
) -> 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 > ;
23
20
}
24
21
25
22
impl < ' tcx > PlaceExt < ' tcx > for Place < ' tcx > {
@@ -29,9 +26,8 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
29
26
mir : & Mir < ' tcx > ,
30
27
locals_state_at_exit : & LocalsStateAtExit ,
31
28
) -> 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 {
35
31
// If a local variable is immutable, then we only need to track borrows to guard
36
32
// against two kinds of errors:
37
33
// * The variable being dropped while still borrowed (e.g., because the fn returns
@@ -40,7 +36,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
40
36
//
41
37
// In particular, the variable cannot be mutated -- the "access checks" will fail --
42
38
// so we don't have to worry about mutation while borrowed.
43
- Place :: Local ( index) => {
39
+ PlaceBase :: Local ( index) => {
44
40
match locals_state_at_exit {
45
41
LocalsStateAtExit :: AllAreInvalidated => false ,
46
42
LocalsStateAtExit :: SomeAreInvalidated { has_storage_dead_or_moved } => {
@@ -50,48 +46,33 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
50
46
ignore
51
47
}
52
48
}
53
- }
54
- Place :: Static ( static_) => {
49
+ } ,
50
+ PlaceBase :: Promoted ( _) => false ,
51
+ PlaceBase :: Static ( static_) => {
55
52
tcx. is_static ( static_. def_id ) == Some ( hir:: Mutability :: MutMutable )
56
53
}
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
+ } ;
64
55
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 ;
81
71
}
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) ,
94
72
}
73
+ base_ty = PlaceTy :: from ( base_ty) . projection_ty ( tcx, elem) . to_ty ( tcx) ;
95
74
}
75
+
76
+ is_unsafe_place
96
77
}
97
78
}
0 commit comments