Skip to content

Commit b461740

Browse files
committed
Make iterate take a FnOnce with PlaceBase and PlaceProjectionIter
1 parent 0326f0a commit b461740

File tree

2 files changed

+236
-214
lines changed

2 files changed

+236
-214
lines changed

src/librustc/mir/mod.rs

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

Comments
 (0)