diff options
| -rw-r--r-- | compiler/rustc_middle/src/ty/vtable.rs | 50 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/collector.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/mod.rs | 26 | ||||
| -rw-r--r-- | src/test/ui/traits/vtable/vtable-diamond.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/traits/vtable/vtable-diamond.stderr | 67 | ||||
| -rw-r--r-- | src/test/ui/traits/vtable/vtable-multiple.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/traits/vtable/vtable-multiple.stderr | 53 |
7 files changed, 98 insertions, 116 deletions
diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index c1775702013..cc3f6b3d6ec 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -1,18 +1,33 @@ use std::convert::TryFrom; +use std::fmt; use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar, ScalarMaybeUninit}; -use crate::ty::fold::TypeFoldable; -use crate::ty::{self, DefId, PolyExistentialTraitRef, SubstsRef, Ty, TyCtxt}; +use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt}; use rustc_ast::Mutability; -#[derive(Clone, Copy, Debug, PartialEq, HashStable)] +#[derive(Clone, Copy, PartialEq, HashStable)] pub enum VtblEntry<'tcx> { MetadataDropInPlace, MetadataSize, MetadataAlign, Vacant, - Method(DefId, SubstsRef<'tcx>), - TraitVPtr(PolyExistentialTraitRef<'tcx>), + Method(Instance<'tcx>), + TraitVPtr(PolyTraitRef<'tcx>), +} + +impl<'tcx> fmt::Debug for VtblEntry<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // We want to call `Display` on `Instance` and `PolyTraitRef`, + // so we implement this manually. + match self { + VtblEntry::MetadataDropInPlace => write!(f, "MetadataDropInPlace"), + VtblEntry::MetadataSize => write!(f, "MetadataSize"), + VtblEntry::MetadataAlign => write!(f, "MetadataAlign"), + VtblEntry::Vacant => write!(f, "Vacant"), + VtblEntry::Method(instance) => write!(f, "Method({})", instance), + VtblEntry::TraitVPtr(trait_ref) => write!(f, "TraitVPtr({})", trait_ref), + } + } } pub const COMMON_VTABLE_ENTRIES: &[VtblEntry<'_>] = @@ -37,11 +52,6 @@ impl<'tcx> TyCtxt<'tcx> { } drop(vtables_cache); - // See https://github.com/rust-lang/rust/pull/86475#discussion_r655162674 - assert!( - !ty.needs_subst() && !poly_trait_ref.map_or(false, |trait_ref| trait_ref.needs_subst()) - ); - let param_env = ty::ParamEnv::reveal_all(); 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(trait_ref); @@ -51,8 +61,9 @@ impl<'tcx> TyCtxt<'tcx> { COMMON_VTABLE_ENTRIES }; - let layout = - tcx.layout_of(param_env.and(ty)).expect("failed to build vtable representation"); + let layout = tcx + .layout_of(ty::ParamEnv::reveal_all().and(ty)) + .expect("failed to build vtable representation"); assert!(!layout.is_unsized(), "can't create a vtable for an unsized type"); let size = layout.size.bytes(); let align = layout.align.abi.bytes(); @@ -80,21 +91,18 @@ impl<'tcx> TyCtxt<'tcx> { VtblEntry::MetadataSize => Scalar::from_uint(size, ptr_size).into(), VtblEntry::MetadataAlign => Scalar::from_uint(align, ptr_size).into(), VtblEntry::Vacant => continue, - VtblEntry::Method(def_id, substs) => { - // See https://github.com/rust-lang/rust/pull/86475#discussion_r655162674 - assert!(!substs.needs_subst()); - + VtblEntry::Method(instance) => { // Prepare the fn ptr we write into the vtable. - let instance = - ty::Instance::resolve_for_vtable(tcx, param_env, *def_id, substs) - .expect("resolution failed during building vtable representation") - .polymorphize(tcx); + let instance = instance.polymorphize(tcx); let fn_alloc_id = tcx.create_fn_alloc(instance); let fn_ptr = Pointer::from(fn_alloc_id); ScalarMaybeUninit::from_pointer(fn_ptr, &tcx) } VtblEntry::TraitVPtr(trait_ref) => { - let supertrait_alloc_id = self.vtable_allocation(ty, Some(*trait_ref)); + let super_trait_ref = trait_ref.map_bound(|trait_ref| { + ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) + }); + let supertrait_alloc_id = self.vtable_allocation(ty, Some(super_trait_ref)); let vptr = Pointer::from(supertrait_alloc_id); ScalarMaybeUninit::from_pointer(vptr, &tcx) } diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 85c51bbff9d..95c4237f383 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -1120,13 +1120,9 @@ fn create_mono_items_for_vtable_methods<'tcx>( // all super trait items already covered, so skip them. None } - VtblEntry::Method(def_id, substs) => ty::Instance::resolve_for_vtable( - tcx, - ty::ParamEnv::reveal_all(), - *def_id, - substs, - ) - .filter(|instance| should_codegen_locally(tcx, instance)), + VtblEntry::Method(instance) => { + Some(*instance).filter(|instance| should_codegen_locally(tcx, instance)) + } }) .map(|item| create_fn_mono_item(tcx, item, source)); output.extend(methods); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 5c3b3926f4c..693384602a7 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -614,9 +614,14 @@ fn prepare_vtable_segments<'tcx, T>( } } -fn dump_vtable_entries<'tcx>(tcx: TyCtxt<'tcx>, entries: &[VtblEntry<'tcx>]) { - let msg = format!("Vtable Entries: {:#?}", entries); - tcx.sess.struct_span_err(rustc_span::DUMMY_SP, &msg).emit(); +fn dump_vtable_entries<'tcx>( + tcx: TyCtxt<'tcx>, + sp: Span, + trait_ref: ty::PolyTraitRef<'tcx>, + entries: &[VtblEntry<'tcx>], +) { + let msg = format!("Vtable entries for `{}`: {:#?}", trait_ref, entries); + tcx.sess.struct_span_err(sp, &msg).emit(); } /// Given a trait `trait_ref`, iterates the vtable entries @@ -678,15 +683,19 @@ fn vtable_entries<'tcx>( return VtblEntry::Vacant; } - VtblEntry::Method(def_id, substs) + let instance = ty::Instance::resolve_for_vtable( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + substs, + ) + .expect("resolution failed during building vtable representation"); + VtblEntry::Method(instance) }); entries.extend(own_entries); if emit_vptr { - let trait_ref = trait_ref.map_bound(|trait_ref| { - ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) - }); entries.push(VtblEntry::TraitVPtr(trait_ref)); } } @@ -698,7 +707,8 @@ fn vtable_entries<'tcx>( let _ = prepare_vtable_segments(tcx, trait_ref, vtable_segment_callback); if tcx.has_attr(trait_ref.def_id(), sym::rustc_dump_vtable) { - dump_vtable_entries(tcx, &entries); + let sp = tcx.def_span(trait_ref.def_id()); + dump_vtable_entries(tcx, sp, trait_ref, &entries); } tcx.arena.alloc_from_iter(entries.into_iter()) diff --git a/src/test/ui/traits/vtable/vtable-diamond.rs b/src/test/ui/traits/vtable/vtable-diamond.rs index ea26c60af72..f64ae95f1d4 100644 --- a/src/test/ui/traits/vtable/vtable-diamond.rs +++ b/src/test/ui/traits/vtable/vtable-diamond.rs @@ -1,6 +1,4 @@ // build-fail -//~^ error Vtable -//~^^ error Vtable #![feature(rustc_attrs)] #[rustc_dump_vtable] @@ -15,11 +13,13 @@ trait B: A { #[rustc_dump_vtable] trait C: A { + //~^ error Vtable fn foo_c(&self) {} } #[rustc_dump_vtable] trait D: B + C { + //~^ error Vtable fn foo_d(&self) {} } diff --git a/src/test/ui/traits/vtable/vtable-diamond.stderr b/src/test/ui/traits/vtable/vtable-diamond.stderr index 582c8184107..92a7f29536e 100644 --- a/src/test/ui/traits/vtable/vtable-diamond.stderr +++ b/src/test/ui/traits/vtable/vtable-diamond.stderr @@ -1,56 +1,35 @@ -error: Vtable Entries: [ +error: Vtable entries for `<S as D>`: [ MetadataDropInPlace, MetadataSize, MetadataAlign, - Method( - DefId(0:4 ~ vtable_diamond[4564]::A::foo_a), - [ - S, - ], - ), - Method( - DefId(0:6 ~ vtable_diamond[4564]::B::foo_b), - [ - S, - ], - ), - Method( - DefId(0:8 ~ vtable_diamond[4564]::C::foo_c), - [ - S, - ], - ), - TraitVPtr( - Binder( - C, - [], - ), - ), - Method( - DefId(0:10 ~ vtable_diamond[4564]::D::foo_d), - [ - S, - ], - ), + Method(<S as A>::foo_a), + Method(<S as B>::foo_b), + Method(<S as C>::foo_c), + TraitVPtr(<S as C>), + Method(<S as D>::foo_d), ] + --> $DIR/vtable-diamond.rs:21:1 + | +LL | / trait D: B + C { +LL | | +LL | | fn foo_d(&self) {} +LL | | } + | |_^ -error: Vtable Entries: [ +error: Vtable entries for `<S as C>`: [ MetadataDropInPlace, MetadataSize, MetadataAlign, - Method( - DefId(0:4 ~ vtable_diamond[4564]::A::foo_a), - [ - S, - ], - ), - Method( - DefId(0:8 ~ vtable_diamond[4564]::C::foo_c), - [ - S, - ], - ), + Method(<S as A>::foo_a), + Method(<S as C>::foo_c), ] + --> $DIR/vtable-diamond.rs:15:1 + | +LL | / trait C: A { +LL | | +LL | | fn foo_c(&self) {} +LL | | } + | |_^ error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/vtable/vtable-multiple.rs b/src/test/ui/traits/vtable/vtable-multiple.rs index d689ae96d41..cb0d0b72481 100644 --- a/src/test/ui/traits/vtable/vtable-multiple.rs +++ b/src/test/ui/traits/vtable/vtable-multiple.rs @@ -1,6 +1,4 @@ // build-fail -//~^ error Vtable -//~^^ error Vtable #![feature(rustc_attrs)] #[rustc_dump_vtable] @@ -10,11 +8,13 @@ trait A { #[rustc_dump_vtable] trait B { + //~^ error Vtable fn foo_b(&self) {} } #[rustc_dump_vtable] trait C: A + B { + //~^ error Vtable fn foo_c(&self) {} } diff --git a/src/test/ui/traits/vtable/vtable-multiple.stderr b/src/test/ui/traits/vtable/vtable-multiple.stderr index 222fe9cb0e4..f51b083de25 100644 --- a/src/test/ui/traits/vtable/vtable-multiple.stderr +++ b/src/test/ui/traits/vtable/vtable-multiple.stderr @@ -1,44 +1,33 @@ -error: Vtable Entries: [ +error: Vtable entries for `<S as C>`: [ MetadataDropInPlace, MetadataSize, MetadataAlign, - Method( - DefId(0:4 ~ vtable_multiple[5246]::A::foo_a), - [ - S, - ], - ), - Method( - DefId(0:6 ~ vtable_multiple[5246]::B::foo_b), - [ - S, - ], - ), - TraitVPtr( - Binder( - B, - [], - ), - ), - Method( - DefId(0:8 ~ vtable_multiple[5246]::C::foo_c), - [ - S, - ], - ), + Method(<S as A>::foo_a), + Method(<S as B>::foo_b), + TraitVPtr(<S as B>), + Method(<S as C>::foo_c), ] + --> $DIR/vtable-multiple.rs:16:1 + | +LL | / trait C: A + B { +LL | | +LL | | fn foo_c(&self) {} +LL | | } + | |_^ -error: Vtable Entries: [ +error: Vtable entries for `<S as B>`: [ MetadataDropInPlace, MetadataSize, MetadataAlign, - Method( - DefId(0:6 ~ vtable_multiple[5246]::B::foo_b), - [ - S, - ], - ), + Method(<S as B>::foo_b), ] + --> $DIR/vtable-multiple.rs:10:1 + | +LL | / trait B { +LL | | +LL | | fn foo_b(&self) {} +LL | | } + | |_^ error: aborting due to 2 previous errors |
