@@ -2059,83 +2059,81 @@ impl<'tcx> Place<'tcx> {
20592059 }
20602060 }
20612061
2062- /// Recursively "iterates" over place components, generating a `PlaceComponents` list,
2063- /// invoking `op` with a `PlaceComponentsIter `.
2062+ /// Recursively "iterates" over place components, generating a `PlaceBase` and
2063+ /// `PlaceProjections` list and invoking `op` with a `PlaceProjectionsIter `.
20642064 pub fn iterate < R > (
20652065 & self ,
2066- op : impl FnOnce ( PlaceComponentsIter < ' _ , ' tcx > ) -> R ,
2066+ op : impl FnOnce ( & PlaceBase < ' tcx > , PlaceProjectionsIter < ' _ , ' tcx > ) -> R ,
20672067 ) -> R {
2068- self . iterate2 ( None , op)
2068+ self . iterate2 ( & PlaceProjections :: Empty , op)
20692069 }
20702070
20712071 fn iterate2 < R > (
20722072 & self ,
2073- next : Option < & PlaceComponents < ' _ , ' tcx > > ,
2074- op : impl FnOnce ( PlaceComponentsIter < ' _ , ' tcx > ) -> R ,
2073+ next : & PlaceProjections < ' _ , ' tcx > ,
2074+ op : impl FnOnce ( & PlaceBase < ' tcx > , PlaceProjectionsIter < ' _ , ' tcx > ) -> R ,
20752075 ) -> R {
20762076 match self {
20772077 Place :: Projection ( interior) => interior. base . iterate2 (
2078- Some ( & PlaceComponents {
2079- component : self ,
2078+ & PlaceProjections :: List {
2079+ projection : interior ,
20802080 next,
2081- } ) ,
2081+ } ,
20822082 op,
20832083 ) ,
20842084
2085- Place :: Base ( PlaceBase :: Local ( _) ) | Place :: Base ( PlaceBase :: Static ( _) ) => {
2086- let list = PlaceComponents {
2087- component : self ,
2088- next,
2089- } ;
2090- op ( list. iter ( ) )
2091- }
2085+ Place :: Base ( base) => op ( base, next. iter ( ) ) ,
20922086 }
20932087 }
20942088}
20952089
2096- /// A linked list of places running up the stack; begins with the
2097- /// innermost place and extends to projections (e.g., `a.b` would have
2098- /// the place `a ` with a "next" pointer to `a.b `). Created by
2099- /// `Place::iterate`.
2090+ /// A linked list of projections running up the stack; begins with the
2091+ /// innermost projection and extends to the outermost (e.g., `a.b.c`
2092+ /// would have the place `b ` with a "next" pointer to `b.c `).
2093+ /// Created by `Place::iterate`.
21002094///
21012095/// N.B., this particular impl strategy is not the most obvious. It was
21022096/// chosen because it makes a measurable difference to NLL
21032097/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
2104- pub struct PlaceComponents < ' p , ' tcx : ' p > {
2105- pub component : & ' p Place < ' tcx > ,
2106- pub next : Option < & ' p PlaceComponents < ' p , ' tcx > > ,
2098+ pub enum PlaceProjections < ' p , ' tcx : ' p > {
2099+ Empty ,
2100+
2101+ List {
2102+ projection : & ' p PlaceProjection < ' tcx > ,
2103+ next : & ' p PlaceProjections < ' p , ' tcx > ,
2104+ }
21072105}
21082106
2109- impl < ' p , ' tcx > PlaceComponents < ' p , ' tcx > {
2110- /// Converts a list of `Place ` components into an iterator; this
2111- /// iterator yields up a never-ending stream of `Option<&Place>`.
2112- /// These begin with the "innermost" place and then with each
2107+ impl < ' p , ' tcx > PlaceProjections < ' p , ' tcx > {
2108+ /// Converts a list of `PlaceProjection ` components into an iterator;
2109+ /// this iterator yields up a never-ending stream of `Option<&Place>`.
2110+ /// These begin with the "innermost" projection and then with each
21132111 /// projection therefrom. So given a place like `a.b.c` it would
21142112 /// yield up:
21152113 ///
21162114 /// ```notrust
21172115 /// Some(`a`), Some(`a.b`), Some(`a.b.c`), None, None, ...
21182116 /// ```
2119- fn iter ( & self ) -> PlaceComponentsIter < ' _ , ' tcx > {
2120- PlaceComponentsIter { value : Some ( self ) }
2117+ fn iter ( & self ) -> PlaceProjectionsIter < ' _ , ' tcx > {
2118+ PlaceProjectionsIter { value : self }
21212119 }
21222120}
21232121
2124- /// Iterator over components; see `PlaceComponents ::iter` for more
2122+ /// Iterator over components; see `PlaceProjections ::iter` for more
21252123/// information.
21262124///
21272125/// N.B., this is not a *true* Rust iterator -- the code above just
21282126/// manually invokes `next`. This is because we (sometimes) want to
21292127/// keep executing even after `None` has been returned.
2130- pub struct PlaceComponentsIter < ' p , ' tcx : ' p > {
2131- pub value : Option < & ' p PlaceComponents < ' p , ' tcx > > ,
2128+ pub struct PlaceProjectionsIter < ' p , ' tcx : ' p > {
2129+ pub value : & ' p PlaceProjections < ' p , ' tcx > ,
21322130}
21332131
2134- impl < ' p , ' tcx > PlaceComponentsIter < ' p , ' tcx > {
2135- pub fn next ( & mut self ) -> Option < & ' p Place < ' tcx > > {
2136- if let Some ( & PlaceComponents { component , next } ) = self . value {
2132+ impl < ' p , ' tcx > PlaceProjectionsIter < ' p , ' tcx > {
2133+ pub fn next ( & mut self ) -> Option < & ' p PlaceProjection < ' tcx > > {
2134+ if let & PlaceProjections :: List { projection , next } = self . value {
21372135 self . value = next;
2138- Some ( component )
2136+ Some ( projection )
21392137 } else {
21402138 None
21412139 }
0 commit comments