diff --git a/compiler/rustc_codegen_llvm/src/gotoc/metadata.rs b/compiler/rustc_codegen_llvm/src/gotoc/metadata.rs index d48fa53e79ce..24f0d50ada8c 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/metadata.rs @@ -96,11 +96,12 @@ impl<'tcx> GotocCtx<'tcx> { /// functions can share the same name, we need to use the index of the entry in the /// vtable. This is the same index that will be passed in virtual function calls as /// InstanceDef::Virtual(def_id, idx). We could use solely the index as a key into - /// the vtable struct, but we add the trait and function names for debugging - /// readability. - /// Example: 3_Shape::vol - pub fn vtable_field_name(&self, def_id: DefId, idx: usize) -> String { - format!("{}_{}", idx, with_no_trimmed_paths(|| self.tcx.def_path_str(def_id))) + /// the vtable struct, but we add the method name for debugging readability. + /// Example: 3_vol + pub fn vtable_field_name(&self, _def_id: DefId, idx: usize) -> String { + // format!("{}_{}", idx, with_no_trimmed_paths(|| self.tcx.item_name(def_id))) + // TODO: use def_id https://github.com/model-checking/rmc/issues/364 + idx.to_string() } /// A human readable name in Rust for reference, should not be used as a key. diff --git a/compiler/rustc_codegen_llvm/src/gotoc/monomorphize/collector.rs b/compiler/rustc_codegen_llvm/src/gotoc/monomorphize/collector.rs index cab80e4e035e..d3589d923d56 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/monomorphize/collector.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/monomorphize/collector.rs @@ -225,7 +225,7 @@ fn collect_items_rec<'tcx>( recursion_depth_reset = None; if let Ok(alloc) = tcx.eval_static_initializer(def_id) { - for &((), id) in alloc.relocations().values() { + for &id in alloc.relocations().values() { collect_miri(tcx, id, &mut neighbors); } } @@ -815,16 +815,13 @@ fn create_mono_items_for_vtable_methods<'tcx>( .iter() .cloned() .filter_map(|entry| match entry { - VtblEntry::Method(def_id, substs) => ty::Instance::resolve_for_vtable( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - substs, - ), + VtblEntry::Method(instance) => Some(instance), VtblEntry::MetadataDropInPlace | VtblEntry::MetadataSize | VtblEntry::MetadataAlign | VtblEntry::Vacant => None, + // Super trait vtable entries already handled by now + VtblEntry::TraitVPtr(..) => None, }) .filter(|&instance| should_codegen_locally(tcx, &instance)) .map(|item| create_fn_mono_item(item, source)); @@ -1039,7 +1036,7 @@ fn collect_miri<'tcx>( } GlobalAlloc::Memory(alloc) => { trace!("collecting {:?} with {:#?}", alloc_id, alloc); - for &((), inner) in alloc.relocations().values() { + for &inner in alloc.relocations().values() { rustc_data_structures::stack::ensure_sufficient_stack(|| { collect_miri(tcx, inner, output); }); @@ -1073,9 +1070,12 @@ fn collect_const_value<'tcx>( output: &mut Vec>>, ) { match value { - ConstValue::Scalar(Scalar::Ptr(ptr)) => collect_miri(tcx, ptr.alloc_id, output), + ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => { + let (alloc_id, _offset) = ptr.into_parts(); + collect_miri(tcx, alloc_id, output); + } ConstValue::Slice { data: alloc, start: _, end: _ } | ConstValue::ByRef { alloc, .. } => { - for &((), id) in alloc.relocations().values() { + for &id in alloc.relocations().values() { collect_miri(tcx, id, output); } } diff --git a/compiler/rustc_codegen_llvm/src/gotoc/operand.rs b/compiler/rustc_codegen_llvm/src/gotoc/operand.rs index c79cae548b3d..ac850a1e326f 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/operand.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/operand.rs @@ -265,9 +265,10 @@ impl<'tcx> GotocCtx<'tcx> { &self.symbol_table, ) } - (Scalar::Ptr(ptr), _) => { + (Scalar::Ptr(ptr, _size), _) => { let res_t = self.codegen_ty(ty); - self.codegen_alloc_pointer(res_t, ptr.alloc_id, ptr.offset, span) + let (alloc_id, offset) = ptr.into_parts(); + self.codegen_alloc_pointer(res_t, alloc_id, offset, span) } _ => unimplemented!(), } @@ -382,7 +383,7 @@ impl<'tcx> GotocCtx<'tcx> { let pointer_size = self.ptr_width() as usize / 8; let mut next_offset = 0; - for &(offset, ((), alloc_id)) in alloc.relocations().iter() { + for &(offset, alloc_id) in alloc.relocations().iter() { let offset = offset.bytes_usize(); if offset > next_offset { let bytes = diff --git a/compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs b/compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs index 91793c127e99..d3dae46e4f82 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs @@ -10,12 +10,7 @@ use crate::btree_string_map; use num::bigint::BigInt; use rustc_middle::mir::{AggregateKind, BinOp, CastKind, NullOp, Operand, Place, Rvalue, UnOp}; use rustc_middle::ty::adjustment::PointerCast; -use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{ - self, Binder, GenericParamDefKind, Instance, IntTy, TraitRef, Ty, UintTy, VtblEntry, - COMMON_VTABLE_ENTRIES, -}; -use rustc_span::def_id::DefId; +use rustc_middle::ty::{self, Instance, IntTy, Ty, UintTy, VtblEntry, COMMON_VTABLE_ENTRIES}; use rustc_target::abi::{FieldsShape, LayoutOf, Primitive, TagEncoding, Variants}; use tracing::{debug, warn}; @@ -702,12 +697,11 @@ impl<'tcx> GotocCtx<'tcx> { fn codegen_vtable_method_field( &mut self, - def_id: DefId, - substs: ty::subst::SubstsRef<'tcx>, + instance: Instance<'tcx>, t: Ty<'tcx>, idx: usize, ) -> Expr { - let vtable_field_name = self.vtable_field_name(def_id, idx); + let vtable_field_name = self.vtable_field_name(instance.def_id(), idx); let vtable_type_name = aggr_name(&self.vtable_name(t)); let field_type = self .symbol_table @@ -715,13 +709,6 @@ impl<'tcx> GotocCtx<'tcx> { .cloned() .unwrap(); - // We use Instance::resolve to more closely match Rust proper behavior. The comment - // there says "used to find the precise code that will run for a trait method invocation" - // and it is used (in a more indirect way) to generate vtables. - let instance = Instance::resolve(self.tcx, ty::ParamEnv::reveal_all(), def_id, substs) - .unwrap() - .unwrap(); - // Lookup in the symbol table using the full symbol table name/key let fn_name = self.symbol_name(instance); if let Some(fn_symbol) = self.symbol_table.lookup(&fn_name) { @@ -858,8 +845,11 @@ impl<'tcx> GotocCtx<'tcx> { VtblEntry::MetadataSize => Some(vt_size.clone()), VtblEntry::MetadataAlign => Some(vt_align.clone()), VtblEntry::Vacant => None, - VtblEntry::Method(def_id, substs) => { - Some(ctx.codegen_vtable_method_field(*def_id, substs, trait_type, idx)) + // TODO: trait upcasting + // https://github.com/model-checking/rmc/issues/358 + VtblEntry::TraitVPtr(_trait_ref) => None, + VtblEntry::Method(instance) => { + Some(ctx.codegen_vtable_method_field(*instance, trait_type, idx)) } }) .collect(); diff --git a/compiler/rustc_codegen_llvm/src/gotoc/typ.rs b/compiler/rustc_codegen_llvm/src/gotoc/typ.rs index 203278eaef37..9d1b30e163a3 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/typ.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/typ.rs @@ -9,7 +9,7 @@ use rustc_index::vec::IndexVec; use rustc_middle::mir::{HasLocalDecls, Local}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::FmtPrinter; -use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; +use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{ self, AdtDef, FloatTy, Instance, IntTy, PolyFnSig, Ty, TyS, UintTy, VariantDef, VtblEntry, }; @@ -117,22 +117,17 @@ impl<'tcx> GotocCtx<'tcx> { /// In particular, these fields are function pointers. fn trait_method_vtable_field_type( &mut self, - def_id: DefId, - substs: SubstsRef<'tcx>, + instance: Instance<'tcx>, idx: usize, ) -> DatatypeComponent { - let instance = Instance::resolve(self.tcx, ty::ParamEnv::reveal_all(), def_id, substs) - .unwrap() - .unwrap(); - // gives a binder with function signature let sig = self.fn_sig_of_instance(instance); // gives an Irep Pointer object for the signature let fnptr = self.codegen_dynamic_function_sig(sig).to_pointer(); - // vtable field name, i.e., 3_Shape::vol (idx_Trait::method) - let vtable_field_name = self.vtable_field_name(def_id, idx); + // vtable field name, i.e., 3_vol (idx_method) + let vtable_field_name = self.vtable_field_name(instance.def_id(), idx); let ins_ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); let _layout = self.layout_of(ins_ty); @@ -198,9 +193,12 @@ impl<'tcx> GotocCtx<'tcx> { .cloned() .enumerate() .filter_map(|(idx, entry)| match entry { - VtblEntry::Method(def_id, substs) => { - Some(self.trait_method_vtable_field_type(def_id, substs, idx)) + VtblEntry::Method(instance) => { + Some(self.trait_method_vtable_field_type(instance, idx)) } + // TODO: trait upcasting + // https://github.com/model-checking/rmc/issues/358 + VtblEntry::TraitVPtr(..) => None, VtblEntry::MetadataDropInPlace | VtblEntry::MetadataSize | VtblEntry::MetadataAlign @@ -225,6 +223,11 @@ impl<'tcx> GotocCtx<'tcx> { /// Gives the vtable name for a type. /// In some cases, we have &T, in other cases T, so normalize. + /// + /// TODO: to handle trait upcasting, this will need to use a + /// poly existential trait type as a part of the key as well. + /// See compiler/rustc_middle/src/ty/vtable.rs + /// https://github.com/model-checking/rmc/issues/358 pub fn vtable_name(&self, t: Ty<'tcx>) -> String { self.normalized_trait_name(t) + "::vtable" }