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:
52//! "Shallow prefixes are found by stripping away fields, but stop at
63//! any dereference. So: writing a path like `a` is illegal if `a.b`
74//! is borrowed. But: writing `a` is legal if `*a` is borrowed,
85//! whether or not `a` is a shared or mutable reference. [...] "
96
107use super :: MirBorrowckCtxt ;
118
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 } ;
1510
1611pub trait IsPrefixOf < ' tcx > {
1712 fn is_prefix_of ( & self , other : PlaceRef < ' tcx > ) -> bool ;
@@ -25,9 +20,7 @@ impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx> {
2520 }
2621}
2722
28- pub ( super ) struct Prefixes < ' cx , ' tcx > {
29- body : & ' cx Body < ' tcx > ,
30- tcx : TyCtxt < ' tcx > ,
23+ pub ( super ) struct Prefixes < ' tcx > {
3124 kind : PrefixSet ,
3225 next : Option < PlaceRef < ' tcx > > ,
3326}
@@ -39,24 +32,18 @@ pub(super) enum PrefixSet {
3932 All ,
4033 /// Stops at any dereference.
4134 Shallow ,
42- /// Stops at the deref of a shared reference.
43- Supporting ,
4435}
4536
4637impl < ' cx , ' tcx > MirBorrowckCtxt < ' cx , ' tcx > {
4738 /// Returns an iterator over the prefixes of `place`
4839 /// (inclusive) from longest to smallest, potentially
4940 /// 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 }
5643 }
5744}
5845
59- impl < ' cx , ' tcx > Iterator for Prefixes < ' cx , ' tcx > {
46+ impl < ' tcx > Iterator for Prefixes < ' tcx > {
6047 type Item = PlaceRef < ' tcx > ;
6148 fn next ( & mut self ) -> Option < Self :: Item > {
6249 let mut cursor = self . next ?;
@@ -91,57 +78,23 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
9178 panic ! ( "Subtype projection is not allowed before borrow check" )
9279 }
9380 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+ }
9596 }
9697 }
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- }
14598 }
14699 }
147100 }
0 commit comments