Skip to content

Commit 4972736

Browse files
committed
don't use Iterator and zip but just invoke next manually
This micro-optimizes some if checks away; the compiler may already have been doing it, not sure.
1 parent e10414e commit 4972736

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

src/librustc_mir/borrow_check/places_conflict.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ pub(super) fn places_conflict<'gcx, 'tcx>(
3838
fn place_components_conflict<'gcx, 'tcx>(
3939
tcx: TyCtxt<'_, 'gcx, 'tcx>,
4040
mir: &Mir<'tcx>,
41-
borrow_components: PlaceComponentsIter<'_, 'tcx>,
42-
access_components: PlaceComponentsIter<'_, 'tcx>,
41+
mut borrow_components: PlaceComponentsIter<'_, 'tcx>,
42+
mut access_components: PlaceComponentsIter<'_, 'tcx>,
4343
access: ShallowOrDeep,
4444
) -> bool {
4545
// The borrowck rules for proving disjointness are applied from the "root" of the
@@ -83,11 +83,14 @@ fn place_components_conflict<'gcx, 'tcx>(
8383
// - If we didn't run out of access to match, our borrow and access are comparable
8484
// and either equal or disjoint.
8585
// - If we did run out of accesss, the borrow can access a part of it.
86-
for (borrow_c, access_c) in borrow_components.zip(access_components) {
86+
loop {
8787
// loop invariant: borrow_c is always either equal to access_c or disjoint from it.
88-
debug!("places_conflict: {:?} vs. {:?}", borrow_c, access_c);
89-
if let Some(borrow_c) = borrow_c {
90-
if let Some(access_c) = access_c {
88+
if let Some(borrow_c) = borrow_components.next() {
89+
debug!("places_conflict: borrow_c = {:?}", borrow_c);
90+
91+
if let Some(access_c) = access_components.next() {
92+
debug!("places_conflict: access_c = {:?}", access_c);
93+
9194
// Borrow and access path both have more components.
9295
//
9396
// Examples:
@@ -214,7 +217,6 @@ fn place_components_conflict<'gcx, 'tcx>(
214217
return true;
215218
}
216219
}
217-
unreachable!("iter::repeat returned None")
218220
}
219221

220222
/// A linked list of places running up the stack; begins with the
@@ -243,19 +245,21 @@ impl<'p, 'tcx> PlaceComponents<'p, 'tcx> {
243245

244246
/// Iterator over components; see `PlaceComponents::iter` for more
245247
/// information.
248+
///
249+
/// NB: This is not a *true* Rust iterator -- the code above just
250+
/// manually invokes `next`. This is because we (sometimes) want to
251+
/// keep executing even after `None` has been returned.
246252
struct PlaceComponentsIter<'p, 'tcx: 'p> {
247253
value: Option<&'p PlaceComponents<'p, 'tcx>>
248254
}
249255

250-
impl<'p, 'tcx> Iterator for PlaceComponentsIter<'p, 'tcx> {
251-
type Item = Option<&'p Place<'tcx>>;
252-
253-
fn next(&mut self) -> Option<Self::Item> {
256+
impl<'p, 'tcx> PlaceComponentsIter<'p, 'tcx> {
257+
fn next(&mut self) -> Option<&'p Place<'tcx>> {
254258
if let Some(&PlaceComponents { component, next }) = self.value {
255259
self.value = next;
256-
Some(Some(component))
260+
Some(component)
257261
} else {
258-
Some(None)
262+
None
259263
}
260264
}
261265
}

0 commit comments

Comments
 (0)