diff options
Diffstat (limited to 'tests/ui/on-unimplemented')
25 files changed, 761 insertions, 0 deletions
diff --git a/tests/ui/on-unimplemented/auxiliary/no_debug.rs b/tests/ui/on-unimplemented/auxiliary/no_debug.rs new file mode 100644 index 000000000..fd3dc0abd --- /dev/null +++ b/tests/ui/on-unimplemented/auxiliary/no_debug.rs @@ -0,0 +1,3 @@ +#![crate_type = "lib"] + +pub struct Bar; diff --git a/tests/ui/on-unimplemented/bad-annotation.rs b/tests/ui/on-unimplemented/bad-annotation.rs new file mode 100644 index 000000000..f05436b8c --- /dev/null +++ b/tests/ui/on-unimplemented/bad-annotation.rs @@ -0,0 +1,64 @@ +// ignore-tidy-linelength + +#![feature(rustc_attrs)] + +#![allow(unused)] + +#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] +trait Foo<Bar, Baz, Quux> +{} + +#[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"] +trait MyFromIterator<A> { + /// Builds a container with elements from an external iterator. + fn my_from_iter<T: Iterator<Item=A>>(iterator: T) -> Self; +} + +#[rustc_on_unimplemented] +//~^ ERROR malformed `rustc_on_unimplemented` attribute +trait BadAnnotation1 +{} + +#[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] +//~^ ERROR there is no parameter `C` on trait `BadAnnotation2` +trait BadAnnotation2<A,B> +{} + +#[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] +//~^ only named substitution parameters are allowed +trait BadAnnotation3<A,B> +{} + +#[rustc_on_unimplemented(lorem="")] +//~^ this attribute must have a valid +trait BadAnnotation4 {} + +#[rustc_on_unimplemented(lorem(ipsum(dolor)))] +//~^ this attribute must have a valid +trait BadAnnotation5 {} + +#[rustc_on_unimplemented(message="x", message="y")] +//~^ this attribute must have a valid +trait BadAnnotation6 {} + +#[rustc_on_unimplemented(message="x", on(desugared, message="y"))] +//~^ this attribute must have a valid +trait BadAnnotation7 {} + +#[rustc_on_unimplemented(on(), message="y")] +//~^ empty `on`-clause +trait BadAnnotation8 {} + +#[rustc_on_unimplemented(on="x", message="y")] +//~^ this attribute must have a valid +trait BadAnnotation9 {} + +#[rustc_on_unimplemented(on(x="y"), message="y")] +trait BadAnnotation10 {} + +#[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")] +//~^ this attribute must have a valid +trait BadAnnotation11 {} + +pub fn main() { +} diff --git a/tests/ui/on-unimplemented/bad-annotation.stderr b/tests/ui/on-unimplemented/bad-annotation.stderr new file mode 100644 index 000000000..a8d3c8680 --- /dev/null +++ b/tests/ui/on-unimplemented/bad-annotation.stderr @@ -0,0 +1,83 @@ +error: malformed `rustc_on_unimplemented` attribute input + --> $DIR/bad-annotation.rs:17:1 + | +LL | #[rustc_on_unimplemented] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[rustc_on_unimplemented = "message"] + | +LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] + | + +error[E0230]: there is no parameter `C` on trait `BadAnnotation2` + --> $DIR/bad-annotation.rs:22:1 + | +LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0231]: only named substitution parameters are allowed + --> $DIR/bad-annotation.rs:27:1 + | +LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0232]: this attribute must have a valid value + --> $DIR/bad-annotation.rs:32:26 + | +LL | #[rustc_on_unimplemented(lorem="")] + | ^^^^^^^^ expected value here + | + = note: eg `#[rustc_on_unimplemented(message="foo")]` + +error[E0232]: this attribute must have a valid value + --> $DIR/bad-annotation.rs:36:26 + | +LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))] + | ^^^^^^^^^^^^^^^^^^^ expected value here + | + = note: eg `#[rustc_on_unimplemented(message="foo")]` + +error[E0232]: this attribute must have a valid value + --> $DIR/bad-annotation.rs:40:39 + | +LL | #[rustc_on_unimplemented(message="x", message="y")] + | ^^^^^^^^^^^ expected value here + | + = note: eg `#[rustc_on_unimplemented(message="foo")]` + +error[E0232]: this attribute must have a valid value + --> $DIR/bad-annotation.rs:44:39 + | +LL | #[rustc_on_unimplemented(message="x", on(desugared, message="y"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here + | + = note: eg `#[rustc_on_unimplemented(message="foo")]` + +error[E0232]: empty `on`-clause in `#[rustc_on_unimplemented]` + --> $DIR/bad-annotation.rs:48:26 + | +LL | #[rustc_on_unimplemented(on(), message="y")] + | ^^^^ empty on-clause here + +error[E0232]: this attribute must have a valid value + --> $DIR/bad-annotation.rs:52:26 + | +LL | #[rustc_on_unimplemented(on="x", message="y")] + | ^^^^^^ expected value here + | + = note: eg `#[rustc_on_unimplemented(message="foo")]` + +error[E0232]: this attribute must have a valid value + --> $DIR/bad-annotation.rs:59:40 + | +LL | #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here + | + = note: eg `#[rustc_on_unimplemented(message="foo")]` + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0230, E0231, E0232. +For more information about an error, try `rustc --explain E0230`. diff --git a/tests/ui/on-unimplemented/expected-comma-found-token.rs b/tests/ui/on-unimplemented/expected-comma-found-token.rs new file mode 100644 index 000000000..8fb34f211 --- /dev/null +++ b/tests/ui/on-unimplemented/expected-comma-found-token.rs @@ -0,0 +1,13 @@ +// Tests that two closures cannot simultaneously have mutable +// access to the variable, whether that mutable access be used +// for direct assignment or for taking mutable ref. Issue #6801. + +#![feature(rustc_attrs)] + +#[rustc_on_unimplemented( + message="the message" + label="the label" //~ ERROR expected `,`, found `label` +)] +trait T {} + +fn main() { } diff --git a/tests/ui/on-unimplemented/expected-comma-found-token.stderr b/tests/ui/on-unimplemented/expected-comma-found-token.stderr new file mode 100644 index 000000000..048b72ee3 --- /dev/null +++ b/tests/ui/on-unimplemented/expected-comma-found-token.stderr @@ -0,0 +1,10 @@ +error: expected `,`, found `label` + --> $DIR/expected-comma-found-token.rs:9:5 + | +LL | message="the message" + | - expected `,` +LL | label="the label" + | ^^^^^ unexpected token + +error: aborting due to previous error + diff --git a/tests/ui/on-unimplemented/feature-gate-on-unimplemented.rs b/tests/ui/on-unimplemented/feature-gate-on-unimplemented.rs new file mode 100644 index 000000000..3cc50e349 --- /dev/null +++ b/tests/ui/on-unimplemented/feature-gate-on-unimplemented.rs @@ -0,0 +1,8 @@ +// Test that `#[rustc_on_unimplemented]` is gated by `rustc_attrs` feature gate. + +#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"] +//~^ ERROR this is an internal attribute that will never be stable +trait Foo<Bar> +{} + +fn main() {} diff --git a/tests/ui/on-unimplemented/feature-gate-on-unimplemented.stderr b/tests/ui/on-unimplemented/feature-gate-on-unimplemented.stderr new file mode 100644 index 000000000..a4b33963f --- /dev/null +++ b/tests/ui/on-unimplemented/feature-gate-on-unimplemented.stderr @@ -0,0 +1,11 @@ +error[E0658]: this is an internal attribute that will never be stable + --> $DIR/feature-gate-on-unimplemented.rs:3:1 + | +LL | #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/on-unimplemented/impl-substs.rs b/tests/ui/on-unimplemented/impl-substs.rs new file mode 100644 index 000000000..fe9c50ec3 --- /dev/null +++ b/tests/ui/on-unimplemented/impl-substs.rs @@ -0,0 +1,15 @@ +#![feature(rustc_attrs)] + +trait Foo<A> { + fn foo(self); +} + +#[rustc_on_unimplemented = "an impl did not match: {A} {B} {C}"] +impl<A, B, C> Foo<A> for (A, B, C) { + fn foo(self) {} +} + +fn main() { + Foo::<usize>::foo((1i32, 1i32, 1i32)); + //~^ ERROR the trait bound `(i32, i32, i32): Foo<usize>` is not satisfied +} diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr new file mode 100644 index 000000000..a0fad0acd --- /dev/null +++ b/tests/ui/on-unimplemented/impl-substs.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `(i32, i32, i32): Foo<usize>` is not satisfied + --> $DIR/impl-substs.rs:13:23 + | +LL | Foo::<usize>::foo((1i32, 1i32, 1i32)); + | ----------------- ^^^^^^^^^^^^^^^^^^ an impl did not match: usize _ _ + | | + | required by a bound introduced by this call + | + = help: the trait `Foo<usize>` is not implemented for `(i32, i32, i32)` + = help: the trait `Foo<A>` is implemented for `(A, B, C)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/issue-104140.rs b/tests/ui/on-unimplemented/issue-104140.rs new file mode 100644 index 000000000..ade3f7270 --- /dev/null +++ b/tests/ui/on-unimplemented/issue-104140.rs @@ -0,0 +1,8 @@ +#![feature(rustc_attrs)] + +trait Foo {} + +#[rustc_on_unimplemented] //~ ERROR malformed `rustc_on_unimplemented` attribute input +impl Foo for u32 {} + +fn main() {} diff --git a/tests/ui/on-unimplemented/issue-104140.stderr b/tests/ui/on-unimplemented/issue-104140.stderr new file mode 100644 index 000000000..ddb1f50f0 --- /dev/null +++ b/tests/ui/on-unimplemented/issue-104140.stderr @@ -0,0 +1,15 @@ +error: malformed `rustc_on_unimplemented` attribute input + --> $DIR/issue-104140.rs:5:1 + | +LL | #[rustc_on_unimplemented] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[rustc_on_unimplemented = "message"] + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to previous error + diff --git a/tests/ui/on-unimplemented/multiple-impls.rs b/tests/ui/on-unimplemented/multiple-impls.rs new file mode 100644 index 000000000..a32fd4566 --- /dev/null +++ b/tests/ui/on-unimplemented/multiple-impls.rs @@ -0,0 +1,45 @@ +// Test if the on_unimplemented message override works + +#![feature(rustc_attrs)] + + +struct Foo<T>(T); +struct Bar<T>(T); + +#[rustc_on_unimplemented = "trait message"] +trait Index<Idx: ?Sized> { + type Output: ?Sized; + fn index(&self, index: Idx) -> &Self::Output; +} + +#[rustc_on_unimplemented = "on impl for Foo"] +impl Index<Foo<usize>> for [i32] { + type Output = i32; + fn index(&self, _index: Foo<usize>) -> &i32 { + loop {} + } +} + +#[rustc_on_unimplemented = "on impl for Bar"] +impl Index<Bar<usize>> for [i32] { + type Output = i32; + fn index(&self, _index: Bar<usize>) -> &i32 { + loop {} + } +} + + +fn main() { + Index::index(&[] as &[i32], 2u32); + //~^ ERROR E0277 + //~| ERROR E0277 + //~| ERROR E0277 + Index::index(&[] as &[i32], Foo(2u32)); + //~^ ERROR E0277 + //~| ERROR E0277 + //~| ERROR E0277 + Index::index(&[] as &[i32], Bar(2u32)); + //~^ ERROR E0277 + //~| ERROR E0277 + //~| ERROR E0277 +} diff --git a/tests/ui/on-unimplemented/multiple-impls.stderr b/tests/ui/on-unimplemented/multiple-impls.stderr new file mode 100644 index 000000000..d628b159a --- /dev/null +++ b/tests/ui/on-unimplemented/multiple-impls.stderr @@ -0,0 +1,108 @@ +error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied + --> $DIR/multiple-impls.rs:33:33 + | +LL | Index::index(&[] as &[i32], 2u32); + | ------------ ^^^^ trait message + | | + | required by a bound introduced by this call + | + = help: the trait `Index<u32>` is not implemented for `[i32]` + = help: the following other types implement trait `Index<Idx>`: + <[i32] as Index<Bar<usize>>> + <[i32] as Index<Foo<usize>>> + +error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied + --> $DIR/multiple-impls.rs:33:5 + | +LL | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait message + | + = help: the trait `Index<u32>` is not implemented for `[i32]` + = help: the following other types implement trait `Index<Idx>`: + <[i32] as Index<Bar<usize>>> + <[i32] as Index<Foo<usize>>> + +error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied + --> $DIR/multiple-impls.rs:37:33 + | +LL | Index::index(&[] as &[i32], Foo(2u32)); + | ------------ ^^^^^^^^^ on impl for Foo + | | + | required by a bound introduced by this call + | + = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]` + = help: the following other types implement trait `Index<Idx>`: + <[i32] as Index<Bar<usize>>> + <[i32] as Index<Foo<usize>>> + +error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied + --> $DIR/multiple-impls.rs:37:5 + | +LL | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo + | + = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]` + = help: the following other types implement trait `Index<Idx>`: + <[i32] as Index<Bar<usize>>> + <[i32] as Index<Foo<usize>>> + +error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied + --> $DIR/multiple-impls.rs:41:33 + | +LL | Index::index(&[] as &[i32], Bar(2u32)); + | ------------ ^^^^^^^^^ on impl for Bar + | | + | required by a bound introduced by this call + | + = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]` + = help: the following other types implement trait `Index<Idx>`: + <[i32] as Index<Bar<usize>>> + <[i32] as Index<Foo<usize>>> + +error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied + --> $DIR/multiple-impls.rs:41:5 + | +LL | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]` + = help: the following other types implement trait `Index<Idx>`: + <[i32] as Index<Bar<usize>>> + <[i32] as Index<Foo<usize>>> + +error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied + --> $DIR/multiple-impls.rs:33:5 + | +LL | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^ trait message + | + = help: the trait `Index<u32>` is not implemented for `[i32]` + = help: the following other types implement trait `Index<Idx>`: + <[i32] as Index<Bar<usize>>> + <[i32] as Index<Foo<usize>>> + +error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied + --> $DIR/multiple-impls.rs:37:5 + | +LL | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^ on impl for Foo + | + = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]` + = help: the following other types implement trait `Index<Idx>`: + <[i32] as Index<Bar<usize>>> + <[i32] as Index<Foo<usize>>> + +error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied + --> $DIR/multiple-impls.rs:41:5 + | +LL | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]` + = help: the following other types implement trait `Index<Idx>`: + <[i32] as Index<Bar<usize>>> + <[i32] as Index<Foo<usize>>> + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/no-debug.rs b/tests/ui/on-unimplemented/no-debug.rs new file mode 100644 index 000000000..bdc80c5b3 --- /dev/null +++ b/tests/ui/on-unimplemented/no-debug.rs @@ -0,0 +1,16 @@ +// aux-build:no_debug.rs + +extern crate no_debug; + +use no_debug::Bar; + +struct Foo; + +fn main() { + println!("{:?} {:?}", Foo, Bar); + println!("{} {}", Foo, Bar); +} +//~^^^ ERROR `Foo` doesn't implement `Debug` +//~| ERROR `Bar` doesn't implement `Debug` +//~^^^^ ERROR `Foo` doesn't implement `std::fmt::Display` +//~| ERROR `Bar` doesn't implement `std::fmt::Display` diff --git a/tests/ui/on-unimplemented/no-debug.stderr b/tests/ui/on-unimplemented/no-debug.stderr new file mode 100644 index 000000000..1035da54d --- /dev/null +++ b/tests/ui/on-unimplemented/no-debug.stderr @@ -0,0 +1,46 @@ +error[E0277]: `Foo` doesn't implement `Debug` + --> $DIR/no-debug.rs:10:27 + | +LL | println!("{:?} {:?}", Foo, Bar); + | ^^^ `Foo` cannot be formatted using `{:?}` + | + = help: the trait `Debug` is not implemented for `Foo` + = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo` + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Foo` with `#[derive(Debug)]` + | +LL | #[derive(Debug)] + | + +error[E0277]: `Bar` doesn't implement `Debug` + --> $DIR/no-debug.rs:10:32 + | +LL | println!("{:?} {:?}", Foo, Bar); + | ^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = help: the trait `Debug` is not implemented for `Bar` + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `Foo` doesn't implement `std::fmt::Display` + --> $DIR/no-debug.rs:11:23 + | +LL | println!("{} {}", Foo, Bar); + | ^^^ `Foo` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `Foo` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `Bar` doesn't implement `std::fmt::Display` + --> $DIR/no-debug.rs:11:28 + | +LL | println!("{} {}", Foo, Bar); + | ^^^ `Bar` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `Bar` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/on-impl.rs b/tests/ui/on-unimplemented/on-impl.rs new file mode 100644 index 000000000..d0537810c --- /dev/null +++ b/tests/ui/on-unimplemented/on-impl.rs @@ -0,0 +1,26 @@ +// Test if the on_unimplemented message override works + +#![feature(rustc_attrs)] + + +#[rustc_on_unimplemented = "invalid"] +trait Index<Idx: ?Sized> { + type Output: ?Sized; + fn index(&self, index: Idx) -> &Self::Output; +} + +#[rustc_on_unimplemented = "a usize is required to index into a slice"] +impl Index<usize> for [i32] { + type Output = i32; + fn index(&self, index: usize) -> &i32 { + &self[index] + } +} + + +fn main() { + Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32); + //~^ ERROR E0277 + //~| ERROR E0277 + //~| ERROR E0277 +} diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr new file mode 100644 index 000000000..2253c5992 --- /dev/null +++ b/tests/ui/on-unimplemented/on-impl.stderr @@ -0,0 +1,32 @@ +error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied + --> $DIR/on-impl.rs:22:47 + | +LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32); + | ------------------- ^^^^ a usize is required to index into a slice + | | + | required by a bound introduced by this call + | + = help: the trait `Index<u32>` is not implemented for `[i32]` + = help: the trait `Index<usize>` is implemented for `[i32]` + +error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied + --> $DIR/on-impl.rs:22:5 + | +LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | + = help: the trait `Index<u32>` is not implemented for `[i32]` + = help: the trait `Index<usize>` is implemented for `[i32]` + +error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied + --> $DIR/on-impl.rs:22:5 + | +LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | + = help: the trait `Index<u32>` is not implemented for `[i32]` + = help: the trait `Index<usize>` is implemented for `[i32]` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/on-trait.rs b/tests/ui/on-unimplemented/on-trait.rs new file mode 100644 index 000000000..556813cd4 --- /dev/null +++ b/tests/ui/on-unimplemented/on-trait.rs @@ -0,0 +1,32 @@ +// ignore-tidy-linelength + +#![feature(rustc_attrs)] + +pub mod Bar { + #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"] + pub trait Foo<Bar, Baz, Quux> {} +} + +use Bar::Foo; + +fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T { + panic!() +} + +#[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"] +trait MyFromIterator<A> { + /// Builds a container with elements from an external iterator. + fn my_from_iter<T: Iterator<Item=A>>(iterator: T) -> Self; +} + +fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B { + MyFromIterator::my_from_iter(it) +} + +pub fn main() { + let x = vec![1u8, 2, 3, 4]; + let y: Option<Vec<u8>> = collect(x.iter()); // this should give approximately the same error for x.iter().collect() + //~^ ERROR + + let x: String = foobar(); //~ ERROR +} diff --git a/tests/ui/on-unimplemented/on-trait.stderr b/tests/ui/on-unimplemented/on-trait.stderr new file mode 100644 index 000000000..4b040f1ac --- /dev/null +++ b/tests/ui/on-unimplemented/on-trait.stderr @@ -0,0 +1,29 @@ +error[E0277]: the trait bound `Option<Vec<u8>>: MyFromIterator<&u8>` is not satisfied + --> $DIR/on-trait.rs:28:30 + | +LL | let y: Option<Vec<u8>> = collect(x.iter()); // this should give approximately the same error for x.iter().collect() + | ^^^^^^^ a collection of type `Option<Vec<u8>>` cannot be built from an iterator over elements of type `&u8` + | + = help: the trait `MyFromIterator<&u8>` is not implemented for `Option<Vec<u8>>` +note: required by a bound in `collect` + --> $DIR/on-trait.rs:22:39 + | +LL | fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B { + | ^^^^^^^^^^^^^^^^^ required by this bound in `collect` + +error[E0277]: the trait bound `String: Foo<u8, _, u32>` is not satisfied + --> $DIR/on-trait.rs:31:21 + | +LL | let x: String = foobar(); + | ^^^^^^ test error `String` with `u8` `_` `u32` in `Foo` + | + = help: the trait `Foo<u8, _, u32>` is not implemented for `String` +note: required by a bound in `foobar` + --> $DIR/on-trait.rs:12:24 + | +LL | fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T { + | ^^^^^^^^^^^^^^^ required by this bound in `foobar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/parent-label.rs b/tests/ui/on-unimplemented/parent-label.rs new file mode 100644 index 000000000..b65f64968 --- /dev/null +++ b/tests/ui/on-unimplemented/parent-label.rs @@ -0,0 +1,27 @@ +// Test scope annotations from `parent_label` parameter + +#![feature(rustc_attrs)] + +#[rustc_on_unimplemented(parent_label = "in this scope")] +trait Trait {} + +struct Foo; + +fn f<T: Trait>(x: T) {} + +fn main() { + let x = || { + f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied + let y = || { + f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied + }; + }; + + { + { + f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied + } + } + + f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied +} diff --git a/tests/ui/on-unimplemented/parent-label.stderr b/tests/ui/on-unimplemented/parent-label.stderr new file mode 100644 index 000000000..8cd7412fd --- /dev/null +++ b/tests/ui/on-unimplemented/parent-label.stderr @@ -0,0 +1,69 @@ +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/parent-label.rs:14:11 + | +LL | let x = || { + | -- in this scope +LL | f(Foo {}); + | - ^^^^^^ the trait `Trait` is not implemented for `Foo` + | | + | required by a bound introduced by this call + | +note: required by a bound in `f` + --> $DIR/parent-label.rs:10:9 + | +LL | fn f<T: Trait>(x: T) {} + | ^^^^^ required by this bound in `f` + +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/parent-label.rs:16:15 + | +LL | let y = || { + | -- in this scope +LL | f(Foo {}); + | - ^^^^^^ the trait `Trait` is not implemented for `Foo` + | | + | required by a bound introduced by this call + | +note: required by a bound in `f` + --> $DIR/parent-label.rs:10:9 + | +LL | fn f<T: Trait>(x: T) {} + | ^^^^^ required by this bound in `f` + +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/parent-label.rs:22:15 + | +LL | fn main() { + | --------- in this scope +... +LL | f(Foo {}); + | - ^^^^^^ the trait `Trait` is not implemented for `Foo` + | | + | required by a bound introduced by this call + | +note: required by a bound in `f` + --> $DIR/parent-label.rs:10:9 + | +LL | fn f<T: Trait>(x: T) {} + | ^^^^^ required by this bound in `f` + +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/parent-label.rs:26:7 + | +LL | fn main() { + | --------- in this scope +... +LL | f(Foo {}); + | - ^^^^^^ the trait `Trait` is not implemented for `Foo` + | | + | required by a bound introduced by this call + | +note: required by a bound in `f` + --> $DIR/parent-label.rs:10:9 + | +LL | fn f<T: Trait>(x: T) {} + | ^^^^^ required by this bound in `f` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/slice-index.rs b/tests/ui/on-unimplemented/slice-index.rs new file mode 100644 index 000000000..758220d3c --- /dev/null +++ b/tests/ui/on-unimplemented/slice-index.rs @@ -0,0 +1,10 @@ +// Test new Index error message for slices + +use std::ops::Index; + + +fn main() { + let x = &[1, 2, 3] as &[i32]; + x[1i32]; //~ ERROR E0277 + x[..1i32]; //~ ERROR E0277 +} diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr new file mode 100644 index 000000000..a7ec3bda8 --- /dev/null +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -0,0 +1,25 @@ +error[E0277]: the type `[i32]` cannot be indexed by `i32` + --> $DIR/slice-index.rs:8:7 + | +LL | x[1i32]; + | ^^^^ slice indices are of type `usize` or ranges of `usize` + | + = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` + = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = note: required for `[i32]` to implement `Index<i32>` + +error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>` + --> $DIR/slice-index.rs:9:7 + | +LL | x[..1i32]; + | ^^^^^^ slice indices are of type `usize` or ranges of `usize` + | + = help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo<i32>` + = help: the following other types implement trait `SliceIndex<T>`: + <RangeTo<usize> as SliceIndex<[T]>> + <RangeTo<usize> as SliceIndex<str>> + = note: required for `[i32]` to implement `Index<RangeTo<i32>>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/sum.rs b/tests/ui/on-unimplemented/sum.rs new file mode 100644 index 000000000..4f1c521d9 --- /dev/null +++ b/tests/ui/on-unimplemented/sum.rs @@ -0,0 +1,9 @@ +// <https://github.com/rust-lang/rust/issues/105184> + +fn main() { + vec![(), ()].iter().sum::<i32>(); + //~^ ERROR + + vec![(), ()].iter().product::<i32>(); + //~^ ERROR +} diff --git a/tests/ui/on-unimplemented/sum.stderr b/tests/ui/on-unimplemented/sum.stderr new file mode 100644 index 000000000..2a316dba7 --- /dev/null +++ b/tests/ui/on-unimplemented/sum.stderr @@ -0,0 +1,43 @@ +error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()` + --> $DIR/sum.rs:4:25 + | +LL | vec![(), ()].iter().sum::<i32>(); + | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>` + | + = help: the trait `Sum<&()>` is not implemented for `i32` + = help: the following other types implement trait `Sum<A>`: + <i32 as Sum<&'a i32>> + <i32 as Sum> +note: the method call chain might not have had the expected associated types + --> $DIR/sum.rs:4:18 + | +LL | vec![(), ()].iter().sum::<i32>(); + | ------------ ^^^^^^ `Iterator::Item` is `&()` here + | | + | this expression has type `Vec<()>` +note: required by a bound in `std::iter::Iterator::sum` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error[E0277]: a value of type `i32` cannot be made by multiplying all elements of type `&()` from an iterator + --> $DIR/sum.rs:7:25 + | +LL | vec![(), ()].iter().product::<i32>(); + | ^^^^^^^ value of type `i32` cannot be made by multiplying all elements from a `std::iter::Iterator<Item=&()>` + | + = help: the trait `Product<&()>` is not implemented for `i32` + = help: the following other types implement trait `Product<A>`: + <i32 as Product<&'a i32>> + <i32 as Product> +note: the method call chain might not have had the expected associated types + --> $DIR/sum.rs:7:18 + | +LL | vec![(), ()].iter().product::<i32>(); + | ------------ ^^^^^^ `Iterator::Item` is `&()` here + | | + | this expression has type `Vec<()>` +note: required by a bound in `std::iter::Iterator::product` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. |