1
Fork 0

Use ExistentialTraitRef throughout codegen

This commit is contained in:
Michael Goulet 2025-01-10 20:26:10 +00:00
parent 739ef83f31
commit 9dc41a048d
16 changed files with 71 additions and 63 deletions

View file

@ -6,7 +6,7 @@ use cranelift_module::*;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::interpret::{AllocId, GlobalAlloc, Scalar, read_target_uint}; use rustc_middle::mir::interpret::{AllocId, GlobalAlloc, Scalar, read_target_uint};
use rustc_middle::ty::{Binder, ExistentialTraitRef, ScalarInt}; use rustc_middle::ty::{ExistentialTraitRef, ScalarInt};
use crate::prelude::*; use crate::prelude::*;
@ -167,7 +167,9 @@ pub(crate) fn codegen_const_value<'tcx>(
&mut fx.constants_cx, &mut fx.constants_cx,
fx.module, fx.module,
ty, ty,
dyn_ty.principal(), dyn_ty.principal().map(|principal| {
fx.tcx.instantiate_bound_regions_with_erased(principal)
}),
); );
let local_data_id = let local_data_id =
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
@ -243,12 +245,9 @@ pub(crate) fn data_id_for_vtable<'tcx>(
cx: &mut ConstantCx, cx: &mut ConstantCx,
module: &mut dyn Module, module: &mut dyn Module,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>, trait_ref: Option<ExistentialTraitRef<'tcx>>,
) -> DataId { ) -> DataId {
let alloc_id = tcx.vtable_allocation(( let alloc_id = tcx.vtable_allocation((ty, trait_ref));
ty,
trait_ref.map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
));
data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not)
} }
@ -463,9 +462,15 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
GlobalAlloc::Memory(target_alloc) => { GlobalAlloc::Memory(target_alloc) => {
data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability) data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability)
} }
GlobalAlloc::VTable(ty, dyn_ty) => { GlobalAlloc::VTable(ty, dyn_ty) => data_id_for_vtable(
data_id_for_vtable(tcx, cx, module, ty, dyn_ty.principal()) tcx,
} cx,
module,
ty,
dyn_ty
.principal()
.map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
),
GlobalAlloc::Static(def_id) => { GlobalAlloc::Static(def_id) => {
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
{ {

View file

@ -61,7 +61,12 @@ pub(crate) fn unsized_info<'tcx>(
old_info old_info
} }
} }
(_, ty::Dynamic(data, ..)) => crate::vtable::get_vtable(fx, source, data.principal()), (_, ty::Dynamic(data, ..)) => crate::vtable::get_vtable(
fx,
source,
data.principal()
.map(|principal| fx.tcx.instantiate_bound_regions_with_erased(principal)),
),
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target), _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
} }
} }

View file

@ -90,7 +90,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
pub(crate) fn get_vtable<'tcx>( pub(crate) fn get_vtable<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
) -> Value { ) -> Value {
let data_id = data_id_for_vtable(fx.tcx, &mut fx.constants_cx, fx.module, ty, trait_ref); let data_id = data_id_for_vtable(fx.tcx, &mut fx.constants_cx, fx.module, ty, trait_ref);
let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func);

View file

@ -14,7 +14,7 @@ use rustc_middle::ty::layout::{
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError,
LayoutOfHelpers, LayoutOfHelpers,
}; };
use rustc_middle::ty::{self, Instance, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::source_map::respan; use rustc_span::source_map::respan;
use rustc_span::{DUMMY_SP, Span}; use rustc_span::{DUMMY_SP, Span};
@ -90,7 +90,7 @@ pub struct CodegenCx<'gcc, 'tcx> {
pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>, pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
/// Cache generated vtables /// Cache generated vtables
pub vtables: pub vtables:
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>>, RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
// TODO(antoyo): improve the SSA API to not require those. // TODO(antoyo): improve the SSA API to not require those.
/// Mapping from function pointer type to indexes of on stack parameters. /// Mapping from function pointer type to indexes of on stack parameters.
@ -401,7 +401,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn vtables( fn vtables(
&self, &self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>> { ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
&self.vtables &self.vtables
} }

View file

@ -7,7 +7,7 @@ use rustc_data_structures::sync::Lrc;
use rustc_index::bit_set::DenseBitSet; use rustc_index::bit_set::DenseBitSet;
use rustc_index::{Idx, IndexVec}; use rustc_index::{Idx, IndexVec};
use rustc_middle::mir::{self, Body, SourceScope}; use rustc_middle::mir::{self, Body, SourceScope};
use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty}; use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty};
use rustc_session::config::DebugInfo; use rustc_session::config::DebugInfo;
use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol}; use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol};
use rustc_target::abi::Size; use rustc_target::abi::Size;
@ -214,7 +214,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn create_vtable_debuginfo( fn create_vtable_debuginfo(
&self, &self,
_ty: Ty<'tcx>, _ty: Ty<'tcx>,
_trait_ref: Option<PolyExistentialTraitRef<'tcx>>, _trait_ref: Option<ExistentialTraitRef<'tcx>>,
_vtable: Self::Value, _vtable: Self::Value,
) { ) {
// TODO(antoyo) // TODO(antoyo)

View file

@ -77,8 +77,7 @@ pub(crate) struct CodegenCx<'ll, 'tcx> {
/// Cache instances of monomorphic and polymorphic items /// Cache instances of monomorphic and polymorphic items
pub instances: RefCell<FxHashMap<Instance<'tcx>, &'ll Value>>, pub instances: RefCell<FxHashMap<Instance<'tcx>, &'ll Value>>,
/// Cache generated vtables /// Cache generated vtables
pub vtables: pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>>,
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>,
/// Cache of constant strings, /// Cache of constant strings,
pub const_str_cache: RefCell<FxHashMap<String, &'ll Value>>, pub const_str_cache: RefCell<FxHashMap<String, &'ll Value>>,
@ -663,15 +662,14 @@ impl<'ll> SimpleCx<'ll> {
impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn vtables( fn vtables(
&self, &self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>> ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>> {
{
&self.vtables &self.vtables
} }
fn apply_vcall_visibility_metadata( fn apply_vcall_visibility_metadata(
&self, &self,
ty: Ty<'tcx>, ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
vtable: &'ll Value, vtable: &'ll Value,
) { ) {
apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable); apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable);

View file

@ -13,7 +13,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AdtKind, CoroutineArgsExt, Instance, PolyExistentialTraitRef, Ty, TyCtxt, Visibility, self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility,
}; };
use rustc_session::config::{self, DebugInfo, Lto}; use rustc_session::config::{self, DebugInfo, Lto};
use rustc_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Symbol, hygiene}; use rustc_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Symbol, hygiene};
@ -1400,13 +1400,13 @@ pub(crate) fn build_global_var_di_node<'ll>(
fn build_vtable_type_di_node<'ll, 'tcx>( fn build_vtable_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
) -> &'ll DIType { ) -> &'ll DIType {
let tcx = cx.tcx; let tcx = cx.tcx;
let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref { let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
let trait_ref = poly_trait_ref.with_self_ty(tcx, ty); let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
let trait_ref = tcx.erase_regions(tcx.instantiate_bound_regions_with_erased(trait_ref)); let trait_ref = tcx.erase_regions(trait_ref);
tcx.vtable_entries(trait_ref) tcx.vtable_entries(trait_ref)
} else { } else {
@ -1491,7 +1491,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_ref: Option<PolyExistentialTraitRef<'tcx>>, trait_ref: Option<ExistentialTraitRef<'tcx>>,
vtable: &'ll Value, vtable: &'ll Value,
) { ) {
// FIXME(flip1995): The virtual function elimination optimization only works with full LTO in // FIXME(flip1995): The virtual function elimination optimization only works with full LTO in
@ -1510,7 +1510,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty); let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty);
let trait_ref_self = cx.tcx.erase_regions(trait_ref_self); let trait_ref_self = cx.tcx.erase_regions(trait_ref_self);
let trait_def_id = trait_ref_self.def_id(); let trait_def_id = trait_ref_self.def_id;
let trait_vis = cx.tcx.visibility(trait_def_id); let trait_vis = cx.tcx.visibility(trait_def_id);
let cgus = cx.sess().codegen_units().as_usize(); let cgus = cx.sess().codegen_units().as_usize();
@ -1569,7 +1569,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
pub(crate) fn create_vtable_di_node<'ll, 'tcx>( pub(crate) fn create_vtable_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
vtable: &'ll Value, vtable: &'ll Value,
) { ) {
if cx.dbg_cx.is_none() { if cx.dbg_cx.is_none() {

View file

@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt};
use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
use crate::common::{AsCCharPtr, CodegenCx}; use crate::common::{AsCCharPtr, CodegenCx};
@ -44,7 +44,7 @@ pub(super) enum UniqueTypeId<'tcx> {
/// The ID for the additional wrapper struct type describing an enum variant in CPP-like mode. /// The ID for the additional wrapper struct type describing an enum variant in CPP-like mode.
VariantStructTypeCppLikeWrapper(Ty<'tcx>, VariantIdx, private::HiddenZst), VariantStructTypeCppLikeWrapper(Ty<'tcx>, VariantIdx, private::HiddenZst),
/// The ID of the artificial type we create for VTables. /// The ID of the artificial type we create for VTables.
VTableTy(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>, private::HiddenZst), VTableTy(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>, private::HiddenZst),
} }
impl<'tcx> UniqueTypeId<'tcx> { impl<'tcx> UniqueTypeId<'tcx> {
@ -88,7 +88,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
pub(crate) fn for_vtable_ty( pub(crate) fn for_vtable_ty(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
self_type: Ty<'tcx>, self_type: Ty<'tcx>,
implemented_trait: Option<PolyExistentialTraitRef<'tcx>>, implemented_trait: Option<ExistentialTraitRef<'tcx>>,
) -> Self { ) -> Self {
assert_eq!( assert_eq!(
self_type, self_type,

View file

@ -585,7 +585,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn create_vtable_debuginfo( fn create_vtable_debuginfo(
&self, &self,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
vtable: Self::Value, vtable: Self::Value,
) { ) {
metadata::create_vtable_di_node(self, ty, trait_ref, vtable) metadata::create_vtable_di_node(self, ty, trait_ref, vtable)

View file

@ -25,7 +25,6 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_session::Session; use rustc_session::Session;
use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType}; use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
use rustc_span::{DUMMY_SP, Symbol, sym}; use rustc_span::{DUMMY_SP, Symbol, sym};
use rustc_trait_selection::infer::at::ToTrace;
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
use tracing::{debug, info}; use tracing::{debug, info};
@ -129,14 +128,9 @@ pub fn validate_trivial_unsize<'tcx>(
BoundRegionConversionTime::HigherRankedType, BoundRegionConversionTime::HigherRankedType,
hr_source_principal, hr_source_principal,
); );
let Ok(()) = ocx.eq_trace( let Ok(()) = ocx.eq(
&ObligationCause::dummy(), &ObligationCause::dummy(),
param_env, param_env,
ToTrace::to_trace(
&ObligationCause::dummy(),
hr_target_principal,
hr_source_principal,
),
target_principal, target_principal,
source_principal, source_principal,
) else { ) else {
@ -211,7 +205,12 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
old_info old_info
} }
} }
(_, ty::Dynamic(data, _, _)) => meth::get_vtable(cx, source, data.principal()), (_, ty::Dynamic(data, _, _)) => meth::get_vtable(
cx,
source,
data.principal()
.map(|principal| bx.tcx().instantiate_bound_regions_with_erased(principal)),
),
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target), _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
} }
} }

View file

@ -507,7 +507,7 @@ pub enum VTableNameKind {
pub fn compute_debuginfo_vtable_name<'tcx>( pub fn compute_debuginfo_vtable_name<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
t: Ty<'tcx>, t: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
kind: VTableNameKind, kind: VTableNameKind,
) -> String { ) -> String {
let cpp_like_debuginfo = cpp_like_debuginfo(tcx); let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
@ -530,8 +530,8 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
} }
if let Some(trait_ref) = trait_ref { if let Some(trait_ref) = trait_ref {
let trait_ref = tcx let trait_ref =
.normalize_erasing_late_bound_regions(ty::TypingEnv::fully_monomorphized(), trait_ref); tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name); push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
visited.clear(); visited.clear();
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited); push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);

View file

@ -1,5 +1,5 @@
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt};
use rustc_session::config::Lto; use rustc_session::config::Lto;
use rustc_symbol_mangling::typeid_for_trait_ref; use rustc_symbol_mangling::typeid_for_trait_ref;
use rustc_target::callconv::FnAbi; use rustc_target::callconv::FnAbi;
@ -72,12 +72,17 @@ impl<'a, 'tcx> VirtualIndex {
/// This takes a valid `self` receiver type and extracts the principal trait /// This takes a valid `self` receiver type and extracts the principal trait
/// ref of the type. Return `None` if there is no principal trait. /// ref of the type. Return `None` if there is no principal trait.
fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> { fn dyn_trait_in_self<'tcx>(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
) -> Option<ty::ExistentialTraitRef<'tcx>> {
for arg in ty.peel_refs().walk() { for arg in ty.peel_refs().walk() {
if let GenericArgKind::Type(ty) = arg.unpack() if let GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Dynamic(data, _, _) = ty.kind() && let ty::Dynamic(data, _, _) = ty.kind()
{ {
return data.principal(); return data
.principal()
.map(|principal| tcx.instantiate_bound_regions_with_erased(principal));
} }
} }
@ -96,28 +101,24 @@ fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> {
pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &Cx, cx: &Cx,
ty: Ty<'tcx>, ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
) -> Cx::Value { ) -> Cx::Value {
let tcx = cx.tcx(); let tcx = cx.tcx();
// Check the cache. // Check the cache.
if let Some(&val) = cx.vtables().borrow().get(&(ty, poly_trait_ref)) { if let Some(&val) = cx.vtables().borrow().get(&(ty, trait_ref)) {
return val; return val;
} }
// FIXME(trait_upcasting): Take a non-higher-ranked vtable as arg.
let trait_ref =
poly_trait_ref.map(|trait_ref| tcx.instantiate_bound_regions_with_erased(trait_ref));
let vtable_alloc_id = tcx.vtable_allocation((ty, trait_ref)); let vtable_alloc_id = tcx.vtable_allocation((ty, trait_ref));
let vtable_allocation = tcx.global_alloc(vtable_alloc_id).unwrap_memory(); let vtable_allocation = tcx.global_alloc(vtable_alloc_id).unwrap_memory();
let vtable_const = cx.const_data_from_alloc(vtable_allocation); let vtable_const = cx.const_data_from_alloc(vtable_allocation);
let align = cx.data_layout().pointer_align.abi; let align = cx.data_layout().pointer_align.abi;
let vtable = cx.static_addr_of(vtable_const, align, Some("vtable")); let vtable = cx.static_addr_of(vtable_const, align, Some("vtable"));
cx.apply_vcall_visibility_metadata(ty, poly_trait_ref, vtable); cx.apply_vcall_visibility_metadata(ty, trait_ref, vtable);
cx.create_vtable_debuginfo(ty, poly_trait_ref, vtable); cx.create_vtable_debuginfo(ty, trait_ref, vtable);
cx.vtables().borrow_mut().insert((ty, poly_trait_ref), vtable); cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
vtable vtable
} }
@ -135,7 +136,7 @@ pub(crate) fn load_vtable<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
if bx.cx().sess().opts.unstable_opts.virtual_function_elimination if bx.cx().sess().opts.unstable_opts.virtual_function_elimination
&& bx.cx().sess().lto() == Lto::Fat && bx.cx().sess().lto() == Lto::Fat
{ {
if let Some(trait_ref) = dyn_trait_in_self(ty) { if let Some(trait_ref) = dyn_trait_in_self(bx.tcx(), ty) {
let typeid = bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref)).unwrap(); let typeid = bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref)).unwrap();
let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
return func; return func;

View file

@ -2,7 +2,7 @@ use std::ops::Range;
use rustc_abi::Size; use rustc_abi::Size;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty}; use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty};
use rustc_span::{SourceFile, Span, Symbol}; use rustc_span::{SourceFile, Span, Symbol};
use rustc_target::callconv::FnAbi; use rustc_target::callconv::FnAbi;
@ -13,7 +13,7 @@ pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes {
fn create_vtable_debuginfo( fn create_vtable_debuginfo(
&self, &self,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_ref: Option<PolyExistentialTraitRef<'tcx>>, trait_ref: Option<ExistentialTraitRef<'tcx>>,
vtable: Self::Value, vtable: Self::Value,
); );

View file

@ -10,11 +10,11 @@ use super::BackendTypes;
pub trait MiscCodegenMethods<'tcx>: BackendTypes { pub trait MiscCodegenMethods<'tcx>: BackendTypes {
fn vtables( fn vtables(
&self, &self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>; ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), Self::Value>>;
fn apply_vcall_visibility_metadata( fn apply_vcall_visibility_metadata(
&self, &self,
_ty: Ty<'tcx>, _ty: Ty<'tcx>,
_poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, _poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
_vtable: Self::Value, _vtable: Self::Value,
) { ) {
} }

View file

@ -151,7 +151,7 @@ fn symbol_name_provider<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty
pub fn typeid_for_trait_ref<'tcx>( pub fn typeid_for_trait_ref<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyExistentialTraitRef<'tcx>, trait_ref: ty::ExistentialTraitRef<'tcx>,
) -> String { ) -> String {
v0::mangle_typeid_for_trait_ref(tcx, trait_ref) v0::mangle_typeid_for_trait_ref(tcx, trait_ref)
} }

View file

@ -72,7 +72,7 @@ pub(super) fn mangle<'tcx>(
pub(super) fn mangle_typeid_for_trait_ref<'tcx>( pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyExistentialTraitRef<'tcx>, trait_ref: ty::ExistentialTraitRef<'tcx>,
) -> String { ) -> String {
// FIXME(flip1995): See comment in `mangle_typeid_for_fnabi`. // FIXME(flip1995): See comment in `mangle_typeid_for_fnabi`.
let mut cx = SymbolMangler { let mut cx = SymbolMangler {
@ -84,7 +84,7 @@ pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
binders: vec![], binders: vec![],
out: String::new(), out: String::new(),
}; };
cx.print_def_path(trait_ref.def_id(), &[]).unwrap(); cx.print_def_path(trait_ref.def_id, &[]).unwrap();
std::mem::take(&mut cx.out) std::mem::take(&mut cx.out)
} }