Rework rustc_dump_vtable

This commit is contained in:
Michael Goulet 2025-01-10 20:09:10 +00:00
parent 5a45ab9738
commit 08d7e9dfe5
23 changed files with 603 additions and 381 deletions

View file

@ -1136,7 +1136,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
rustc_attr!(
TEST, rustc_dump_vtable, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes
WarnFollowing, EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/),

View file

@ -1,7 +1,8 @@
use rustc_hir as hir;
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::intravisit;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::sym;
pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
@ -87,3 +88,82 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) {
}
}
}
pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
for id in tcx.hir().items() {
let def_id = id.owner_id.def_id;
let Some(attr) = tcx.get_attr(def_id, sym::rustc_dump_vtable) else {
continue;
};
let vtable_entries = match tcx.hir().item(id).kind {
hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
let trait_ref = tcx.impl_trait_ref(def_id).unwrap().instantiate_identity();
if trait_ref.has_non_region_param() {
tcx.dcx().span_err(
attr.span,
"`rustc_dump_vtable` must be applied to non-generic impl",
);
continue;
}
if !tcx.is_dyn_compatible(trait_ref.def_id) {
tcx.dcx().span_err(
attr.span,
"`rustc_dump_vtable` must be applied to dyn-compatible trait",
);
continue;
}
let Ok(trait_ref) = tcx
.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref)
else {
tcx.dcx().span_err(
attr.span,
"`rustc_dump_vtable` applied to impl header that cannot be normalized",
);
continue;
};
tcx.vtable_entries(ty::Binder::dummy(trait_ref))
}
hir::ItemKind::TyAlias(_, _) => {
let ty = tcx.type_of(def_id).instantiate_identity();
if ty.has_non_region_param() {
tcx.dcx().span_err(
attr.span,
"`rustc_dump_vtable` must be applied to non-generic type",
);
continue;
}
let Ok(ty) =
tcx.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
else {
tcx.dcx().span_err(
attr.span,
"`rustc_dump_vtable` applied to type alias that cannot be normalized",
);
continue;
};
let ty::Dynamic(data, _, _) = *ty.kind() else {
tcx.dcx().span_err(attr.span, "`rustc_dump_vtable` to type alias of dyn type");
continue;
};
if let Some(principal) = data.principal() {
tcx.vtable_entries(
principal.map_bound(|principal| principal.with_self_ty(tcx, ty)),
)
} else {
TyCtxt::COMMON_VTABLE_ENTRIES
}
}
_ => {
tcx.dcx().span_err(
attr.span,
"`rustc_dump_vtable` only applies to impl, or type alias of dyn type",
);
continue;
}
};
tcx.dcx().span_err(tcx.def_span(def_id), format!("vtable entries: {vtable_entries:#?}"));
}
}

View file

@ -152,11 +152,14 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
});
if tcx.features().rustc_attrs() {
tcx.sess.time("outlives_dumping", || outlives::dump::inferred_outlives(tcx));
tcx.sess.time("variance_dumping", || variance::dump::variances(tcx));
collect::dump::opaque_hidden_types(tcx);
collect::dump::predicates_and_item_bounds(tcx);
collect::dump::def_parents(tcx);
tcx.sess.time("dumping_rustc_attr_data", || {
outlives::dump::inferred_outlives(tcx);
variance::dump::variances(tcx);
collect::dump::opaque_hidden_types(tcx);
collect::dump::predicates_and_item_bounds(tcx);
collect::dump::def_parents(tcx);
collect::dump::vtables(tcx);
});
}
// Make sure we evaluate all static and (non-associated) const items, even if unused.

View file

@ -148,8 +148,6 @@ trait_selection_dtcs_has_req_note = the used `impl` has a `'static` requirement
trait_selection_dtcs_introduces_requirement = calling this method introduces the `impl`'s `'static` requirement
trait_selection_dtcs_suggestion = consider relaxing the implicit `'static` requirement
trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
.label = empty on-clause here

View file

@ -12,7 +12,7 @@ use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty};
use rustc_hir::{self as hir, AmbigArg, FnRetTy, GenericParamKind, Node};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath};
use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, PolyTraitRef, Region, Ty, TyCtxt};
use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, Region, Ty, TyCtxt};
use rustc_span::{BytePos, Ident, Span, Symbol, kw};
use crate::error_reporting::infer::ObligationCauseAsDiagArg;
@ -22,15 +22,6 @@ use crate::fluent_generated as fluent;
pub mod note_and_explain;
#[derive(Diagnostic)]
#[diag(trait_selection_dump_vtable_entries)]
pub struct DumpVTableEntries<'a> {
#[primary_span]
pub span: Span,
pub trait_ref: PolyTraitRef<'a>,
pub entries: String,
}
#[derive(Diagnostic)]
#[diag(trait_selection_unable_to_construct_constant_value)]
pub struct UnableToConstructConstantValue<'a> {

View file

@ -11,11 +11,10 @@ use rustc_middle::query::Providers;
use rustc_middle::ty::{
self, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, Upcast, VtblEntry,
};
use rustc_span::{DUMMY_SP, Span, sym};
use rustc_span::DUMMY_SP;
use smallvec::{SmallVec, smallvec};
use tracing::debug;
use crate::errors::DumpVTableEntries;
use crate::traits::{ObligationCtxt, impossible_predicates, is_vtable_safe_method};
#[derive(Clone, Debug)]
@ -192,15 +191,6 @@ fn maybe_iter<I: Iterator>(i: Option<I>) -> impl Iterator<Item = I::Item> {
i.into_iter().flatten()
}
fn dump_vtable_entries<'tcx>(
tcx: TyCtxt<'tcx>,
sp: Span,
trait_ref: ty::PolyTraitRef<'tcx>,
entries: &[VtblEntry<'tcx>],
) {
tcx.dcx().emit_err(DumpVTableEntries { span: sp, trait_ref, entries: format!("{entries:#?}") });
}
fn has_own_existential_vtable_entries(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
own_existential_vtable_entries_iter(tcx, trait_def_id).next().is_some()
}
@ -317,11 +307,6 @@ 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) {
let sp = tcx.def_span(trait_ref.def_id());
dump_vtable_entries(tcx, sp, trait_ref, &entries);
}
tcx.arena.alloc_from_iter(entries)
}

View file

@ -275,7 +275,7 @@ Here are some notable ones:
| `rustc_dump_def_parents` | Dumps the chain of `DefId` parents of certain definitions. |
| `rustc_dump_item_bounds` | Dumps the [`item_bounds`] of an item. |
| `rustc_dump_predicates` | Dumps the [`predicates_of`] an item. |
| `rustc_dump_vtable` | |
| `rustc_dump_vtable` | Dumps the vtable layout of an impl, or a type alias of a dyn type. |
| `rustc_hidden_type_of_opaques` | Dumps the [hidden type of each opaque types][opaq] in the crate. |
| `rustc_layout` | [See this section](#debugging-type-layouts). |
| `rustc_object_lifetime_default` | Dumps the [object lifetime defaults] of an item. |

View file

@ -0,0 +1,25 @@
#![feature(rustc_attrs)]
trait Supertrait<T> {
fn _print_numbers(&self, mem: &[usize; 100]) {
}
}
impl<T> Supertrait<T> for () {}
trait Trait<T, U>: Supertrait<T> + Supertrait<U> {
fn say_hello(&self, _: &usize) {
}
}
impl<T, U> Trait<T, U> for () {}
// We should observe compatibility between these two vtables.
#[rustc_dump_vtable]
type First = dyn for<'a> Trait<&'static (), &'a ()>;
//~^ ERROR vtable entries
#[rustc_dump_vtable]
type Second = dyn Trait<&'static (), &'static ()>;
//~^ ERROR vtable entries
fn main() {}

View file

@ -0,0 +1,28 @@
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<dyn for<'a> Trait<&(), &'a ()> as Supertrait<&()>>::_print_numbers - shim(reify)),
Method(<dyn for<'a> Trait<&(), &'a ()> as Supertrait<&()>>::_print_numbers - shim(reify)),
TraitVPtr(for<'a> <dyn for<'a> Trait<&(), &'a ()> as Supertrait<&'a ()>>),
Method(<dyn for<'a> Trait<&(), &'a ()> as Trait<&(), &()>>::say_hello - shim(reify)),
]
--> $DIR/multiple-supertraits-modulo-binder-vtable.rs:18:1
|
LL | type First = dyn for<'a> Trait<&'static (), &'a ()>;
| ^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<dyn Trait<&(), &()> as Supertrait<&()>>::_print_numbers - shim(reify)),
Method(<dyn Trait<&(), &()> as Trait<&(), &()>>::say_hello - shim(reify)),
]
--> $DIR/multiple-supertraits-modulo-binder-vtable.rs:22:1
|
LL | type Second = dyn Trait<&'static (), &'static ()>;
| ^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -0,0 +1,36 @@
#![feature(rustc_attrs)]
#![feature(trait_upcasting)]
trait Supertrait<T> {
fn _print_numbers(&self, mem: &[usize; 100]) {
println!("{mem:?}");
}
}
impl<T> Supertrait<T> for () {}
trait Identity {
type Selff;
}
impl<Selff> Identity for Selff {
type Selff = Selff;
}
trait Middle<T>: Supertrait<()> + Supertrait<T> {
fn say_hello(&self, _: &usize) {
println!("Hello!");
}
}
impl<T> Middle<T> for () {}
trait Trait: Middle<<() as Identity>::Selff> {}
#[rustc_dump_vtable]
impl Trait for () {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
type Virtual = dyn Middle<()>;
//~^ ERROR vtable entries
fn main() {}

View file

@ -0,0 +1,28 @@
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<() as Supertrait<()>>::_print_numbers),
Method(<() as Supertrait<()>>::_print_numbers),
TraitVPtr(<() as Supertrait<<() as Identity>::Selff>>),
Method(<() as Middle<()>>::say_hello),
]
--> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:29:1
|
LL | impl Trait for () {}
| ^^^^^^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<dyn Middle<()> as Supertrait<()>>::_print_numbers - shim(reify)),
Method(<dyn Middle<()> as Middle<()>>::say_hello - shim(reify)),
]
--> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:33:1
|
LL | type Virtual = dyn Middle<()>;
| ^^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -2,8 +2,7 @@
//
// This test makes sure that multiple marker (method-less) traits can reuse the
// same pointer for upcasting.
//
//@ build-fail
#![crate_type = "lib"]
#![feature(rustc_attrs)]
@ -17,17 +16,13 @@ trait T {
fn method(&self) {}
}
#[rustc_dump_vtable]
trait A: M0 + M1 + M2 + T {} //~ error: vtable entries for `<S as A>`:
trait A: M0 + M1 + M2 + T {}
#[rustc_dump_vtable]
trait B: M0 + M1 + T + M2 {} //~ error: vtable entries for `<S as B>`:
trait B: M0 + M1 + T + M2 {}
#[rustc_dump_vtable]
trait C: M0 + T + M1 + M2 {} //~ error: vtable entries for `<S as C>`:
trait C: M0 + T + M1 + M2 {}
#[rustc_dump_vtable]
trait D: T + M0 + M1 + M2 {} //~ error: vtable entries for `<S as D>`:
trait D: T + M0 + M1 + M2 {}
struct S;
@ -35,13 +30,21 @@ impl M0 for S {}
impl M1 for S {}
impl M2 for S {}
impl T for S {}
#[rustc_dump_vtable]
impl A for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl B for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl C for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl D for S {}
//~^ ERROR vtable entries
pub fn require_vtables() {
fn require_vtables(_: &dyn A, _: &dyn B, _: &dyn C, _: &dyn D) {}
require_vtables(&S, &S, &S, &S)
}
fn main() {}

View file

@ -1,46 +1,46 @@
error: vtable entries for `<S as A>`: [
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as T>::method),
]
--> $DIR/multiple-markers.rs:21:1
--> $DIR/multiple-markers.rs:35:1
|
LL | trait A: M0 + M1 + M2 + T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl A for S {}
| ^^^^^^^^^^^^
error: vtable entries for `<S as B>`: [
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as T>::method),
]
--> $DIR/multiple-markers.rs:24:1
--> $DIR/multiple-markers.rs:39:1
|
LL | trait B: M0 + M1 + T + M2 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl B for S {}
| ^^^^^^^^^^^^
error: vtable entries for `<S as C>`: [
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as T>::method),
]
--> $DIR/multiple-markers.rs:27:1
--> $DIR/multiple-markers.rs:43:1
|
LL | trait C: M0 + T + M1 + M2 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl C for S {}
| ^^^^^^^^^^^^
error: vtable entries for `<S as D>`: [
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as T>::method),
]
--> $DIR/multiple-markers.rs:30:1
--> $DIR/multiple-markers.rs:47:1
|
LL | trait D: T + M0 + M1 + M2 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl D for S {}
| ^^^^^^^^^^^^
error: aborting due to 4 previous errors

View file

@ -1,44 +1,37 @@
//@ build-fail
#![feature(rustc_attrs)]
#[rustc_dump_vtable]
trait A {
fn foo_a(&self) {}
}
#[rustc_dump_vtable]
trait B: A {
fn foo_b(&self) {}
}
#[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) {}
}
struct S;
#[rustc_dump_vtable]
impl A for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl B for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl C for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl D for S {}
//~^ ERROR vtable entries
fn foo(d: &dyn D) {
d.foo_d();
}
fn bar(d: &dyn C) {
d.foo_c();
}
fn main() {
foo(&S);
bar(&S);
}
fn main() {}

View file

@ -1,4 +1,39 @@
error: vtable entries for `<S as D>`: [
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
]
--> $DIR/vtable-diamond.rs:22:1
|
LL | impl A for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
Method(<S as B>::foo_b),
]
--> $DIR/vtable-diamond.rs:26:1
|
LL | impl B for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
Method(<S as C>::foo_c),
]
--> $DIR/vtable-diamond.rs:30:1
|
LL | impl C for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
@ -8,22 +43,10 @@ error: vtable entries for `<S as D>`: [
TraitVPtr(<S as C>),
Method(<S as D>::foo_d),
]
--> $DIR/vtable-diamond.rs:21:1
--> $DIR/vtable-diamond.rs:34:1
|
LL | trait D: B + C {
| ^^^^^^^^^^^^^^
LL | impl D for S {}
| ^^^^^^^^^^^^
error: vtable entries for `<S as C>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
Method(<S as C>::foo_c),
]
--> $DIR/vtable-diamond.rs:15:1
|
LL | trait C: A {
| ^^^^^^^^^^
error: aborting due to 2 previous errors
error: aborting due to 4 previous errors

View file

@ -1,15 +1,16 @@
//@ build-fail
#![feature(rustc_attrs)]
// Ensure that dyn-incompatible methods in Iterator does not generate
// vtable entries.
#[rustc_dump_vtable]
trait A: Iterator {}
//~^ error vtable
impl<T> A for T where T: Iterator {}
#[rustc_dump_vtable]
type Test = dyn A<Item=u8>;
//~^ error vtable
fn foo(_a: &mut dyn A<Item=u8>) {
}

View file

@ -1,16 +1,16 @@
error: vtable entries for `<std::vec::IntoIter<u8> as A>`: [
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<std::vec::IntoIter<u8> as Iterator>::next),
Method(<std::vec::IntoIter<u8> as Iterator>::size_hint),
Method(<std::vec::IntoIter<u8> as Iterator>::advance_by),
Method(<std::vec::IntoIter<u8> as Iterator>::nth),
Method(<dyn A<Item = u8> as Iterator>::next - shim(reify)),
Method(<dyn A<Item = u8> as Iterator>::size_hint - shim(reify)),
Method(<dyn A<Item = u8> as Iterator>::advance_by - shim(reify)),
Method(<dyn A<Item = u8> as Iterator>::nth - shim(reify)),
]
--> $DIR/vtable-dyn-incompatible.rs:8:1
--> $DIR/vtable-dyn-incompatible.rs:11:1
|
LL | trait A: Iterator {}
| ^^^^^^^^^^^^^^^^^
LL | type Test = dyn A<Item=u8>;
| ^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -1,4 +1,3 @@
//@ build-fail
#![feature(rustc_attrs)]
// O --> G --> C --> A
@ -10,134 +9,126 @@
// |-> M --> K
// \-> L
#[rustc_dump_vtable]
trait A {
//~^ error vtable
fn foo_a(&self) {}
}
#[rustc_dump_vtable]
trait B {
//~^ error vtable
fn foo_b(&self) {}
}
#[rustc_dump_vtable]
trait C: A + B {
//~^ error vtable
fn foo_c(&self) {}
}
#[rustc_dump_vtable]
trait D {
//~^ error vtable
fn foo_d(&self) {}
}
#[rustc_dump_vtable]
trait E {
//~^ error vtable
fn foo_e(&self) {}
}
#[rustc_dump_vtable]
trait F: D + E {
//~^ error vtable
fn foo_f(&self) {}
}
#[rustc_dump_vtable]
trait G: C + F {
fn foo_g(&self) {}
}
#[rustc_dump_vtable]
trait H {
//~^ error vtable
fn foo_h(&self) {}
}
#[rustc_dump_vtable]
trait I {
//~^ error vtable
fn foo_i(&self) {}
}
#[rustc_dump_vtable]
trait J: H + I {
//~^ error vtable
fn foo_j(&self) {}
}
#[rustc_dump_vtable]
trait K {
//~^ error vtable
fn foo_k(&self) {}
}
#[rustc_dump_vtable]
trait L {
//~^ error vtable
fn foo_l(&self) {}
}
#[rustc_dump_vtable]
trait M: K + L {
//~^ error vtable
fn foo_m(&self) {}
}
#[rustc_dump_vtable]
trait N: J + M {
//~^ error vtable
fn foo_n(&self) {}
}
#[rustc_dump_vtable]
trait O: G + N {
//~^ error vtable
fn foo_o(&self) {}
}
struct S;
#[rustc_dump_vtable]
impl A for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl B for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl C for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl D for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl E for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl F for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl G for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl H for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl I for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl J for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl K for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl L for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl M for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl N for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl O for S {}
//~^ ERROR vtable entries
macro_rules! monomorphize_vtable {
($trait:ident) => {{
fn foo(_ : &dyn $trait) {}
foo(&S);
}}
}
fn main() {
monomorphize_vtable!(O);
monomorphize_vtable!(A);
monomorphize_vtable!(B);
monomorphize_vtable!(C);
monomorphize_vtable!(D);
monomorphize_vtable!(E);
monomorphize_vtable!(F);
monomorphize_vtable!(H);
monomorphize_vtable!(I);
monomorphize_vtable!(J);
monomorphize_vtable!(K);
monomorphize_vtable!(L);
monomorphize_vtable!(M);
monomorphize_vtable!(N);
}
fn main() {}

View file

@ -1,4 +1,190 @@
error: vtable entries for `<S as O>`: [
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
]
--> $DIR/vtable-multi-level.rs:75:1
|
LL | impl A for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as B>::foo_b),
]
--> $DIR/vtable-multi-level.rs:79:1
|
LL | impl B for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
Method(<S as B>::foo_b),
TraitVPtr(<S as B>),
Method(<S as C>::foo_c),
]
--> $DIR/vtable-multi-level.rs:83:1
|
LL | impl C for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as D>::foo_d),
]
--> $DIR/vtable-multi-level.rs:87:1
|
LL | impl D for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as E>::foo_e),
]
--> $DIR/vtable-multi-level.rs:91:1
|
LL | impl E for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as D>::foo_d),
Method(<S as E>::foo_e),
TraitVPtr(<S as E>),
Method(<S as F>::foo_f),
]
--> $DIR/vtable-multi-level.rs:95:1
|
LL | impl F for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
Method(<S as B>::foo_b),
TraitVPtr(<S as B>),
Method(<S as C>::foo_c),
Method(<S as D>::foo_d),
TraitVPtr(<S as D>),
Method(<S as E>::foo_e),
TraitVPtr(<S as E>),
Method(<S as F>::foo_f),
TraitVPtr(<S as F>),
Method(<S as G>::foo_g),
]
--> $DIR/vtable-multi-level.rs:99:1
|
LL | impl G for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as H>::foo_h),
]
--> $DIR/vtable-multi-level.rs:103:1
|
LL | impl H for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as I>::foo_i),
]
--> $DIR/vtable-multi-level.rs:107:1
|
LL | impl I for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as H>::foo_h),
Method(<S as I>::foo_i),
TraitVPtr(<S as I>),
Method(<S as J>::foo_j),
]
--> $DIR/vtable-multi-level.rs:111:1
|
LL | impl J for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as K>::foo_k),
]
--> $DIR/vtable-multi-level.rs:115:1
|
LL | impl K for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as L>::foo_l),
]
--> $DIR/vtable-multi-level.rs:119:1
|
LL | impl L for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as K>::foo_k),
Method(<S as L>::foo_l),
TraitVPtr(<S as L>),
Method(<S as M>::foo_m),
]
--> $DIR/vtable-multi-level.rs:123:1
|
LL | impl M for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as H>::foo_h),
Method(<S as I>::foo_i),
TraitVPtr(<S as I>),
Method(<S as J>::foo_j),
Method(<S as K>::foo_k),
TraitVPtr(<S as K>),
Method(<S as L>::foo_l),
TraitVPtr(<S as L>),
Method(<S as M>::foo_m),
TraitVPtr(<S as M>),
Method(<S as N>::foo_n),
]
--> $DIR/vtable-multi-level.rs:127:1
|
LL | impl N for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
@ -29,175 +215,10 @@ error: vtable entries for `<S as O>`: [
TraitVPtr(<S as N>),
Method(<S as O>::foo_o),
]
--> $DIR/vtable-multi-level.rs:97:1
--> $DIR/vtable-multi-level.rs:131:1
|
LL | trait O: G + N {
| ^^^^^^^^^^^^^^
LL | impl O for S {}
| ^^^^^^^^^^^^
error: vtable entries for `<S as A>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
]
--> $DIR/vtable-multi-level.rs:14:1
|
LL | trait A {
| ^^^^^^^
error: vtable entries for `<S as B>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as B>::foo_b),
]
--> $DIR/vtable-multi-level.rs:20:1
|
LL | trait B {
| ^^^^^^^
error: vtable entries for `<S as C>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
Method(<S as B>::foo_b),
TraitVPtr(<S as B>),
Method(<S as C>::foo_c),
]
--> $DIR/vtable-multi-level.rs:26:1
|
LL | trait C: A + B {
| ^^^^^^^^^^^^^^
error: vtable entries for `<S as D>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as D>::foo_d),
]
--> $DIR/vtable-multi-level.rs:32:1
|
LL | trait D {
| ^^^^^^^
error: vtable entries for `<S as E>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as E>::foo_e),
]
--> $DIR/vtable-multi-level.rs:38:1
|
LL | trait E {
| ^^^^^^^
error: vtable entries for `<S as F>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as D>::foo_d),
Method(<S as E>::foo_e),
TraitVPtr(<S as E>),
Method(<S as F>::foo_f),
]
--> $DIR/vtable-multi-level.rs:44:1
|
LL | trait F: D + E {
| ^^^^^^^^^^^^^^
error: vtable entries for `<S as H>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as H>::foo_h),
]
--> $DIR/vtable-multi-level.rs:55:1
|
LL | trait H {
| ^^^^^^^
error: vtable entries for `<S as I>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as I>::foo_i),
]
--> $DIR/vtable-multi-level.rs:61:1
|
LL | trait I {
| ^^^^^^^
error: vtable entries for `<S as J>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as H>::foo_h),
Method(<S as I>::foo_i),
TraitVPtr(<S as I>),
Method(<S as J>::foo_j),
]
--> $DIR/vtable-multi-level.rs:67:1
|
LL | trait J: H + I {
| ^^^^^^^^^^^^^^
error: vtable entries for `<S as K>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as K>::foo_k),
]
--> $DIR/vtable-multi-level.rs:73:1
|
LL | trait K {
| ^^^^^^^
error: vtable entries for `<S as L>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as L>::foo_l),
]
--> $DIR/vtable-multi-level.rs:79:1
|
LL | trait L {
| ^^^^^^^
error: vtable entries for `<S as M>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as K>::foo_k),
Method(<S as L>::foo_l),
TraitVPtr(<S as L>),
Method(<S as M>::foo_m),
]
--> $DIR/vtable-multi-level.rs:85:1
|
LL | trait M: K + L {
| ^^^^^^^^^^^^^^
error: vtable entries for `<S as N>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as H>::foo_h),
Method(<S as I>::foo_i),
TraitVPtr(<S as I>),
Method(<S as J>::foo_j),
Method(<S as K>::foo_k),
TraitVPtr(<S as K>),
Method(<S as L>::foo_l),
TraitVPtr(<S as L>),
Method(<S as M>::foo_m),
TraitVPtr(<S as M>),
Method(<S as N>::foo_n),
]
--> $DIR/vtable-multi-level.rs:91:1
|
LL | trait N: J + M {
| ^^^^^^^^^^^^^^
error: aborting due to 14 previous errors
error: aborting due to 15 previous errors

View file

@ -1,33 +1,29 @@
//@ build-fail
#![feature(rustc_attrs)]
#[rustc_dump_vtable]
trait A {
fn foo_a(&self) {}
}
#[rustc_dump_vtable]
trait B {
//~^ error vtable
fn foo_b(&self) {}
}
#[rustc_dump_vtable]
trait C: A + B {
//~^ error vtable
fn foo_c(&self) {}
}
struct S;
#[rustc_dump_vtable]
impl A for S {}
//~^ error vtable
#[rustc_dump_vtable]
impl B for S {}
//~^ error vtable
#[rustc_dump_vtable]
impl C for S {}
//~^ error vtable
fn foo(c: &dyn C) {}
fn bar(c: &dyn B) {}
fn main() {
foo(&S);
bar(&S);
}
fn main() {}

View file

@ -1,4 +1,26 @@
error: vtable entries for `<S as C>`: [
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a),
]
--> $DIR/vtable-multiple.rs:18:1
|
LL | impl A for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as B>::foo_b),
]
--> $DIR/vtable-multiple.rs:22:1
|
LL | impl B for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
@ -7,21 +29,10 @@ error: vtable entries for `<S as C>`: [
TraitVPtr(<S as B>),
Method(<S as C>::foo_c),
]
--> $DIR/vtable-multiple.rs:16:1
--> $DIR/vtable-multiple.rs:26:1
|
LL | trait C: A + B {
| ^^^^^^^^^^^^^^
LL | impl C for S {}
| ^^^^^^^^^^^^
error: vtable entries for `<S as B>`: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as B>::foo_b),
]
--> $DIR/vtable-multiple.rs:10:1
|
LL | trait B {
| ^^^^^^^
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors

View file

@ -1,18 +1,14 @@
//@ build-fail
#![feature(rustc_attrs)]
#![feature(negative_impls)]
// B --> A
#[rustc_dump_vtable]
trait A {
fn foo_a1(&self) {}
fn foo_a2(&self) where Self: Send {}
}
#[rustc_dump_vtable]
trait B: A {
//~^ error vtable
fn foo_b1(&self) {}
fn foo_b2(&self) where Self: Send {}
}
@ -20,11 +16,12 @@ trait B: A {
struct S;
impl !Send for S {}
#[rustc_dump_vtable]
impl A for S {}
//~^ error vtable
#[rustc_dump_vtable]
impl B for S {}
//~^ error vtable
fn foo(_: &dyn B) {}
fn main() {
foo(&S);
}
fn main() {}

View file

@ -1,4 +1,16 @@
error: vtable entries for `<S as B>`: [
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
Method(<S as A>::foo_a1),
Vacant,
]
--> $DIR/vtable-vacant.rs:20:1
|
LL | impl A for S {}
| ^^^^^^^^^^^^
error: vtable entries: [
MetadataDropInPlace,
MetadataSize,
MetadataAlign,
@ -7,10 +19,10 @@ error: vtable entries for `<S as B>`: [
Method(<S as B>::foo_b1),
Vacant,
]
--> $DIR/vtable-vacant.rs:14:1
--> $DIR/vtable-vacant.rs:24:1
|
LL | trait B: A {
| ^^^^^^^^^^
LL | impl B for S {}
| ^^^^^^^^^^^^
error: aborting due to 1 previous error
error: aborting due to 2 previous errors