about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/mir/visit.rs28
-rw-r--r--src/librustc_mir/transform/inline.rs8
-rw-r--r--src/test/mir-opt/inline-retag.rs45
3 files changed, 74 insertions, 7 deletions
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index d60fff18b94..aa4004cf07b 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -152,6 +152,13 @@ macro_rules! make_mir_visitor {
                 self.super_ascribe_user_ty(place, variance, user_ty, location);
             }
 
+            fn visit_retag(&mut self,
+                           fn_entry: & $($mutability)* bool,
+                           place: & $($mutability)* Place<'tcx>,
+                           location: Location) {
+                self.super_retag(fn_entry, place, location);
+            }
+
             fn visit_place(&mut self,
                             place: & $($mutability)* Place<'tcx>,
                             context: PlaceContext<'tcx>,
@@ -371,13 +378,6 @@ macro_rules! make_mir_visitor {
                         );
                     }
                     StatementKind::EndRegion(_) => {}
-                    StatementKind::Retag { fn_entry: _, ref $($mutability)* place } => {
-                        self.visit_place(
-                            place,
-                            PlaceContext::MutatingUse(MutatingUseContext::Retag),
-                            location,
-                        );
-                    }
                     StatementKind::SetDiscriminant{ ref $($mutability)* place, .. } => {
                         self.visit_place(
                             place,
@@ -413,6 +413,9 @@ macro_rules! make_mir_visitor {
                             self.visit_operand(input, location);
                         }
                     }
+                    StatementKind::Retag { ref $($mutability)* fn_entry, ref $($mutability)* place } => {
+                        self.visit_retag(fn_entry, place, location);
+                    }
                     StatementKind::AscribeUserType(
                         ref $($mutability)* place,
                         ref $($mutability)* variance,
@@ -715,6 +718,17 @@ macro_rules! make_mir_visitor {
                 self.visit_user_type_projection(user_ty);
             }
 
+            fn super_retag(&mut self,
+                           _fn_entry: & $($mutability)* bool,
+                           place: & $($mutability)* Place<'tcx>,
+                           location: Location) {
+                self.visit_place(
+                    place,
+                    PlaceContext::MutatingUse(MutatingUseContext::Retag),
+                    location,
+                );
+            }
+
             fn super_place(&mut self,
                             place: & $($mutability)* Place<'tcx>,
                             context: PlaceContext<'tcx>,
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 5963f1a481c..199cf5650fd 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -691,6 +691,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
         self.in_cleanup_block = false;
     }
 
+    fn visit_retag(&mut self, fn_entry: &mut bool, place: &mut Place<'tcx>, loc: Location) {
+        self.super_retag(fn_entry, place, loc);
+
+        // We have to patch all inlined retags to be aware that they are no longer
+        // happening on function entry.
+        *fn_entry = false;
+    }
+
     fn visit_terminator_kind(&mut self, block: BasicBlock,
                              kind: &mut TerminatorKind<'tcx>, loc: Location) {
         self.super_terminator_kind(block, kind, loc);
diff --git a/src/test/mir-opt/inline-retag.rs b/src/test/mir-opt/inline-retag.rs
new file mode 100644
index 00000000000..4b3280ee561
--- /dev/null
+++ b/src/test/mir-opt/inline-retag.rs
@@ -0,0 +1,45 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Z span_free_formats -Z mir-emit-retag
+
+// Tests that MIR inliner fixes up `Retag`'s `fn_entry` flag
+
+fn main() {
+    println!("{}", bar());
+}
+
+#[inline(always)]
+fn foo(x: &i32, y: &i32) -> bool {
+    *x == *y
+}
+
+fn bar() -> bool {
+    let f = foo;
+    f(&1, &-1)
+}
+
+// END RUST SOURCE
+// START rustc.bar.Inline.after.mir
+// ...
+//     bb0: {
+//         ...
+//         Retag(_3);
+//         Retag(_6);
+//         StorageLive(_9);
+//         _9 = (*_3);
+//         StorageLive(_10);
+//         _10 = (*_6);
+//         _0 = Eq(move _9, move _10);
+//         ...
+//         return;
+//     }
+// ...
+// END rustc.bar.Inline.after.mir