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.
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 |
// 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;
}
// 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