about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/ty/vtable.rs50
-rw-r--r--compiler/rustc_mir/src/monomorphize/collector.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs26
-rw-r--r--src/test/ui/traits/vtable/vtable-diamond.rs4
-rw-r--r--src/test/ui/traits/vtable/vtable-diamond.stderr67
-rw-r--r--src/test/ui/traits/vtable/vtable-multiple.rs4
-rw-r--r--src/test/ui/traits/vtable/vtable-multiple.stderr53
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