]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/transform/add_retag.rs
Convert Place's projection to a boxed slice
[rust.git] / src / librustc_mir / transform / add_retag.rs
index d573423906c2ab58047d55c5bde6bfba735e7282..466f6060827ec1d7b15f95538157982bfbb841e0 100644 (file)
 fn is_stable(
     place: PlaceRef<'_, '_>,
 ) -> bool {
-    if let Some(proj) = &place.projection {
-        match proj.elem {
+    place.projection.iter().all(|elem| {
+        match elem {
             // Which place this evaluates to can change with any memory write,
             // so cannot assume this to be stable.
-            ProjectionElem::Deref =>
-                false,
+            ProjectionElem::Deref => false,
             // Array indices are intersting, but MIR building generates a *fresh*
             // temporary for every array access, so the index cannot be changed as
             // a side-effect.
@@ -31,20 +30,13 @@ fn is_stable(
             ProjectionElem::Field { .. } |
             ProjectionElem::ConstantIndex { .. } |
             ProjectionElem::Subslice { .. } |
-            ProjectionElem::Downcast { .. } =>
-                is_stable(PlaceRef {
-                    base: place.base,
-                    projection: &proj.base,
-                }),
+            ProjectionElem::Downcast { .. } => true,
         }
-    } else {
-        true
-    }
+    })
 }
 
-/// 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,22 +47,19 @@ 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,
     }
 }
 
-impl MirPass for AddRetag {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for AddRetag {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         if !tcx.sess.opts.debugging_opts.mir_emit_retag {
             return;
         }
@@ -80,7 +69,7 @@ fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Bo
             // 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