From 042f6052abfd6a8557192a8962d47b25fa61b021 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 23 Jun 2023 16:04:35 +0000 Subject: [PATCH] Add some tests around where bounds on associated items and their lack of effect on impls --- tests/ui/traits/auxiliary/trivial3.rs | 1 + tests/ui/traits/auxiliary/trivial4.rs | 3 +++ tests/ui/traits/trivial_impl.rs | 18 ++++++++++++++++ tests/ui/traits/trivial_impl.stderr | 14 ++++++++++++ tests/ui/traits/trivial_impl2.rs | 13 ++++++++++++ tests/ui/traits/trivial_impl2.stderr | 14 ++++++++++++ tests/ui/traits/trivial_impl3.rs | 19 +++++++++++++++++ tests/ui/traits/trivial_impl3.stderr | 14 ++++++++++++ tests/ui/traits/trivial_impl4.rs | 21 ++++++++++++++++++ tests/ui/traits/trivial_impl4.stderr | 14 ++++++++++++ tests/ui/traits/trivial_impl_sized.rs | 26 +++++++++++++++++++++++ tests/ui/traits/trivial_impl_sized.stderr | 25 ++++++++++++++++++++++ 12 files changed, 182 insertions(+) create mode 100644 tests/ui/traits/auxiliary/trivial3.rs create mode 100644 tests/ui/traits/auxiliary/trivial4.rs create mode 100644 tests/ui/traits/trivial_impl.rs create mode 100644 tests/ui/traits/trivial_impl.stderr create mode 100644 tests/ui/traits/trivial_impl2.rs create mode 100644 tests/ui/traits/trivial_impl2.stderr create mode 100644 tests/ui/traits/trivial_impl3.rs create mode 100644 tests/ui/traits/trivial_impl3.stderr create mode 100644 tests/ui/traits/trivial_impl4.rs create mode 100644 tests/ui/traits/trivial_impl4.stderr create mode 100644 tests/ui/traits/trivial_impl_sized.rs create mode 100644 tests/ui/traits/trivial_impl_sized.stderr diff --git a/tests/ui/traits/auxiliary/trivial3.rs b/tests/ui/traits/auxiliary/trivial3.rs new file mode 100644 index 0000000000000..0a47fdc74d721 --- /dev/null +++ b/tests/ui/traits/auxiliary/trivial3.rs @@ -0,0 +1 @@ +pub trait Trait {} diff --git a/tests/ui/traits/auxiliary/trivial4.rs b/tests/ui/traits/auxiliary/trivial4.rs new file mode 100644 index 0000000000000..a527d1a9526d9 --- /dev/null +++ b/tests/ui/traits/auxiliary/trivial4.rs @@ -0,0 +1,3 @@ +pub trait Trait {} + +impl Trait for () {} diff --git a/tests/ui/traits/trivial_impl.rs b/tests/ui/traits/trivial_impl.rs new file mode 100644 index 0000000000000..6ac8c744bc455 --- /dev/null +++ b/tests/ui/traits/trivial_impl.rs @@ -0,0 +1,18 @@ +//! This test checks that we do need to implement +//! all members, even if their where bounds only hold +//! due to other impls. + +trait Foo { + fn foo() + where + Self: Foo<()>; +} + +impl Foo<()> for () { + fn foo() {} +} + +impl Foo for () {} +//~^ ERROR: not all trait items implemented, missing: `foo` + +fn main() {} diff --git a/tests/ui/traits/trivial_impl.stderr b/tests/ui/traits/trivial_impl.stderr new file mode 100644 index 0000000000000..4b29b55bea13d --- /dev/null +++ b/tests/ui/traits/trivial_impl.stderr @@ -0,0 +1,14 @@ +error[E0046]: not all trait items implemented, missing: `foo` + --> $DIR/trivial_impl.rs:15:1 + | +LL | / fn foo() +LL | | where +LL | | Self: Foo<()>; + | |______________________- `foo` from trait +... +LL | impl Foo for () {} + | ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/traits/trivial_impl2.rs b/tests/ui/traits/trivial_impl2.rs new file mode 100644 index 0000000000000..be58096007f2b --- /dev/null +++ b/tests/ui/traits/trivial_impl2.rs @@ -0,0 +1,13 @@ +//! This test checks that we currently need to implement +//! members, even if their where bounds don't hold for the impl type. + +trait Foo { + fn foo() + where + Self: Foo<()>; +} + +impl Foo for () {} +//~^ ERROR: not all trait items implemented, missing: `foo` + +fn main() {} diff --git a/tests/ui/traits/trivial_impl2.stderr b/tests/ui/traits/trivial_impl2.stderr new file mode 100644 index 0000000000000..04c05df0616d1 --- /dev/null +++ b/tests/ui/traits/trivial_impl2.stderr @@ -0,0 +1,14 @@ +error[E0046]: not all trait items implemented, missing: `foo` + --> $DIR/trivial_impl2.rs:10:1 + | +LL | / fn foo() +LL | | where +LL | | Self: Foo<()>; + | |______________________- `foo` from trait +... +LL | impl Foo for () {} + | ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/traits/trivial_impl3.rs b/tests/ui/traits/trivial_impl3.rs new file mode 100644 index 0000000000000..714f643bc994c --- /dev/null +++ b/tests/ui/traits/trivial_impl3.rs @@ -0,0 +1,19 @@ +//! Check that we don't break orphan rules. +//! The dependency may add an impl for `u8` later, +//! which would break this crate. We want to avoid adding +//! more ways in which adding an impl can be a breaking change. + +// aux-build:trivial3.rs + +extern crate trivial3; + +pub trait Foo { + fn foo() + where + Self: trivial3::Trait; +} + +impl Foo for u8 {} +//~^ ERROR not all trait items implemented, missing: `foo` + +fn main() {} diff --git a/tests/ui/traits/trivial_impl3.stderr b/tests/ui/traits/trivial_impl3.stderr new file mode 100644 index 0000000000000..dfb39d6ce159c --- /dev/null +++ b/tests/ui/traits/trivial_impl3.stderr @@ -0,0 +1,14 @@ +error[E0046]: not all trait items implemented, missing: `foo` + --> $DIR/trivial_impl3.rs:16:1 + | +LL | / fn foo() +LL | | where +LL | | Self: trivial3::Trait; + | |______________________________- `foo` from trait +... +LL | impl Foo for u8 {} + | ^^^^^^^^^^^^^^^ missing `foo` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/traits/trivial_impl4.rs b/tests/ui/traits/trivial_impl4.rs new file mode 100644 index 0000000000000..518f159c1fb65 --- /dev/null +++ b/tests/ui/traits/trivial_impl4.rs @@ -0,0 +1,21 @@ +//! Check that we don't break orphan rules. +//! The dependency may add an impl for `u8` later, +//! which would break this crate. We want to avoid adding +//! more ways in which adding an impl can be a breaking change. +//! This test differs from `trivial_impl3` because there actually +//! exists any impl for `Trait`, which has an effect on coherence. + +// aux-build:trivial4.rs + +extern crate trivial4; + +pub trait Foo { + fn foo() + where + Self: trivial4::Trait; +} + +impl Foo for u8 {} +//~^ ERROR not all trait items implemented, missing: `foo` + +fn main() {} diff --git a/tests/ui/traits/trivial_impl4.stderr b/tests/ui/traits/trivial_impl4.stderr new file mode 100644 index 0000000000000..04b29ed77340d --- /dev/null +++ b/tests/ui/traits/trivial_impl4.stderr @@ -0,0 +1,14 @@ +error[E0046]: not all trait items implemented, missing: `foo` + --> $DIR/trivial_impl4.rs:18:1 + | +LL | / fn foo() +LL | | where +LL | | Self: trivial4::Trait; + | |______________________________- `foo` from trait +... +LL | impl Foo for u8 {} + | ^^^^^^^^^^^^^^^ missing `foo` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/traits/trivial_impl_sized.rs b/tests/ui/traits/trivial_impl_sized.rs new file mode 100644 index 0000000000000..501a3405090e6 --- /dev/null +++ b/tests/ui/traits/trivial_impl_sized.rs @@ -0,0 +1,26 @@ +//! This test checks that we currently need to implement +//! members, even if their where bounds don't hold for the impl type. + +trait Foo { + fn foo() + where + Self: Sized; +} + +impl Foo for () { + fn foo() {} +} + +// Must not be allowed +impl Foo for i32 {} +//~^ ERROR: not all trait items implemented, missing: `foo` + +// Should be allowed +impl Foo for dyn std::fmt::Debug {} +//~^ ERROR: not all trait items implemented, missing: `foo` + +impl Foo for dyn std::fmt::Display { + fn foo() {} +} + +fn main() {} diff --git a/tests/ui/traits/trivial_impl_sized.stderr b/tests/ui/traits/trivial_impl_sized.stderr new file mode 100644 index 0000000000000..ebf6dfc9dd2df --- /dev/null +++ b/tests/ui/traits/trivial_impl_sized.stderr @@ -0,0 +1,25 @@ +error[E0046]: not all trait items implemented, missing: `foo` + --> $DIR/trivial_impl_sized.rs:15:1 + | +LL | / fn foo() +LL | | where +LL | | Self: Sized; + | |____________________- `foo` from trait +... +LL | impl Foo for i32 {} + | ^^^^^^^^^^^^^^^^ missing `foo` in implementation + +error[E0046]: not all trait items implemented, missing: `foo` + --> $DIR/trivial_impl_sized.rs:19:1 + | +LL | / fn foo() +LL | | where +LL | | Self: Sized; + | |____________________- `foo` from trait +... +LL | impl Foo for dyn std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0046`.