Skip to content

Commit 92d372a

Browse files
authored
Rollup merge of #98625 - RalfJung:retag, r=oli-obk
emit Retag for compound types with reference fields I want to add an option to Miri to do retagging inside reference fields. But that means we first have to even emit `Retag` for types that *contain* references (rather than being of reference types). :) Stacked Borrows originally did that, but we stopped doing it when hitting bunch of issues in the standard library. However I have since realized that we actually do emit `noalias` for newtypes references, which means for soundness we should recurse into fields. Also it'd probably be bad news if newtypes lose out on optimizations (and they don't, for anything else). I want to add an option for that to Miri so that we can start experimenting with those semantics. r? `@oli-obk`
2 parents bb8ad95 + 5fc1dd1 commit 92d372a

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

Diff for: compiler/rustc_mir_transform/src/add_retag.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ fn is_stable(place: PlaceRef<'_>) -> bool {
3333
})
3434
}
3535

36-
/// Determine whether this type may be a reference (or box), and thus needs retagging.
37-
fn may_be_reference(ty: Ty<'_>) -> bool {
36+
/// Determine whether this type may contain a reference (or box), and thus needs retagging.
37+
/// We will only recurse `depth` times into Tuples/ADTs to bound the cost of this.
38+
fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> bool {
3839
match ty.kind() {
3940
// Primitive types that are not references
4041
ty::Bool
@@ -50,8 +51,20 @@ fn may_be_reference(ty: Ty<'_>) -> bool {
5051
// References
5152
ty::Ref(..) => true,
5253
ty::Adt(..) if ty.is_box() => true,
53-
// Compound types are not references
54-
ty::Array(..) | ty::Slice(..) | ty::Tuple(..) | ty::Adt(..) => false,
54+
// Compound types: recurse
55+
ty::Array(ty, _) | ty::Slice(ty) => {
56+
// This does not branch so we keep the depth the same.
57+
may_contain_reference(*ty, depth, tcx)
58+
}
59+
ty::Tuple(tys) => {
60+
depth == 0 || tys.iter().any(|ty| may_contain_reference(ty, depth - 1, tcx))
61+
}
62+
ty::Adt(adt, subst) => {
63+
depth == 0
64+
|| adt.variants().iter().any(|v| {
65+
v.fields.iter().any(|f| may_contain_reference(f.ty(tcx, subst), depth - 1, tcx))
66+
})
67+
}
5568
// Conservative fallback
5669
_ => true,
5770
}
@@ -83,7 +96,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
8396
// FIXME: Instead of giving up for unstable places, we should introduce
8497
// a temporary and retag on that.
8598
is_stable(place.as_ref())
86-
&& may_be_reference(place.ty(&*local_decls, tcx).ty)
99+
&& may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
87100
&& is_not_temp(&local_decls[place.local])
88101
};
89102
let place_base_raw = |place: &Place<'tcx>| {

Diff for: src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir

+2
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ fn array_casts() -> () {
129129
_18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
130130
Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
131131
_13 = (move _14, move _18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
132+
Retag(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
132133
StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
133134
StorageDead(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
134135
StorageLive(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -171,6 +172,7 @@ fn array_casts() -> () {
171172
Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
172173
StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
173174
_34 = Option::<Arguments>::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
175+
Retag(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
174176
_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
175177
// mir::Constant
176178
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL

0 commit comments

Comments
 (0)