From e8e53b56dff3cd1f9e6d65ee30d5e0bfc55d9607 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 1 Jan 2020 20:10:55 -0500 Subject: [PATCH] Ensure that we process projections during MIR inlining Fixes #67710 Previously, we were not calling `super_place`, which resulted in us failing to update any local references that occur in ProjectionElem::Index. This caused the post-inlining MIR to contain a reference to a local ID from the inlined callee, leading to an ICE due to a type mismatch. --- src/librustc_mir/transform/inline.rs | 12 ++++-------- .../ui/mir/issue-67710-inline-projection.rs | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/mir/issue-67710-inline-projection.rs diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 98cd341770965..3c9f8542e51d0 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -671,12 +671,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { *local = self.make_integrate_local(local); } - 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) { match &mut place.base { PlaceBase::Static(_) => {} PlaceBase::Local(l) => { @@ -689,10 +684,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { place.projection = self.tcx.intern_place_elems(&*projs); } - - *l = self.make_integrate_local(l); } } + // Handles integrating any locals that occur in the base + // or projections + self.super_place(place, context, location) } fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option> { diff --git a/src/test/ui/mir/issue-67710-inline-projection.rs b/src/test/ui/mir/issue-67710-inline-projection.rs new file mode 100644 index 0000000000000..37d8f2eac9be1 --- /dev/null +++ b/src/test/ui/mir/issue-67710-inline-projection.rs @@ -0,0 +1,17 @@ +// compile-flags: -Z mir-opt-level=2 +// build-pass + +// This used to ICE due to the inling pass not examining projections +// for references to locals + +pub fn parse(version: ()) { + p(&b'.', b"0"); +} +#[inline(always)] +fn p(byte: &u8, s: &[u8]) { + !(s[0] == *byte); +} + +fn main() { + parse(()); +}