From fbb353ae2b5cef75c7d97be4f3c2283a63e0fd7f Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Thu, 22 Jul 2021 23:29:53 +0800 Subject: [PATCH] Add comment and more tests. --- compiler/rustc_middle/src/ty/vtable.rs | 6 + .../ui/traits/vtable/vtable-multi-level.rs | 122 ++++++++++ .../traits/vtable/vtable-multi-level.stderr | 214 ++++++++++++++++++ src/test/ui/traits/vtable/vtable-vacant.rs | 28 +++ .../ui/traits/vtable/vtable-vacant.stderr | 20 ++ 5 files changed, 390 insertions(+) create mode 100644 src/test/ui/traits/vtable/vtable-multi-level.rs create mode 100644 src/test/ui/traits/vtable/vtable-multi-level.stderr create mode 100644 src/test/ui/traits/vtable/vtable-vacant.rs create mode 100644 src/test/ui/traits/vtable/vtable-vacant.stderr diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index cc3f6b3d6ec..5904f133e78 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -7,11 +7,17 @@ use rustc_ast::Mutability; #[derive(Clone, Copy, PartialEq, HashStable)] pub enum VtblEntry<'tcx> { + /// destructor of this type (used in vtable header) MetadataDropInPlace, + /// layout size of this type (used in vtable header) MetadataSize, + /// layout align of this type (used in vtable header) MetadataAlign, + /// non-dispatchable associated function that is excluded from trait object Vacant, + /// dispatchable associated function Method(Instance<'tcx>), + /// pointer to a separate supertrait vtable, can be used by trait upcasting coercion TraitVPtr(PolyTraitRef<'tcx>), } diff --git a/src/test/ui/traits/vtable/vtable-multi-level.rs b/src/test/ui/traits/vtable/vtable-multi-level.rs new file mode 100644 index 00000000000..33112b4eaaa --- /dev/null +++ b/src/test/ui/traits/vtable/vtable-multi-level.rs @@ -0,0 +1,122 @@ +// build-fail +#![feature(rustc_attrs)] + +// O --> G --> C --> A +// \ \ \-> B +// | |-> F --> D +// | \-> E +// |-> N --> J --> H +// \ \-> I +// |-> M --> K +// \-> L + +#[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 { + 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; + +impl A for S {} +impl B for S {} +impl C for S {} +impl D for S {} +impl E for S {} +impl F for S {} +impl G for S {} +impl H for S {} +impl I for S {} +impl J for S {} +impl K for S {} +impl L for S {} +impl M for S {} +impl N for S {} +impl O for S {} + +fn foo(_: &dyn O) {} + +fn main() { + foo(&S); +} diff --git a/src/test/ui/traits/vtable/vtable-multi-level.stderr b/src/test/ui/traits/vtable/vtable-multi-level.stderr new file mode 100644 index 00000000000..7700db98e0b --- /dev/null +++ b/src/test/ui/traits/vtable/vtable-multi-level.stderr @@ -0,0 +1,214 @@ +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_a), + Method(::foo_b), + TraitVPtr(), + Method(::foo_c), + Method(::foo_d), + TraitVPtr(), + Method(::foo_e), + TraitVPtr(), + Method(::foo_f), + TraitVPtr(), + Method(::foo_g), + Method(::foo_h), + TraitVPtr(), + Method(::foo_i), + TraitVPtr(), + Method(::foo_j), + TraitVPtr(), + Method(::foo_k), + TraitVPtr(), + Method(::foo_l), + TraitVPtr(), + Method(::foo_m), + TraitVPtr(), + Method(::foo_n), + TraitVPtr(), + Method(::foo_o), +] + --> $DIR/vtable-multi-level.rs:95:1 + | +LL | / trait O: G + N { +LL | | +LL | | fn foo_o(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_b), +] + --> $DIR/vtable-multi-level.rs:19:1 + | +LL | / trait B { +LL | | +LL | | fn foo_b(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_d), +] + --> $DIR/vtable-multi-level.rs:30:1 + | +LL | / trait D { +LL | | +LL | | fn foo_d(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_e), +] + --> $DIR/vtable-multi-level.rs:36:1 + | +LL | / trait E { +LL | | +LL | | fn foo_e(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_d), + Method(::foo_e), + TraitVPtr(), + Method(::foo_f), +] + --> $DIR/vtable-multi-level.rs:42:1 + | +LL | / trait F: D + E { +LL | | +LL | | fn foo_f(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_h), +] + --> $DIR/vtable-multi-level.rs:53:1 + | +LL | / trait H { +LL | | +LL | | fn foo_h(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_i), +] + --> $DIR/vtable-multi-level.rs:59:1 + | +LL | / trait I { +LL | | +LL | | fn foo_i(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_h), + Method(::foo_i), + TraitVPtr(), + Method(::foo_j), +] + --> $DIR/vtable-multi-level.rs:65:1 + | +LL | / trait J: H + I { +LL | | +LL | | fn foo_j(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_k), +] + --> $DIR/vtable-multi-level.rs:71:1 + | +LL | / trait K { +LL | | +LL | | fn foo_k(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_l), +] + --> $DIR/vtable-multi-level.rs:77:1 + | +LL | / trait L { +LL | | +LL | | fn foo_l(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_k), + Method(::foo_l), + TraitVPtr(), + Method(::foo_m), +] + --> $DIR/vtable-multi-level.rs:83:1 + | +LL | / trait M: K + L { +LL | | +LL | | fn foo_m(&self) {} +LL | | } + | |_^ + +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_h), + Method(::foo_i), + TraitVPtr(), + Method(::foo_j), + Method(::foo_k), + TraitVPtr(), + Method(::foo_l), + TraitVPtr(), + Method(::foo_m), + TraitVPtr(), + Method(::foo_n), +] + --> $DIR/vtable-multi-level.rs:89:1 + | +LL | / trait N: J + M { +LL | | +LL | | fn foo_n(&self) {} +LL | | } + | |_^ + +error: aborting due to 12 previous errors + diff --git a/src/test/ui/traits/vtable/vtable-vacant.rs b/src/test/ui/traits/vtable/vtable-vacant.rs new file mode 100644 index 00000000000..ebea94171f2 --- /dev/null +++ b/src/test/ui/traits/vtable/vtable-vacant.rs @@ -0,0 +1,28 @@ +// build-fail +#![feature(rustc_attrs)] + +// B --> A + +#[rustc_dump_vtable] +trait A { + fn foo_a1(&self) {} + fn foo_a2(&self) where Self: Sized {} +} + +#[rustc_dump_vtable] +trait B: A { + //~^ error Vtable + fn foo_b1(&self) {} + fn foo_b2() where Self: Sized {} +} + +struct S; + +impl A for S {} +impl B for S {} + +fn foo(_: &dyn B) {} + +fn main() { + foo(&S); +} diff --git a/src/test/ui/traits/vtable/vtable-vacant.stderr b/src/test/ui/traits/vtable/vtable-vacant.stderr new file mode 100644 index 00000000000..768cca52689 --- /dev/null +++ b/src/test/ui/traits/vtable/vtable-vacant.stderr @@ -0,0 +1,20 @@ +error: Vtable entries for ``: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(::foo_a1), + Vacant, + Method(::foo_b1), + Vacant, +] + --> $DIR/vtable-vacant.rs:13:1 + | +LL | / trait B: A { +LL | | +LL | | fn foo_b1(&self) {} +LL | | fn foo_b2() where Self: Sized {} +LL | | } + | |_^ + +error: aborting due to previous error +