@@ -2045,84 +2045,81 @@ impl<'tcx> Place<'tcx> {
20452045 }
20462046 }
20472047
2048- /// Recursively "iterates" over place components, generating a `PlaceComponents` list,
2049- /// invoking `op` with a `PlaceComponentsIter `.
2048+ /// Recursively "iterates" over place components, generating a `PlaceBase` and
2049+ /// `PlaceProjections` list and invoking `op` with a `PlaceProjectionsIter `.
20502050 pub fn iterate < R > (
20512051 & self ,
2052- op : impl FnOnce ( PlaceComponentsIter < ' _ , ' tcx > ) -> R ,
2052+ op : impl FnOnce ( & PlaceBase < ' tcx > , PlaceProjectionsIter < ' _ , ' tcx > ) -> R ,
20532053 ) -> R {
2054- self . iterate2 ( None , op)
2054+ self . iterate2 ( & PlaceProjections :: Empty , op)
20552055 }
20562056
20572057 fn iterate2 < R > (
20582058 & self ,
2059- next : Option < & PlaceComponents < ' _ , ' tcx > > ,
2060- op : impl FnOnce ( PlaceComponentsIter < ' _ , ' tcx > ) -> R ,
2059+ next : & PlaceProjections < ' _ , ' tcx > ,
2060+ op : impl FnOnce ( & PlaceBase < ' tcx > , PlaceProjectionsIter < ' _ , ' tcx > ) -> R ,
20612061 ) -> R {
20622062 match self {
20632063 Place :: Projection ( interior) => interior. base . iterate2 (
2064- Some ( & PlaceComponents {
2065- component : self ,
2064+ & PlaceProjections :: List {
2065+ projection : interior ,
20662066 next,
2067- } ) ,
2067+ } ,
20682068 op,
20692069 ) ,
20702070
2071- Place :: Base ( PlaceBase :: Promoted ( _) ) |
2072- Place :: Base ( PlaceBase :: Local ( _) ) | Place :: Base ( PlaceBase :: Static ( _) ) => {
2073- let list = PlaceComponents {
2074- component : self ,
2075- next,
2076- } ;
2077- op ( list. iter ( ) )
2078- }
2071+ Place :: Base ( base) => op ( base, next. iter ( ) ) ,
20792072 }
20802073 }
20812074}
20822075
2083- /// A linked list of places running up the stack; begins with the
2084- /// innermost place and extends to projections (e.g., `a.b` would have
2085- /// the place `a ` with a "next" pointer to `a.b `). Created by
2086- /// `Place::iterate`.
2076+ /// A linked list of projections running up the stack; begins with the
2077+ /// innermost projection and extends to the outermost (e.g., `a.b.c`
2078+ /// would have the place `b ` with a "next" pointer to `b.c `).
2079+ /// Created by `Place::iterate`.
20872080///
20882081/// N.B., this particular impl strategy is not the most obvious. It was
20892082/// chosen because it makes a measurable difference to NLL
20902083/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
2091- pub struct PlaceComponents < ' p , ' tcx : ' p > {
2092- pub component : & ' p Place < ' tcx > ,
2093- pub next : Option < & ' p PlaceComponents < ' p , ' tcx > > ,
2084+ pub enum PlaceProjections < ' p , ' tcx : ' p > {
2085+ Empty ,
2086+
2087+ List {
2088+ projection : & ' p PlaceProjection < ' tcx > ,
2089+ next : & ' p PlaceProjections < ' p , ' tcx > ,
2090+ }
20942091}
20952092
2096- impl < ' p , ' tcx > PlaceComponents < ' p , ' tcx > {
2097- /// Converts a list of `Place ` components into an iterator; this
2098- /// iterator yields up a never-ending stream of `Option<&Place>`.
2099- /// These begin with the "innermost" place and then with each
2093+ impl < ' p , ' tcx > PlaceProjections < ' p , ' tcx > {
2094+ /// Converts a list of `PlaceProjection ` components into an iterator;
2095+ /// this iterator yields up a never-ending stream of `Option<&Place>`.
2096+ /// These begin with the "innermost" projection and then with each
21002097 /// projection therefrom. So given a place like `a.b.c` it would
21012098 /// yield up:
21022099 ///
21032100 /// ```notrust
21042101 /// Some(`a`), Some(`a.b`), Some(`a.b.c`), None, None, ...
21052102 /// ```
2106- fn iter ( & self ) -> PlaceComponentsIter < ' _ , ' tcx > {
2107- PlaceComponentsIter { value : Some ( self ) }
2103+ fn iter ( & self ) -> PlaceProjectionsIter < ' _ , ' tcx > {
2104+ PlaceProjectionsIter { value : self }
21082105 }
21092106}
21102107
2111- /// Iterator over components; see `PlaceComponents ::iter` for more
2108+ /// Iterator over components; see `PlaceProjections ::iter` for more
21122109/// information.
21132110///
21142111/// N.B., this is not a *true* Rust iterator -- the code above just
21152112/// manually invokes `next`. This is because we (sometimes) want to
21162113/// keep executing even after `None` has been returned.
2117- pub struct PlaceComponentsIter < ' p , ' tcx : ' p > {
2118- pub value : Option < & ' p PlaceComponents < ' p , ' tcx > > ,
2114+ pub struct PlaceProjectionsIter < ' p , ' tcx : ' p > {
2115+ pub value : & ' p PlaceProjections < ' p , ' tcx > ,
21192116}
21202117
2121- impl < ' p , ' tcx > PlaceComponentsIter < ' p , ' tcx > {
2122- pub fn next ( & mut self ) -> Option < & ' p Place < ' tcx > > {
2123- if let Some ( & PlaceComponents { component , next } ) = self . value {
2118+ impl < ' p , ' tcx > PlaceProjectionsIter < ' p , ' tcx > {
2119+ pub fn next ( & mut self ) -> Option < & ' p PlaceProjection < ' tcx > > {
2120+ if let & PlaceProjections :: List { projection , next } = self . value {
21242121 self . value = next;
2125- Some ( component )
2122+ Some ( projection )
21262123 } else {
21272124 None
21282125 }
0 commit comments