Skip to content

Commit 3bf1bab

Browse files
committed
Make iterate take a FnOnce with PlaceBase and PlaceProjectionIter
1 parent 39f6d6b commit 3bf1bab

File tree

2 files changed

+240
-220
lines changed

2 files changed

+240
-220
lines changed

src/librustc/mir/mod.rs

+34-37
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)