@@ -38,8 +38,8 @@ pub(super) fn places_conflict<'gcx, 'tcx>(
38
38
fn place_components_conflict < ' gcx , ' tcx > (
39
39
tcx : TyCtxt < ' _ , ' gcx , ' tcx > ,
40
40
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 > ,
43
43
access : ShallowOrDeep ,
44
44
) -> bool {
45
45
// The borrowck rules for proving disjointness are applied from the "root" of the
@@ -83,11 +83,14 @@ fn place_components_conflict<'gcx, 'tcx>(
83
83
// - If we didn't run out of access to match, our borrow and access are comparable
84
84
// and either equal or disjoint.
85
85
// - 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 {
87
87
// 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
+
91
94
// Borrow and access path both have more components.
92
95
//
93
96
// Examples:
@@ -214,7 +217,6 @@ fn place_components_conflict<'gcx, 'tcx>(
214
217
return true ;
215
218
}
216
219
}
217
- unreachable ! ( "iter::repeat returned None" )
218
220
}
219
221
220
222
/// A linked list of places running up the stack; begins with the
@@ -243,19 +245,21 @@ impl<'p, 'tcx> PlaceComponents<'p, 'tcx> {
243
245
244
246
/// Iterator over components; see `PlaceComponents::iter` for more
245
247
/// 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.
246
252
struct PlaceComponentsIter < ' p , ' tcx : ' p > {
247
253
value : Option < & ' p PlaceComponents < ' p , ' tcx > >
248
254
}
249
255
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 > > {
254
258
if let Some ( & PlaceComponents { component, next } ) = self . value {
255
259
self . value = next;
256
- Some ( Some ( component) )
260
+ Some ( component)
257
261
} else {
258
- Some ( None )
262
+ None
259
263
}
260
264
}
261
265
}
0 commit comments