about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAaron Hill <aa1ronham@gmail.com>2020-01-01 20:10:55 -0500
committerAaron Hill <aa1ronham@gmail.com>2020-01-01 20:10:55 -0500
commite8e53b56dff3cd1f9e6d65ee30d5e0bfc55d9607 (patch)
tree01164280b7eeceb1a28e10d42a7e371e5dc01010
parent0ec370670220b712b042ee09aab067ec7e5878d5 (diff)
downloadrust-e8e53b56dff3cd1f9e6d65ee30d5e0bfc55d9607.tar.gz
rust-e8e53b56dff3cd1f9e6d65ee30d5e0bfc55d9607.zip
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.
-rw-r--r--src/librustc_mir/transform/inline.rs12
-rw-r--r--src/test/ui/mir/issue-67710-inline-projection.rs17
2 files changed, 21 insertions, 8 deletions
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 98cd3417709..3c9f8542e51 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<PlaceElem<'tcx>> {
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 00000000000..37d8f2eac9b
--- /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(());
+}