emit Retag for compound types with reference fields
This commit is contained in:
parent
7f08d04d60
commit
5fc1dd11a9
2 changed files with 20 additions and 5 deletions
|
@ -33,8 +33,9 @@ fn is_stable(place: PlaceRef<'_>) -> bool {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine whether this type may be a reference (or box), and thus needs retagging.
|
/// Determine whether this type may contain a reference (or box), and thus needs retagging.
|
||||||
fn may_be_reference(ty: Ty<'_>) -> bool {
|
/// We will only recurse `depth` times into Tuples/ADTs to bound the cost of this.
|
||||||
|
fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> bool {
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
// Primitive types that are not references
|
// Primitive types that are not references
|
||||||
ty::Bool
|
ty::Bool
|
||||||
|
@ -50,8 +51,20 @@ fn may_be_reference(ty: Ty<'_>) -> bool {
|
||||||
// References
|
// References
|
||||||
ty::Ref(..) => true,
|
ty::Ref(..) => true,
|
||||||
ty::Adt(..) if ty.is_box() => true,
|
ty::Adt(..) if ty.is_box() => true,
|
||||||
// Compound types are not references
|
// Compound types: recurse
|
||||||
ty::Array(..) | ty::Slice(..) | ty::Tuple(..) | ty::Adt(..) => false,
|
ty::Array(ty, _) | ty::Slice(ty) => {
|
||||||
|
// This does not branch so we keep the depth the same.
|
||||||
|
may_contain_reference(*ty, depth, tcx)
|
||||||
|
}
|
||||||
|
ty::Tuple(tys) => {
|
||||||
|
depth == 0 || tys.iter().any(|ty| may_contain_reference(ty, depth - 1, tcx))
|
||||||
|
}
|
||||||
|
ty::Adt(adt, subst) => {
|
||||||
|
depth == 0
|
||||||
|
|| adt.variants().iter().any(|v| {
|
||||||
|
v.fields.iter().any(|f| may_contain_reference(f.ty(tcx, subst), depth - 1, tcx))
|
||||||
|
})
|
||||||
|
}
|
||||||
// Conservative fallback
|
// Conservative fallback
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
|
@ -83,7 +96,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
|
||||||
// FIXME: Instead of giving up for unstable places, we should introduce
|
// FIXME: Instead of giving up for unstable places, we should introduce
|
||||||
// a temporary and retag on that.
|
// a temporary and retag on that.
|
||||||
is_stable(place.as_ref())
|
is_stable(place.as_ref())
|
||||||
&& may_be_reference(place.ty(&*local_decls, tcx).ty)
|
&& may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
|
||||||
&& is_not_temp(&local_decls[place.local])
|
&& is_not_temp(&local_decls[place.local])
|
||||||
};
|
};
|
||||||
let place_base_raw = |place: &Place<'tcx>| {
|
let place_base_raw = |place: &Place<'tcx>| {
|
||||||
|
|
|
@ -129,6 +129,7 @@ fn array_casts() -> () {
|
||||||
_18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
_18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
_13 = (move _14, move _18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
_13 = (move _14, move _18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
Retag(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
StorageDead(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
StorageDead(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
StorageLive(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
StorageLive(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
@ -171,6 +172,7 @@ fn array_casts() -> () {
|
||||||
Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
_34 = Option::<Arguments>::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
_34 = Option::<Arguments>::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
Retag(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
_28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
_28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue