Skip to content

Commit

Permalink
Use ExistentialTraitRef throughout codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jan 11, 2025
1 parent 1583ee2 commit 76eb4f3
Show file tree
Hide file tree
Showing 16 changed files with 71 additions and 63 deletions.
25 changes: 15 additions & 10 deletions compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use cranelift_module::*;
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
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::*;

Expand Down Expand Up @@ -167,7 +167,9 @@ pub(crate) fn codegen_const_value<'tcx>(
&mut fx.constants_cx,
fx.module,
ty,
dyn_ty.principal(),
dyn_ty.principal().map(|principal| {
fx.tcx.instantiate_bound_regions_with_erased(principal)
}),
);
let local_data_id =
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
Expand Down Expand Up @@ -243,12 +245,9 @@ pub(crate) fn data_id_for_vtable<'tcx>(
cx: &mut ConstantCx,
module: &mut dyn Module,
ty: Ty<'tcx>,
trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>,
trait_ref: Option<ExistentialTraitRef<'tcx>>,
) -> DataId {
let alloc_id = tcx.vtable_allocation((
ty,
trait_ref.map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
));
let alloc_id = tcx.vtable_allocation((ty, trait_ref));
data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not)
}

Expand Down Expand Up @@ -463,9 +462,15 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
GlobalAlloc::Memory(target_alloc) => {
data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability)
}
GlobalAlloc::VTable(ty, dyn_ty) => {
data_id_for_vtable(tcx, cx, module, ty, dyn_ty.principal())
}
GlobalAlloc::VTable(ty, dyn_ty) => data_id_for_vtable(
tcx,
cx,
module,
ty,
dyn_ty
.principal()
.map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
),
GlobalAlloc::Static(def_id) => {
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
{
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_codegen_cranelift/src/unsize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ pub(crate) fn unsized_info<'tcx>(
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),
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
pub(crate) fn get_vtable<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
ty: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
) -> Value {
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);
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_gcc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::ty::layout::{
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError,
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_span::source_map::respan;
use rustc_span::{DUMMY_SP, Span};
Expand Down Expand Up @@ -90,7 +90,7 @@ pub struct CodegenCx<'gcc, 'tcx> {
pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
/// Cache generated 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.
/// Mapping from function pointer type to indexes of on stack parameters.
Expand Down Expand Up @@ -400,7 +400,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn vtables(
&self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
&self.vtables
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_data_structures::sync::Lrc;
use rustc_index::bit_set::BitSet;
use rustc_index::{Idx, IndexVec};
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_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol};
use rustc_target::abi::Size;
Expand Down Expand Up @@ -214,7 +214,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn create_vtable_debuginfo(
&self,
_ty: Ty<'tcx>,
_trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
_trait_ref: Option<ExistentialTraitRef<'tcx>>,
_vtable: Self::Value,
) {
// TODO(antoyo)
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ pub(crate) struct CodegenCx<'ll, 'tcx> {
/// Cache instances of monomorphic and polymorphic items
pub instances: RefCell<FxHashMap<Instance<'tcx>, &'ll Value>>,
/// Cache generated vtables
pub vtables:
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>,
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>>,
/// Cache of constant strings,
pub const_str_cache: RefCell<FxHashMap<String, &'ll Value>>,

Expand Down Expand Up @@ -630,15 +629,14 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn vtables(
&self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>
{
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>> {
&self.vtables
}

fn apply_vcall_visibility_metadata(
&self,
ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
vtable: &'ll Value,
) {
apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable);
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug;
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout};
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_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Symbol, hygiene};
Expand Down Expand Up @@ -1400,13 +1400,13 @@ pub(crate) fn build_global_var_di_node<'ll>(
fn build_vtable_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
) -> &'ll DIType {
let tcx = cx.tcx;

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 = tcx.erase_regions(tcx.instantiate_bound_regions_with_erased(trait_ref));
let trait_ref = tcx.erase_regions(trait_ref);

tcx.vtable_entries(trait_ref)
} else {
Expand Down Expand Up @@ -1491,7 +1491,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>,
trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
trait_ref: Option<ExistentialTraitRef<'tcx>>,
vtable: &'ll Value,
) {
// FIXME(flip1995): The virtual function elimination optimization only works with full LTO in
Expand All @@ -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 = 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 cgus = cx.sess().codegen_units().as_usize();
Expand Down Expand Up @@ -1569,7 +1569,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
pub(crate) fn create_vtable_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
vtable: &'ll Value,
) {
if cx.dbg_cx.is_none() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable;
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 crate::common::{AsCCharPtr, CodegenCx};
Expand Down Expand Up @@ -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.
VariantStructTypeCppLikeWrapper(Ty<'tcx>, VariantIdx, private::HiddenZst),
/// 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> {
Expand Down Expand Up @@ -88,7 +88,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
pub(crate) fn for_vtable_ty(
tcx: TyCtxt<'tcx>,
self_type: Ty<'tcx>,
implemented_trait: Option<PolyExistentialTraitRef<'tcx>>,
implemented_trait: Option<ExistentialTraitRef<'tcx>>,
) -> Self {
assert_eq!(
self_type,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn create_vtable_debuginfo(
&self,
ty: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
vtable: Self::Value,
) {
metadata::create_vtable_di_node(self, ty, trait_ref, vtable)
Expand Down
15 changes: 7 additions & 8 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_session::Session;
use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
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::traits::{ObligationCause, ObligationCtxt};
use tracing::{debug, info};
Expand Down Expand Up @@ -128,14 +127,9 @@ pub fn validate_trivial_unsize<'tcx>(
BoundRegionConversionTime::HigherRankedType,
hr_source_principal,
);
let Ok(()) = ocx.eq_trace(
let Ok(()) = ocx.eq(
&ObligationCause::dummy(),
param_env,
ToTrace::to_trace(
&ObligationCause::dummy(),
hr_target_principal,
hr_source_principal,
),
target_principal,
source_principal,
) else {
Expand Down Expand Up @@ -210,7 +204,12 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
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),
}
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ pub enum VTableNameKind {
pub fn compute_debuginfo_vtable_name<'tcx>(
tcx: TyCtxt<'tcx>,
t: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
kind: VTableNameKind,
) -> String {
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
Expand All @@ -530,8 +530,8 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
}

if let Some(trait_ref) = trait_ref {
let trait_ref = tcx
.normalize_erasing_late_bound_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
let trait_ref =
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
visited.clear();
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
Expand Down
27 changes: 14 additions & 13 deletions compiler/rustc_codegen_ssa/src/meth.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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_symbol_mangling::typeid_for_trait_ref;
use rustc_target::callconv::FnAbi;
Expand Down Expand Up @@ -72,12 +72,17 @@ impl<'a, 'tcx> VirtualIndex {

/// This takes a valid `self` receiver type and extracts the 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() {
if let GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Dynamic(data, _, _) = ty.kind()
{
return data.principal();
return data
.principal()
.map(|principal| tcx.instantiate_bound_regions_with_erased(principal));
}
}

Expand All @@ -96,28 +101,24 @@ fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> {
pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &Cx,
ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
) -> Cx::Value {
let tcx = cx.tcx();

// 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;
}

// 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_allocation = tcx.global_alloc(vtable_alloc_id).unwrap_memory();
let vtable_const = cx.const_data_from_alloc(vtable_allocation);
let align = cx.data_layout().pointer_align.abi;
let vtable = cx.static_addr_of(vtable_const, align, Some("vtable"));

cx.apply_vcall_visibility_metadata(ty, poly_trait_ref, vtable);
cx.create_vtable_debuginfo(ty, poly_trait_ref, vtable);
cx.vtables().borrow_mut().insert((ty, poly_trait_ref), vtable);
cx.apply_vcall_visibility_metadata(ty, trait_ref, vtable);
cx.create_vtable_debuginfo(ty, trait_ref, vtable);
cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
vtable
}

Expand All @@ -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
&& 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 func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
return func;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::ops::Range;

use rustc_abi::Size;
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_target::callconv::FnAbi;

Expand All @@ -13,7 +13,7 @@ pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes {
fn create_vtable_debuginfo(
&self,
ty: Ty<'tcx>,
trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
trait_ref: Option<ExistentialTraitRef<'tcx>>,
vtable: Self::Value,
);

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/traits/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ use super::BackendTypes;
pub trait MiscCodegenMethods<'tcx>: BackendTypes {
fn vtables(
&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(
&self,
_ty: Ty<'tcx>,
_poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
_poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
_vtable: Self::Value,
) {
}
Expand Down
Loading

0 comments on commit 76eb4f3

Please sign in to comment.