1
- //! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
2
- //! place are formed by stripping away fields and derefs, except that
3
- //! we stop when we reach the deref of a shared reference. [...] "
4
- //!
1
+ //! From the NLL RFC:
5
2
//! "Shallow prefixes are found by stripping away fields, but stop at
6
3
//! any dereference. So: writing a path like `a` is illegal if `a.b`
7
4
//! is borrowed. But: writing `a` is legal if `*a` is borrowed,
8
5
//! whether or not `a` is a shared or mutable reference. [...] "
9
6
10
7
use super :: MirBorrowckCtxt ;
11
8
12
- use rustc_hir as hir;
13
- use rustc_middle:: mir:: { Body , PlaceRef , ProjectionElem } ;
14
- use rustc_middle:: ty:: { self , TyCtxt } ;
9
+ use rustc_middle:: mir:: { PlaceRef , ProjectionElem } ;
15
10
16
11
pub trait IsPrefixOf < ' tcx > {
17
12
fn is_prefix_of ( & self , other : PlaceRef < ' tcx > ) -> bool ;
@@ -25,9 +20,7 @@ impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx> {
25
20
}
26
21
}
27
22
28
- pub ( super ) struct Prefixes < ' cx , ' tcx > {
29
- body : & ' cx Body < ' tcx > ,
30
- tcx : TyCtxt < ' tcx > ,
23
+ pub ( super ) struct Prefixes < ' tcx > {
31
24
kind : PrefixSet ,
32
25
next : Option < PlaceRef < ' tcx > > ,
33
26
}
@@ -39,24 +32,18 @@ pub(super) enum PrefixSet {
39
32
All ,
40
33
/// Stops at any dereference.
41
34
Shallow ,
42
- /// Stops at the deref of a shared reference.
43
- Supporting ,
44
35
}
45
36
46
37
impl < ' cx , ' tcx > MirBorrowckCtxt < ' cx , ' tcx > {
47
38
/// Returns an iterator over the prefixes of `place`
48
39
/// (inclusive) from longest to smallest, potentially
49
40
/// terminating the iteration early based on `kind`.
50
- pub ( super ) fn prefixes (
51
- & self ,
52
- place_ref : PlaceRef < ' tcx > ,
53
- kind : PrefixSet ,
54
- ) -> Prefixes < ' cx , ' tcx > {
55
- Prefixes { next : Some ( place_ref) , kind, body : self . body , tcx : self . infcx . tcx }
41
+ pub ( super ) fn prefixes ( & self , place_ref : PlaceRef < ' tcx > , kind : PrefixSet ) -> Prefixes < ' tcx > {
42
+ Prefixes { next : Some ( place_ref) , kind }
56
43
}
57
44
}
58
45
59
- impl < ' cx , ' tcx > Iterator for Prefixes < ' cx , ' tcx > {
46
+ impl < ' tcx > Iterator for Prefixes < ' tcx > {
60
47
type Item = PlaceRef < ' tcx > ;
61
48
fn next ( & mut self ) -> Option < Self :: Item > {
62
49
let mut cursor = self . next ?;
@@ -91,57 +78,23 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
91
78
panic ! ( "Subtype projection is not allowed before borrow check" )
92
79
}
93
80
ProjectionElem :: Deref => {
94
- // (handled below)
81
+ match self . kind {
82
+ PrefixSet :: Shallow => {
83
+ // Shallow prefixes are found by stripping away
84
+ // fields, but stop at *any* dereference.
85
+ // So we can just stop the traversal now.
86
+ self . next = None ;
87
+ return Some ( cursor) ;
88
+ }
89
+ PrefixSet :: All => {
90
+ // All prefixes: just blindly enqueue the base
91
+ // of the projection.
92
+ self . next = Some ( cursor_base) ;
93
+ return Some ( cursor) ;
94
+ }
95
+ }
95
96
}
96
97
}
97
-
98
- assert_eq ! ( elem, ProjectionElem :: Deref ) ;
99
-
100
- match self . kind {
101
- PrefixSet :: Shallow => {
102
- // Shallow prefixes are found by stripping away
103
- // fields, but stop at *any* dereference.
104
- // So we can just stop the traversal now.
105
- self . next = None ;
106
- return Some ( cursor) ;
107
- }
108
- PrefixSet :: All => {
109
- // All prefixes: just blindly enqueue the base
110
- // of the projection.
111
- self . next = Some ( cursor_base) ;
112
- return Some ( cursor) ;
113
- }
114
- PrefixSet :: Supporting => {
115
- // Fall through!
116
- }
117
- }
118
-
119
- assert_eq ! ( self . kind, PrefixSet :: Supporting ) ;
120
- // Supporting prefixes: strip away fields and
121
- // derefs, except we stop at the deref of a shared
122
- // reference.
123
-
124
- let ty = cursor_base. ty ( self . body , self . tcx ) . ty ;
125
- match ty. kind ( ) {
126
- ty:: RawPtr ( _) | ty:: Ref ( _ /*rgn*/ , _ /*ty*/ , hir:: Mutability :: Not ) => {
127
- // don't continue traversing over derefs of raw pointers or shared
128
- // borrows.
129
- self . next = None ;
130
- return Some ( cursor) ;
131
- }
132
-
133
- ty:: Ref ( _ /*rgn*/ , _ /*ty*/ , hir:: Mutability :: Mut ) => {
134
- self . next = Some ( cursor_base) ;
135
- return Some ( cursor) ;
136
- }
137
-
138
- ty:: Adt ( ..) if ty. is_box ( ) => {
139
- self . next = Some ( cursor_base) ;
140
- return Some ( cursor) ;
141
- }
142
-
143
- _ => panic ! ( "unknown type fed to Projection Deref." ) ,
144
- }
145
98
}
146
99
}
147
100
}
0 commit comments