1
Fork 0

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!( rustc_attr!(
TEST, rustc_dump_vtable, Normal, template!(Word), TEST, rustc_dump_vtable, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes WarnFollowing, EncodeCrossCrate::No
), ),
rustc_attr!( rustc_attr!(
TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/), 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::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::intravisit; use rustc_hir::intravisit;
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::sym; use rustc_span::sym;
pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { 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() { if tcx.features().rustc_attrs() {
tcx.sess.time("outlives_dumping", || outlives::dump::inferred_outlives(tcx)); tcx.sess.time("dumping_rustc_attr_data", || {
tcx.sess.time("variance_dumping", || variance::dump::variances(tcx)); outlives::dump::inferred_outlives(tcx);
variance::dump::variances(tcx);
collect::dump::opaque_hidden_types(tcx); collect::dump::opaque_hidden_types(tcx);
collect::dump::predicates_and_item_bounds(tcx); collect::dump::predicates_and_item_bounds(tcx);
collect::dump::def_parents(tcx); collect::dump::def_parents(tcx);
collect::dump::vtables(tcx);
});
} }
// Make sure we evaluate all static and (non-associated) const items, even if unused. // 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_introduces_requirement = calling this method introduces the `impl`'s `'static` requirement
trait_selection_dtcs_suggestion = consider relaxing the implicit `'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]` trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
.label = empty on-clause here .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_hir::{self as hir, AmbigArg, FnRetTy, GenericParamKind, Node};
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath}; 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 rustc_span::{BytePos, Ident, Span, Symbol, kw};
use crate::error_reporting::infer::ObligationCauseAsDiagArg; use crate::error_reporting::infer::ObligationCauseAsDiagArg;
@ -22,15 +22,6 @@ use crate::fluent_generated as fluent;
pub mod note_and_explain; 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)] #[derive(Diagnostic)]
#[diag(trait_selection_unable_to_construct_constant_value)] #[diag(trait_selection_unable_to_construct_constant_value)]
pub struct UnableToConstructConstantValue<'a> { pub struct UnableToConstructConstantValue<'a> {

View file

@ -11,11 +11,10 @@ use rustc_middle::query::Providers;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, Upcast, VtblEntry, 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 smallvec::{SmallVec, smallvec};
use tracing::debug; use tracing::debug;
use crate::errors::DumpVTableEntries;
use crate::traits::{ObligationCtxt, impossible_predicates, is_vtable_safe_method}; use crate::traits::{ObligationCtxt, impossible_predicates, is_vtable_safe_method};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -192,15 +191,6 @@ fn maybe_iter<I: Iterator>(i: Option<I>) -> impl Iterator<Item = I::Item> {
i.into_iter().flatten() 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 { 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() 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); 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) 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_def_parents` | Dumps the chain of `DefId` parents of certain definitions. |
| `rustc_dump_item_bounds` | Dumps the [`item_bounds`] of an item. | | `rustc_dump_item_bounds` | Dumps the [`item_bounds`] of an item. |
| `rustc_dump_predicates` | Dumps the [`predicates_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_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_layout` | [See this section](#debugging-type-layouts). |
| `rustc_object_lifetime_default` | Dumps the [object lifetime defaults] of an item. | | `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 // This test makes sure that multiple marker (method-less) traits can reuse the
// same pointer for upcasting. // same pointer for upcasting.
//
//@ build-fail
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
@ -17,17 +16,13 @@ trait T {
fn method(&self) {} fn method(&self) {}
} }
#[rustc_dump_vtable] trait A: M0 + M1 + M2 + T {}
trait A: M0 + M1 + M2 + T {} //~ error: vtable entries for `<S as A>`:
#[rustc_dump_vtable] trait B: M0 + M1 + T + M2 {}
trait B: M0 + M1 + T + M2 {} //~ error: vtable entries for `<S as B>`:
#[rustc_dump_vtable] trait C: M0 + T + M1 + M2 {}
trait C: M0 + T + M1 + M2 {} //~ error: vtable entries for `<S as C>`:
#[rustc_dump_vtable] trait D: T + M0 + M1 + M2 {}
trait D: T + M0 + M1 + M2 {} //~ error: vtable entries for `<S as D>`:
struct S; struct S;
@ -35,13 +30,21 @@ impl M0 for S {}
impl M1 for S {} impl M1 for S {}
impl M2 for S {} impl M2 for S {}
impl T for S {} impl T for S {}
#[rustc_dump_vtable]
impl A for S {} impl A for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl B for S {} impl B for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl C for S {} impl C for S {}
//~^ ERROR vtable entries
#[rustc_dump_vtable]
impl D for S {} impl D for S {}
//~^ ERROR vtable entries
pub fn require_vtables() { fn main() {}
fn require_vtables(_: &dyn A, _: &dyn B, _: &dyn C, _: &dyn D) {}
require_vtables(&S, &S, &S, &S)
}

View file

@ -1,46 +1,46 @@
error: vtable entries for `<S as A>`: [ error: vtable entries: [
MetadataDropInPlace, MetadataDropInPlace,
MetadataSize, MetadataSize,
MetadataAlign, MetadataAlign,
Method(<S as T>::method), 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, MetadataDropInPlace,
MetadataSize, MetadataSize,
MetadataAlign, MetadataAlign,
Method(<S as T>::method), 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, MetadataDropInPlace,
MetadataSize, MetadataSize,
MetadataAlign, MetadataAlign,
Method(<S as T>::method), 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, MetadataDropInPlace,
MetadataSize, MetadataSize,
MetadataAlign, MetadataAlign,
Method(<S as T>::method), 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 error: aborting due to 4 previous errors

View file

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

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, MetadataDropInPlace,
MetadataSize, MetadataSize,
MetadataAlign, MetadataAlign,
@ -8,22 +43,10 @@ error: vtable entries for `<S as D>`: [
TraitVPtr(<S as C>), TraitVPtr(<S as C>),
Method(<S as D>::foo_d), 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>`: [ error: aborting due to 4 previous errors
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

View file

@ -1,15 +1,16 @@
//@ build-fail
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
// Ensure that dyn-incompatible methods in Iterator does not generate // Ensure that dyn-incompatible methods in Iterator does not generate
// vtable entries. // vtable entries.
#[rustc_dump_vtable]
trait A: Iterator {} trait A: Iterator {}
//~^ error vtable
impl<T> A for T where T: Iterator {} 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>) { 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, MetadataDropInPlace,
MetadataSize, MetadataSize,
MetadataAlign, MetadataAlign,
Method(<std::vec::IntoIter<u8> as Iterator>::next), Method(<dyn A<Item = u8> as Iterator>::next - shim(reify)),
Method(<std::vec::IntoIter<u8> as Iterator>::size_hint), Method(<dyn A<Item = u8> as Iterator>::size_hint - shim(reify)),
Method(<std::vec::IntoIter<u8> as Iterator>::advance_by), Method(<dyn A<Item = u8> as Iterator>::advance_by - shim(reify)),
Method(<std::vec::IntoIter<u8> as Iterator>::nth), 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 error: aborting due to 1 previous error

View file

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

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, MetadataDropInPlace,
MetadataSize, MetadataSize,
MetadataAlign, MetadataAlign,
@ -29,175 +215,10 @@ error: vtable entries for `<S as O>`: [
TraitVPtr(<S as N>), TraitVPtr(<S as N>),
Method(<S as O>::foo_o), 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>`: [ error: aborting due to 15 previous errors
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

View file

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

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, MetadataDropInPlace,
MetadataSize, MetadataSize,
MetadataAlign, MetadataAlign,
@ -7,21 +29,10 @@ error: vtable entries for `<S as C>`: [
TraitVPtr(<S as B>), TraitVPtr(<S as B>),
Method(<S as C>::foo_c), 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>`: [ error: aborting due to 3 previous errors
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

View file

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

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, MetadataDropInPlace,
MetadataSize, MetadataSize,
MetadataAlign, MetadataAlign,
@ -7,10 +19,10 @@ error: vtable entries for `<S as B>`: [
Method(<S as B>::foo_b1), Method(<S as B>::foo_b1),
Vacant, 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