Skip to content

Commit c37fbd8

Browse files
committed
Auto merge of rust-lang#135318 - compiler-errors:vtable-fixes, r=lcnr
Fix deduplication mismatches in vtables leading to upcasting unsoundness We currently have two cases where subtleties in supertraits can trigger disagreements in the vtable layout, e.g. leading to a different vtable layout being accessed at a callsite compared to what was prepared during unsizing. Namely: ### rust-lang#135315 In this example, we were not normalizing supertraits when preparing vtables. In the example, ``` trait Supertrait<T> { fn _print_numbers(&self, mem: &[usize; 100]) { println!("{mem:?}"); } } impl<T> Supertrait<T> for () {} trait Identity { type Selff; } impl<Selff> Identity for Selff { type Selff = Selff; } trait Middle<T>: Supertrait<()> + Supertrait<T> { fn say_hello(&self, _: &usize) { println!("Hello!"); } } impl<T> Middle<T> for () {} trait Trait: Middle<<() as Identity>::Selff> {} impl Trait for () {} fn main() { (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0); } ``` When we prepare `dyn Trait`, we see a supertrait of `Middle<<() as Identity>::Selff>`, which itself has two supertraits `Supertrait<()>` and `Supertrait<<() as Identity>::Selff>`. These two supertraits are identical, but they are not duplicated because we were using structural equality and *not* considering normalization. This leads to a vtable layout with two trait pointers. When we upcast to `dyn Middle<()>`, those two supertraits are now the same, leading to a vtable layout with only one trait pointer. This leads to an offset error, and we call the wrong method. ### rust-lang#135316 This one is a bit more interesting, and is the bulk of the changes in this PR. It's a bit similar, except it uses binder equality instead of normalization to make the compiler get confused about two vtable layouts. In the example, ``` trait Supertrait<T> { fn _print_numbers(&self, mem: &[usize; 100]) { println!("{mem:?}"); } } impl<T> Supertrait<T> for () {} trait Trait<T, U>: Supertrait<T> + Supertrait<U> { fn say_hello(&self, _: &usize) { println!("Hello!"); } } impl<T, U> Trait<T, U> for () {} fn main() { (&() as &'static dyn for<'a> Trait<&'static (), &'a ()> as &'static dyn Trait<&'static (), &'static ()>) .say_hello(&0); } ``` When we prepare the vtable for `dyn for<'a> Trait<&'static (), &'a ()>`, we currently consider the PolyTraitRef of the vtable as the key for a supertrait. This leads two two supertraits -- `Supertrait<&'static ()>` and `for<'a> Supertrait<&'a ()>`. However, we can upcast[^up] without offsetting the vtable from `dyn for<'a> Trait<&'static (), &'a ()>` to `dyn Trait<&'static (), &'static ()>`. This is just instantiating the principal trait ref for a specific `'a = 'static`. However, when considering those supertraits, we now have only one distinct supertrait -- `Supertrait<&'static ()>` (which is deduplicated since there are two supertraits with the same substitutions). This leads to similar offsetting issues, leading to the wrong method being called. [^up]: I say upcast but this is a cast that is allowed on stable, since it's not changing the vtable at all, just instantiating the binder of the principal trait ref for some lifetime. The solution here is to recognize that a vtable isn't really meaningfully higher ranked, and to just treat a vtable as corresponding to a `TraitRef` so we can do this deduplication more faithfully. That is to say, the vtable for `dyn for<'a> Tr<'a>` and `dyn Tr<'x>` are always identical, since they both would correspond to a set of free regions on an impl... Do note that `Tr<for<'a> fn(&'a ())>` and `Tr<fn(&'static ())>` are still distinct. ---- There's a bit more that can be cleaned up. In codegen, we can stop using `PolyExistentialTraitRef` basically everywhere. We can also fix SMIR to stop storing `PolyExistentialTraitRef` in its vtable allocations. As for testing, it's difficult to actually turn this into something that can be tested with `rustc_dump_vtable`, since having multiple supertraits that are identical is a recipe for ambiguity errors. Maybe someone else is more creative with getting that attr to work, since the tests I added being run-pass tests is a bit unsatisfying. Miri also doesn't help here, since it doesn't really generate vtables that are offset by an index in the same way as codegen. r? `@lcnr` for the vibe check? Or reassign, idk. Maybe let's talk about whether this makes sense. <sup>(I guess an alternative would also be to not do any deduplication of vtable supertraits (or only a really conservative subset) rather than trying to normalize and deduplicate more faithfully here. Not sure if that works and is sufficient tho.)</sup> cc `@steffahn` -- ty for the minimizations cc `@WaffleLapkin` -- since you're overseeing the feature stabilization :3 Fixes rust-lang#135315 Fixes rust-lang#135316
2 parents 6c1d960 + d98b99a commit c37fbd8

File tree

63 files changed

+905
-728
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+905
-728
lines changed

compiler/rustc_codegen_cranelift/src/constant.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use cranelift_module::*;
66
use rustc_data_structures::fx::FxHashSet;
77
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
88
use rustc_middle::mir::interpret::{AllocId, GlobalAlloc, Scalar, read_target_uint};
9-
use rustc_middle::ty::{Binder, ExistentialTraitRef, ScalarInt};
9+
use rustc_middle::ty::{ExistentialTraitRef, ScalarInt};
1010

1111
use crate::prelude::*;
1212

@@ -167,7 +167,9 @@ pub(crate) fn codegen_const_value<'tcx>(
167167
&mut fx.constants_cx,
168168
fx.module,
169169
ty,
170-
dyn_ty.principal(),
170+
dyn_ty.principal().map(|principal| {
171+
fx.tcx.instantiate_bound_regions_with_erased(principal)
172+
}),
171173
);
172174
let local_data_id =
173175
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
@@ -243,7 +245,7 @@ pub(crate) fn data_id_for_vtable<'tcx>(
243245
cx: &mut ConstantCx,
244246
module: &mut dyn Module,
245247
ty: Ty<'tcx>,
246-
trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>,
248+
trait_ref: Option<ExistentialTraitRef<'tcx>>,
247249
) -> DataId {
248250
let alloc_id = tcx.vtable_allocation((ty, trait_ref));
249251
data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not)
@@ -460,9 +462,15 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
460462
GlobalAlloc::Memory(target_alloc) => {
461463
data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability)
462464
}
463-
GlobalAlloc::VTable(ty, dyn_ty) => {
464-
data_id_for_vtable(tcx, cx, module, ty, dyn_ty.principal())
465-
}
465+
GlobalAlloc::VTable(ty, dyn_ty) => data_id_for_vtable(
466+
tcx,
467+
cx,
468+
module,
469+
ty,
470+
dyn_ty
471+
.principal()
472+
.map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
473+
),
466474
GlobalAlloc::Static(def_id) => {
467475
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
468476
{

compiler/rustc_codegen_cranelift/src/unsize.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,12 @@ pub(crate) fn unsized_info<'tcx>(
6161
old_info
6262
}
6363
}
64-
(_, ty::Dynamic(data, ..)) => crate::vtable::get_vtable(fx, source, data.principal()),
64+
(_, ty::Dynamic(data, ..)) => crate::vtable::get_vtable(
65+
fx,
66+
source,
67+
data.principal()
68+
.map(|principal| fx.tcx.instantiate_bound_regions_with_erased(principal)),
69+
),
6570
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
6671
}
6772
}

compiler/rustc_codegen_cranelift/src/vtable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
9090
pub(crate) fn get_vtable<'tcx>(
9191
fx: &mut FunctionCx<'_, '_, 'tcx>,
9292
ty: Ty<'tcx>,
93-
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
93+
trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
9494
) -> Value {
9595
let data_id = data_id_for_vtable(fx.tcx, &mut fx.constants_cx, fx.module, ty, trait_ref);
9696
let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func);

compiler/rustc_codegen_gcc/src/common.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
234234
GlobalAlloc::VTable(ty, dyn_ty) => {
235235
let alloc = self
236236
.tcx
237-
.global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal())))
237+
.global_alloc(self.tcx.vtable_allocation((
238+
ty,
239+
dyn_ty.principal().map(|principal| {
240+
self.tcx.instantiate_bound_regions_with_erased(principal)
241+
}),
242+
)))
238243
.unwrap_memory();
239244
let init = const_alloc_to_gcc(self, alloc);
240245
self.static_addr_of(init, alloc.inner().align, None)

compiler/rustc_codegen_gcc/src/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::ty::layout::{
1414
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError,
1515
LayoutOfHelpers,
1616
};
17-
use rustc_middle::ty::{self, Instance, PolyExistentialTraitRef, Ty, TyCtxt};
17+
use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt};
1818
use rustc_session::Session;
1919
use rustc_span::source_map::respan;
2020
use rustc_span::{DUMMY_SP, Span};
@@ -90,7 +90,7 @@ pub struct CodegenCx<'gcc, 'tcx> {
9090
pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
9191
/// Cache generated vtables
9292
pub vtables:
93-
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
93+
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
9494

9595
// TODO(antoyo): improve the SSA API to not require those.
9696
/// Mapping from function pointer type to indexes of on stack parameters.
@@ -401,7 +401,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
401401
impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
402402
fn vtables(
403403
&self,
404-
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
404+
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
405405
&self.vtables
406406
}
407407

compiler/rustc_codegen_gcc/src/debuginfo.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_data_structures::sync::Lrc;
77
use rustc_index::bit_set::DenseBitSet;
88
use rustc_index::{Idx, IndexVec};
99
use rustc_middle::mir::{self, Body, SourceScope};
10-
use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty};
10+
use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty};
1111
use rustc_session::config::DebugInfo;
1212
use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol};
1313
use rustc_target::abi::Size;
@@ -214,7 +214,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
214214
fn create_vtable_debuginfo(
215215
&self,
216216
_ty: Ty<'tcx>,
217-
_trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
217+
_trait_ref: Option<ExistentialTraitRef<'tcx>>,
218218
_vtable: Self::Value,
219219
) {
220220
// TODO(antoyo)

compiler/rustc_codegen_llvm/src/common.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,12 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
314314
GlobalAlloc::VTable(ty, dyn_ty) => {
315315
let alloc = self
316316
.tcx
317-
.global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal())))
317+
.global_alloc(self.tcx.vtable_allocation((
318+
ty,
319+
dyn_ty.principal().map(|principal| {
320+
self.tcx.instantiate_bound_regions_with_erased(principal)
321+
}),
322+
)))
318323
.unwrap_memory();
319324
let init = const_alloc_to_llvm(self, alloc, /*static*/ false);
320325
let value = self.static_addr_of_impl(init, alloc.inner().align, None);

compiler/rustc_codegen_llvm/src/context.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ pub(crate) struct CodegenCx<'ll, 'tcx> {
7777
/// Cache instances of monomorphic and polymorphic items
7878
pub instances: RefCell<FxHashMap<Instance<'tcx>, &'ll Value>>,
7979
/// Cache generated vtables
80-
pub vtables:
81-
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>,
80+
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>>,
8281
/// Cache of constant strings,
8382
pub const_str_cache: RefCell<FxHashMap<String, &'ll Value>>,
8483

@@ -663,15 +662,14 @@ impl<'ll> SimpleCx<'ll> {
663662
impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
664663
fn vtables(
665664
&self,
666-
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>
667-
{
665+
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>> {
668666
&self.vtables
669667
}
670668

671669
fn apply_vcall_visibility_metadata(
672670
&self,
673671
ty: Ty<'tcx>,
674-
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
672+
poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
675673
vtable: &'ll Value,
676674
) {
677675
apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable);

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1313
use rustc_middle::bug;
1414
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout};
1515
use rustc_middle::ty::{
16-
self, AdtKind, CoroutineArgsExt, Instance, PolyExistentialTraitRef, Ty, TyCtxt, Visibility,
16+
self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility,
1717
};
1818
use rustc_session::config::{self, DebugInfo, Lto};
1919
use rustc_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Symbol, hygiene};
@@ -1399,7 +1399,7 @@ pub(crate) fn build_global_var_di_node<'ll>(
13991399
fn build_vtable_type_di_node<'ll, 'tcx>(
14001400
cx: &CodegenCx<'ll, 'tcx>,
14011401
ty: Ty<'tcx>,
1402-
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
1402+
poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
14031403
) -> &'ll DIType {
14041404
let tcx = cx.tcx;
14051405

@@ -1510,7 +1510,7 @@ fn find_vtable_behind_cast<'ll>(vtable: &'ll Value) -> &'ll Value {
15101510
pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
15111511
cx: &CodegenCx<'ll, 'tcx>,
15121512
ty: Ty<'tcx>,
1513-
trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
1513+
trait_ref: Option<ExistentialTraitRef<'tcx>>,
15141514
vtable: &'ll Value,
15151515
) {
15161516
// FIXME(flip1995): The virtual function elimination optimization only works with full LTO in
@@ -1531,7 +1531,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
15311531
let vtable = find_vtable_behind_cast(vtable);
15321532
let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty);
15331533
let trait_ref_self = cx.tcx.erase_regions(trait_ref_self);
1534-
let trait_def_id = trait_ref_self.def_id();
1534+
let trait_def_id = trait_ref_self.def_id;
15351535
let trait_vis = cx.tcx.visibility(trait_def_id);
15361536

15371537
let cgus = cx.sess().codegen_units().as_usize();
@@ -1590,7 +1590,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
15901590
pub(crate) fn create_vtable_di_node<'ll, 'tcx>(
15911591
cx: &CodegenCx<'ll, 'tcx>,
15921592
ty: Ty<'tcx>,
1593-
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
1593+
poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
15941594
vtable: &'ll Value,
15951595
) {
15961596
if cx.dbg_cx.is_none() {

compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
66
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
77
use rustc_macros::HashStable;
88
use rustc_middle::bug;
9-
use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt};
9+
use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt};
1010

1111
use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
1212
use crate::common::{AsCCharPtr, CodegenCx};
@@ -44,7 +44,7 @@ pub(super) enum UniqueTypeId<'tcx> {
4444
/// The ID for the additional wrapper struct type describing an enum variant in CPP-like mode.
4545
VariantStructTypeCppLikeWrapper(Ty<'tcx>, VariantIdx, private::HiddenZst),
4646
/// The ID of the artificial type we create for VTables.
47-
VTableTy(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>, private::HiddenZst),
47+
VTableTy(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>, private::HiddenZst),
4848
}
4949

5050
impl<'tcx> UniqueTypeId<'tcx> {
@@ -88,7 +88,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
8888
pub(crate) fn for_vtable_ty(
8989
tcx: TyCtxt<'tcx>,
9090
self_type: Ty<'tcx>,
91-
implemented_trait: Option<PolyExistentialTraitRef<'tcx>>,
91+
implemented_trait: Option<ExistentialTraitRef<'tcx>>,
9292
) -> Self {
9393
assert_eq!(
9494
self_type,

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
588588
fn create_vtable_debuginfo(
589589
&self,
590590
ty: Ty<'tcx>,
591-
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
591+
trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
592592
vtable: Self::Value,
593593
) {
594594
metadata::create_vtable_di_node(self, ty, trait_ref, vtable)

compiler/rustc_codegen_ssa/src/base.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
2525
use rustc_session::Session;
2626
use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
2727
use rustc_span::{DUMMY_SP, Symbol, sym};
28-
use rustc_trait_selection::infer::at::ToTrace;
2928
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
3029
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
3130
use tracing::{debug, info};
@@ -129,14 +128,9 @@ pub fn validate_trivial_unsize<'tcx>(
129128
BoundRegionConversionTime::HigherRankedType,
130129
hr_source_principal,
131130
);
132-
let Ok(()) = ocx.eq_trace(
131+
let Ok(()) = ocx.eq(
133132
&ObligationCause::dummy(),
134133
param_env,
135-
ToTrace::to_trace(
136-
&ObligationCause::dummy(),
137-
hr_target_principal,
138-
hr_source_principal,
139-
),
140134
target_principal,
141135
source_principal,
142136
) else {
@@ -211,7 +205,12 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
211205
old_info
212206
}
213207
}
214-
(_, ty::Dynamic(data, _, _)) => meth::get_vtable(cx, source, data.principal()),
208+
(_, ty::Dynamic(data, _, _)) => meth::get_vtable(
209+
cx,
210+
source,
211+
data.principal()
212+
.map(|principal| bx.tcx().instantiate_bound_regions_with_erased(principal)),
213+
),
215214
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
216215
}
217216
}

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ pub enum VTableNameKind {
507507
pub fn compute_debuginfo_vtable_name<'tcx>(
508508
tcx: TyCtxt<'tcx>,
509509
t: Ty<'tcx>,
510-
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
510+
trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
511511
kind: VTableNameKind,
512512
) -> String {
513513
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
@@ -530,8 +530,8 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
530530
}
531531

532532
if let Some(trait_ref) = trait_ref {
533-
let trait_ref = tcx
534-
.normalize_erasing_late_bound_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
533+
let trait_ref =
534+
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
535535
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
536536
visited.clear();
537537
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);

compiler/rustc_codegen_ssa/src/meth.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_middle::bug;
2-
use rustc_middle::ty::{self, GenericArgKind, Ty};
2+
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt};
33
use rustc_session::config::Lto;
44
use rustc_symbol_mangling::typeid_for_trait_ref;
55
use rustc_target::callconv::FnAbi;
@@ -72,12 +72,19 @@ impl<'a, 'tcx> VirtualIndex {
7272

7373
/// This takes a valid `self` receiver type and extracts the principal trait
7474
/// ref of the type. Return `None` if there is no principal trait.
75-
fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> {
75+
fn dyn_trait_in_self<'tcx>(
76+
tcx: TyCtxt<'tcx>,
77+
ty: Ty<'tcx>,
78+
) -> Option<ty::ExistentialTraitRef<'tcx>> {
7679
for arg in ty.peel_refs().walk() {
7780
if let GenericArgKind::Type(ty) = arg.unpack()
7881
&& let ty::Dynamic(data, _, _) = ty.kind()
7982
{
80-
return data.principal();
83+
// FIXME(arbitrary_self_types): This is likely broken for receivers which
84+
// have a "non-self" trait objects as a generic argument.
85+
return data
86+
.principal()
87+
.map(|principal| tcx.instantiate_bound_regions_with_erased(principal));
8188
}
8289
}
8390

@@ -96,7 +103,7 @@ fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> {
96103
pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
97104
cx: &Cx,
98105
ty: Ty<'tcx>,
99-
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
106+
trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
100107
) -> Cx::Value {
101108
let tcx = cx.tcx();
102109

@@ -131,7 +138,7 @@ pub(crate) fn load_vtable<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
131138
if bx.cx().sess().opts.unstable_opts.virtual_function_elimination
132139
&& bx.cx().sess().lto() == Lto::Fat
133140
{
134-
if let Some(trait_ref) = dyn_trait_in_self(ty) {
141+
if let Some(trait_ref) = dyn_trait_in_self(bx.tcx(), ty) {
135142
let typeid = bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref)).unwrap();
136143
let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
137144
return func;

compiler/rustc_codegen_ssa/src/traits/debuginfo.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::ops::Range;
22

33
use rustc_abi::Size;
44
use rustc_middle::mir;
5-
use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty};
5+
use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty};
66
use rustc_span::{SourceFile, Span, Symbol};
77
use rustc_target::callconv::FnAbi;
88

@@ -13,7 +13,7 @@ pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes {
1313
fn create_vtable_debuginfo(
1414
&self,
1515
ty: Ty<'tcx>,
16-
trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
16+
trait_ref: Option<ExistentialTraitRef<'tcx>>,
1717
vtable: Self::Value,
1818
);
1919

compiler/rustc_codegen_ssa/src/traits/misc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ use super::BackendTypes;
1010
pub trait MiscCodegenMethods<'tcx>: BackendTypes {
1111
fn vtables(
1212
&self,
13-
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
13+
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), Self::Value>>;
1414
fn apply_vcall_visibility_metadata(
1515
&self,
1616
_ty: Ty<'tcx>,
17-
_poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
17+
_poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
1818
_vtable: Self::Value,
1919
) {
2020
}

0 commit comments

Comments
 (0)