diff options
| author | bors <bors@rust-lang.org> | 2022-06-29 15:05:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-06-29 15:05:29 +0000 |
| commit | 3fcf43bb0f3e86c16a88f239da18a1729a94d244 (patch) | |
| tree | 17006f074d35aff9787abc12ac80094d53a436b2 /compiler/rustc_mir_transform/src | |
| parent | 66c83ffca1512ed76f9445ec7f7280f768ef71c4 (diff) | |
| parent | 68228be56062eb62f09088663e93ea66109156f8 (diff) | |
| download | rust-3fcf43bb0f3e86c16a88f239da18a1729a94d244.tar.gz rust-3fcf43bb0f3e86c16a88f239da18a1729a94d244.zip | |
Auto merge of #98669 - Dylan-DPC:rollup-8uzhcip, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #98415 (Migrate some `rustc_borrowck` diagnostics to `SessionDiagnostic`) - #98479 (Add `fetch_not` method on `AtomicBool`) - #98499 (Erase regions in New Abstract Consts) - #98516 (library: fix uefi va_list type definition) - #98554 (Fix box with custom allocator in miri) - #98607 (Clean up arg mismatch diagnostic, generalize tuple wrap suggestion) - #98625 (emit Retag for compound types with reference fields) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/add_retag.rs | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 0495439385b..0f87e638d26 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -33,8 +33,9 @@ fn is_stable(place: PlaceRef<'_>) -> bool { }) } -/// Determine whether this type may be a reference (or box), and thus needs retagging. -fn may_be_reference(ty: Ty<'_>) -> bool { +/// Determine whether this type may contain a reference (or box), and thus needs retagging. +/// 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() { // Primitive types that are not references ty::Bool @@ -50,8 +51,20 @@ fn may_be_reference(ty: Ty<'_>) -> bool { // References ty::Ref(..) => true, ty::Adt(..) if ty.is_box() => true, - // Compound types are not references - ty::Array(..) | ty::Slice(..) | ty::Tuple(..) | ty::Adt(..) => false, + // Compound types: recurse + 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 _ => true, } @@ -83,7 +96,7 @@ impl<'tcx> MirPass<'tcx> 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_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]) }; let place_base_raw = |place: &Place<'tcx>| { |
