diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 865fa012c29..a801548efab 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -88,6 +88,24 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor { *local = self.to; } } + + fn visit_place(&mut self, + place: &mut Place<'tcx>, + context: PlaceContext, + location: Location) { + self.visit_place_base(&mut place.base, context, location); + + let new_projection: Vec<_> = place.projection.iter().map(|elem| + match elem { + PlaceElem::Index(local) if *local == self.from => { + PlaceElem::Index(self.to) + } + _ => elem.clone(), + } + ).collect(); + + place.projection = new_projection.into_boxed_slice(); + } } struct DerefArgVisitor; @@ -110,7 +128,13 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor { projection: Box::new([ProjectionElem::Deref]), }); } else { - self.super_place(place, context, location); + self.visit_place_base(&mut place.base, context, location); + + for elem in place.projection.iter() { + if let PlaceElem::Index(local) = elem { + assert_ne!(*local, self_arg()); + } + } } } } @@ -137,7 +161,13 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { projection: Box::new([ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]), }); } else { - self.super_place(place, context, location); + self.visit_place_base(&mut place.base, context, location); + + for elem in place.projection.iter() { + if let PlaceElem::Index(local) = elem { + assert_ne!(*local, self_arg()); + } + } } } } @@ -247,17 +277,25 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { assert_eq!(self.remap.get(local), None); } - fn visit_place(&mut self, - place: &mut Place<'tcx>, - context: PlaceContext, - location: Location) { + fn visit_place( + &mut self, + place: &mut Place<'tcx>, + context: PlaceContext, + location: Location, + ) { if let PlaceBase::Local(l) = place.base { // Replace an Local in the remap with a generator struct access if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) { replace_base(place, self.make_field(variant_index, idx, ty)); } } else { - self.super_place(place, context, location); + self.visit_place_base(&mut place.base, context, location); + + for elem in place.projection.iter() { + if let PlaceElem::Index(local) = elem { + assert_ne!(*local, self_arg()); + } + } } }