summaryrefslogtreecommitdiffstats
path: root/tests/ui/on-unimplemented
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/on-unimplemented')
-rw-r--r--tests/ui/on-unimplemented/auxiliary/no_debug.rs3
-rw-r--r--tests/ui/on-unimplemented/bad-annotation.rs64
-rw-r--r--tests/ui/on-unimplemented/bad-annotation.stderr83
-rw-r--r--tests/ui/on-unimplemented/expected-comma-found-token.rs13
-rw-r--r--tests/ui/on-unimplemented/expected-comma-found-token.stderr10
-rw-r--r--tests/ui/on-unimplemented/feature-gate-on-unimplemented.rs8
-rw-r--r--tests/ui/on-unimplemented/feature-gate-on-unimplemented.stderr11
-rw-r--r--tests/ui/on-unimplemented/impl-substs.rs15
-rw-r--r--tests/ui/on-unimplemented/impl-substs.stderr14
-rw-r--r--tests/ui/on-unimplemented/issue-104140.rs8
-rw-r--r--tests/ui/on-unimplemented/issue-104140.stderr15
-rw-r--r--tests/ui/on-unimplemented/multiple-impls.rs45
-rw-r--r--tests/ui/on-unimplemented/multiple-impls.stderr108
-rw-r--r--tests/ui/on-unimplemented/no-debug.rs16
-rw-r--r--tests/ui/on-unimplemented/no-debug.stderr46
-rw-r--r--tests/ui/on-unimplemented/on-impl.rs26
-rw-r--r--tests/ui/on-unimplemented/on-impl.stderr32
-rw-r--r--tests/ui/on-unimplemented/on-trait.rs32
-rw-r--r--tests/ui/on-unimplemented/on-trait.stderr29
-rw-r--r--tests/ui/on-unimplemented/parent-label.rs27
-rw-r--r--tests/ui/on-unimplemented/parent-label.stderr69
-rw-r--r--tests/ui/on-unimplemented/slice-index.rs10
-rw-r--r--tests/ui/on-unimplemented/slice-index.stderr25
-rw-r--r--tests/ui/on-unimplemented/sum.rs9
-rw-r--r--tests/ui/on-unimplemented/sum.stderr43
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`.