diff options
Diffstat (limited to 'compiler/rustc_borrowck/src/prefixes.rs')
| -rw-r--r-- | compiler/rustc_borrowck/src/prefixes.rs | 89 |
1 files changed, 21 insertions, 68 deletions
diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index 8bb3dc88b34..8a3a089d0ee 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -1,7 +1,4 @@ -//! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an -//! place are formed by stripping away fields and derefs, except that -//! we stop when we reach the deref of a shared reference. [...] " -//! +//! From the NLL RFC: //! "Shallow prefixes are found by stripping away fields, but stop at //! any dereference. So: writing a path like `a` is illegal if `a.b` //! is borrowed. But: writing `a` is legal if `*a` is borrowed, @@ -9,9 +6,7 @@ use super::MirBorrowckCtxt; -use rustc_hir as hir; -use rustc_middle::mir::{Body, PlaceRef, ProjectionElem}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::mir::{PlaceRef, ProjectionElem}; pub trait IsPrefixOf<'tcx> { fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool; @@ -25,9 +20,7 @@ impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx> { } } -pub(super) struct Prefixes<'cx, 'tcx> { - body: &'cx Body<'tcx>, - tcx: TyCtxt<'tcx>, +pub(super) struct Prefixes<'tcx> { kind: PrefixSet, next: Option<PlaceRef<'tcx>>, } @@ -39,24 +32,18 @@ pub(super) enum PrefixSet { All, /// Stops at any dereference. Shallow, - /// Stops at the deref of a shared reference. - Supporting, } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Returns an iterator over the prefixes of `place` /// (inclusive) from longest to smallest, potentially /// terminating the iteration early based on `kind`. - pub(super) fn prefixes( - &self, - place_ref: PlaceRef<'tcx>, - kind: PrefixSet, - ) -> Prefixes<'cx, 'tcx> { - Prefixes { next: Some(place_ref), kind, body: self.body, tcx: self.infcx.tcx } + pub(super) fn prefixes(&self, place_ref: PlaceRef<'tcx>, kind: PrefixSet) -> Prefixes<'tcx> { + Prefixes { next: Some(place_ref), kind } } } -impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { +impl<'tcx> Iterator for Prefixes<'tcx> { type Item = PlaceRef<'tcx>; fn next(&mut self) -> Option<Self::Item> { let mut cursor = self.next?; @@ -91,57 +78,23 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { panic!("Subtype projection is not allowed before borrow check") } ProjectionElem::Deref => { - // (handled below) + match self.kind { + PrefixSet::Shallow => { + // Shallow prefixes are found by stripping away + // fields, but stop at *any* dereference. + // So we can just stop the traversal now. + self.next = None; + return Some(cursor); + } + PrefixSet::All => { + // All prefixes: just blindly enqueue the base + // of the projection. + self.next = Some(cursor_base); + return Some(cursor); + } + } } } - - assert_eq!(elem, ProjectionElem::Deref); - - match self.kind { - PrefixSet::Shallow => { - // Shallow prefixes are found by stripping away - // fields, but stop at *any* dereference. - // So we can just stop the traversal now. - self.next = None; - return Some(cursor); - } - PrefixSet::All => { - // All prefixes: just blindly enqueue the base - // of the projection. - self.next = Some(cursor_base); - return Some(cursor); - } - PrefixSet::Supporting => { - // Fall through! - } - } - - assert_eq!(self.kind, PrefixSet::Supporting); - // Supporting prefixes: strip away fields and - // derefs, except we stop at the deref of a shared - // reference. - - let ty = cursor_base.ty(self.body, self.tcx).ty; - match ty.kind() { - ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => { - // don't continue traversing over derefs of raw pointers or shared - // borrows. - self.next = None; - return Some(cursor); - } - - ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Mut) => { - self.next = Some(cursor_base); - return Some(cursor); - } - - ty::Adt(..) if ty.is_box() => { - self.next = Some(cursor_base); - return Some(cursor); - } - - _ => panic!("unknown type fed to Projection Deref."), - } } } } |
