Use ExistentialTraitRef throughout codegen
This commit is contained in:
parent
739ef83f31
commit
9dc41a048d
16 changed files with 71 additions and 63 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue