about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-08-15 14:34:01 +0200
committerGitHub <noreply@github.com>2019-08-15 14:34:01 +0200
commit988cd5d50c203d5d37da8e0e047381fbebf53b8d (patch)
tree92553547582d4ba767f3696d04fb826a2bbafb48
parent7e9682559e5b5fc5a37b25e8e6500cddf743081b (diff)
parent2122fe4611d194534e2c60b0b0bb7e86c63e68b0 (diff)
downloadrust-988cd5d50c203d5d37da8e0e047381fbebf53b8d.tar.gz
rust-988cd5d50c203d5d37da8e0e047381fbebf53b8d.zip
Rollup merge of #63306 - RalfJung:retag, r=varkor
Adapt AddRetag for shallow retagging

With https://github.com/rust-lang/miri/pull/872, Miri only retags "bare" references, not those nested in compound types. This adjust `Retag` statement generation to don't emit retags if they are definitely not a bare reference.

I also expanded the mir-opt test to cover the `Retag` in the drop shim, which had previously not been tested.
-rw-r--r--src/librustc_mir/transform/add_retag.rs22
-rw-r--r--src/test/mir-opt/retag.rs38
2 files changed, 36 insertions, 24 deletions
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index d573423906c..524a19e3434 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -42,9 +42,8 @@ fn is_stable(
     }
 }
 
-/// Determine whether this type may have a reference in it, recursing below compound types but
-/// not below references.
-fn may_have_reference<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
+/// Determine whether this type may be a reference (or box), and thus needs retagging.
+fn may_be_reference<'tcx>(ty: Ty<'tcx>) -> bool {
     match ty.sty {
         // Primitive types that are not references
         ty::Bool | ty::Char |
@@ -55,15 +54,12 @@ fn may_have_reference<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
         // References
         ty::Ref(..) => true,
         ty::Adt(..) if ty.is_box() => true,
-        // Compound types
-        ty::Array(ty, ..) | ty::Slice(ty) =>
-            may_have_reference(ty, tcx),
-        ty::Tuple(tys) =>
-            tys.iter().any(|ty| may_have_reference(ty.expect_ty(), tcx)),
-        ty::Adt(adt, substs) =>
-            adt.variants.iter().any(|v| v.fields.iter().any(|f|
-                may_have_reference(f.ty(tcx, substs), tcx)
-            )),
+        // Compound types are not references
+        ty::Array(..) |
+        ty::Slice(..) |
+        ty::Tuple(..) |
+        ty::Adt(..) =>
+            false,
         // Conservative fallback
         _ => true,
     }
@@ -80,7 +76,7 @@ impl MirPass for AddRetag {
             // FIXME: Instead of giving up for unstable places, we should introduce
             // a temporary and retag on that.
             is_stable(place.as_ref())
-                && may_have_reference(place.ty(&*local_decls, tcx).ty, tcx)
+                && may_be_reference(place.ty(&*local_decls, tcx).ty)
         };
 
         // PART 1
diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs
index 33ee0fe61b2..db36a1fab5f 100644
--- a/src/test/mir-opt/retag.rs
+++ b/src/test/mir-opt/retag.rs
@@ -1,3 +1,4 @@
+// ignore-wasm32-bare compiled with panic=abort by default
 // ignore-tidy-linelength
 // compile-flags: -Z mir-emit-retag -Z mir-opt-level=0 -Z span_free_formats
 
@@ -11,6 +12,10 @@ impl Test {
     fn foo_shr<'x>(&self, x: &'x i32) -> &'x i32 { x }
 }
 
+impl Drop for Test {
+    fn drop(&mut self) {}
+}
+
 fn main() {
     let mut x = 0;
     {
@@ -60,10 +65,12 @@ fn main() {
 //     ...
 //     bb0: {
 //         ...
-//         _3 = const Test::foo(move _4, move _6) -> bb1;
+//         _3 = const Test::foo(move _4, move _6) -> [return: bb2, unwind: bb3];
 //     }
 //
-//     bb1: {
+//     ...
+//
+//     bb2: {
 //         Retag(_3);
 //         ...
 //         _9 = move _3;
@@ -80,25 +87,20 @@ fn main() {
 //         _12 = move _13 as *mut i32 (Misc);
 //         Retag([raw] _12);
 //         ...
-//         _16 = move _17(move _18) -> bb2;
+//         _16 = move _17(move _18) -> bb5;
 //     }
 //
-//     bb2: {
+//     bb5: {
 //         Retag(_16);
 //         ...
-//         _20 = const Test::foo_shr(move _21, move _23) -> bb3;
-//     }
-//
-//     bb3: {
-//         ...
-//         return;
+//         _20 = const Test::foo_shr(move _21, move _23) -> [return: bb6, unwind: bb7];
 //     }
 //
 //     ...
 // }
 // END rustc.main.EraseRegions.after.mir
 // START rustc.main-{{closure}}.EraseRegions.after.mir
-// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(20), local_id: 72 }], _2: &i32) -> &i32 {
+// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(22), local_id: 72 }], _2: &i32) -> &i32 {
 //     ...
 //     bb0: {
 //         Retag([fn entry] _1);
@@ -113,3 +115,17 @@ fn main() {
 //     }
 // }
 // END rustc.main-{{closure}}.EraseRegions.after.mir
+// START rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir
+// fn  std::ptr::real_drop_in_place(_1: &mut Test) -> () {
+//     ...
+//     bb0: {
+//         Retag([raw] _1);
+//         _2 = &mut (*_1);
+//         _3 = const <Test as std::ops::Drop>::drop(move _2) -> bb1;
+//     }
+//
+//     bb1: {
+//         return;
+//     }
+// }
+// END rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir