diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 0bf0e21baaf93..c02d1394f6bb5 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -330,6 +330,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .filter(|a| a.check_name("rustc_on_unimplemented")) .next() { + let name = self.tcx.item_name(def_id).as_str(); let err_sp = item.span.substitute_dummy(span); let trait_str = self.tcx.item_path_str(trait_ref.def_id); if let Some(istring) = item.value_str() { @@ -347,6 +348,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { Piece::NextArgument(a) => match a.position { Position::ArgumentNamed(s) => match generic_map.get(s) { Some(val) => Some(val), + None if s == name => { + Some(&trait_str) + } None => { span_err!(self.tcx.sess, err_sp, E0272, "the #[rustc_on_unimplemented] attribute on trait \ diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3241267bbc2e4..41edf8c2926ec 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1166,6 +1166,7 @@ fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }) { if let Some(istring) = attr.value_str() { let istring = istring.as_str(); + let name = tcx.item_name(def_id).as_str(); let parser = Parser::new(&istring); let types = &generics.types; for token in parser { @@ -1174,13 +1175,14 @@ fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Piece::NextArgument(a) => match a.position { // `{Self}` is allowed Position::ArgumentNamed(s) if s == "Self" => (), + // `{ThisTraitsName}` is allowed + Position::ArgumentNamed(s) if s == name => (), // So is `{A}` if A is a type parameter Position::ArgumentNamed(s) => match types.iter().find(|t| { t.name == s }) { Some(_) => (), None => { - let name = tcx.item_name(def_id); span_err!(tcx.sess, attr.span, E0230, "there is no type parameter \ {} on trait {}", diff --git a/src/test/compile-fail/on-unimplemented/bad-annotation.rs b/src/test/ui/on-unimplemented/bad-annotation.rs similarity index 100% rename from src/test/compile-fail/on-unimplemented/bad-annotation.rs rename to src/test/ui/on-unimplemented/bad-annotation.rs diff --git a/src/test/ui/on-unimplemented/bad-annotation.stderr b/src/test/ui/on-unimplemented/bad-annotation.stderr new file mode 100644 index 0000000000000..8599477e8ed7e --- /dev/null +++ b/src/test/ui/on-unimplemented/bad-annotation.stderr @@ -0,0 +1,22 @@ +error[E0232]: this attribute must have a value + --> $DIR/bad-annotation.rs:26:1 + | +26 | #[rustc_on_unimplemented] //~ ERROR this attribute must have a value + | ^^^^^^^^^^^^^^^^^^^^^^^^^ attribute requires a value + | + = note: eg `#[rustc_on_unimplemented = "foo"]` + +error[E0230]: there is no type parameter C on trait BadAnnotation2 + --> $DIR/bad-annotation.rs:30:1 + | +30 | #[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:35:1 + | +35 | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/compile-fail/on-unimplemented/multiple-impls.rs b/src/test/ui/on-unimplemented/multiple-impls.rs similarity index 100% rename from src/test/compile-fail/on-unimplemented/multiple-impls.rs rename to src/test/ui/on-unimplemented/multiple-impls.rs diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr new file mode 100644 index 0000000000000..a1fa8b720a829 --- /dev/null +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -0,0 +1,53 @@ +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/multiple-impls.rs:43:5 + | +43 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^ trait message + | + = help: the trait `Index` is not implemented for `[i32]` + = note: required by `Index::index` + +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/multiple-impls.rs:43:5 + | +43 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait message + | + = help: the trait `Index` is not implemented for `[i32]` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:49:5 + | +49 | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^ on impl for Foo + | + = help: the trait `Index>` is not implemented for `[i32]` + = note: required by `Index::index` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:49:5 + | +49 | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo + | + = help: the trait `Index>` is not implemented for `[i32]` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:55:5 + | +55 | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index>` is not implemented for `[i32]` + = note: required by `Index::index` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:55:5 + | +55 | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index>` is not implemented for `[i32]` + +error: aborting due to 6 previous errors + diff --git a/src/test/compile-fail/on-unimplemented/on-impl.rs b/src/test/ui/on-unimplemented/on-impl.rs similarity index 100% rename from src/test/compile-fail/on-unimplemented/on-impl.rs rename to src/test/ui/on-unimplemented/on-impl.rs diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr new file mode 100644 index 0000000000000..c8c06bf44fd6f --- /dev/null +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/on-impl.rs:32:5 + | +32 | Index::::index(&[1, 2, 3] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | + = help: the trait `Index` is not implemented for `[i32]` + = note: required by `Index::index` + +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/on-impl.rs:32:5 + | +32 | Index::::index(&[1, 2, 3] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | + = help: the trait `Index` is not implemented for `[i32]` + +error: aborting due to 2 previous errors + diff --git a/src/test/compile-fail/on-unimplemented/on-trait.rs b/src/test/ui/on-unimplemented/on-trait.rs similarity index 90% rename from src/test/compile-fail/on-unimplemented/on-trait.rs rename to src/test/ui/on-unimplemented/on-trait.rs index a8daef356a5cc..ed7ec9b143689 100644 --- a/src/test/compile-fail/on-unimplemented/on-trait.rs +++ b/src/test/ui/on-unimplemented/on-trait.rs @@ -11,9 +11,12 @@ #![feature(on_unimplemented)] -#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] -trait Foo -{} +pub mod Bar { + #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"] + pub trait Foo {} +} + +use Bar::Foo; fn foobar>() -> T { panic!() diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr new file mode 100644 index 0000000000000..84986c1ecfdd3 --- /dev/null +++ b/src/test/ui/on-unimplemented/on-trait.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `std::option::Option>: MyFromIterator<&u8>` is not satisfied + --> $DIR/on-trait.rs:37:30 + | +37 | let y: Option> = collect(x.iter()); // this should give approximately the same error for x.iter().collect() + | ^^^^^^^ a collection of type `std::option::Option>` cannot be built from an iterator over elements of type `&u8` + | + = help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option>` + = note: required by `collect` + +error[E0277]: the trait bound `std::string::String: Bar::Foo` is not satisfied + --> $DIR/on-trait.rs:42:21 + | +42 | let x: String = foobar(); //~ ERROR + | ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo` + | + = help: the trait `Bar::Foo` is not implemented for `std::string::String` + = note: required by `foobar` + +error: aborting due to 2 previous errors + diff --git a/src/test/compile-fail/on-unimplemented/slice-index.rs b/src/test/ui/on-unimplemented/slice-index.rs similarity index 100% rename from src/test/compile-fail/on-unimplemented/slice-index.rs rename to src/test/ui/on-unimplemented/slice-index.rs diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr new file mode 100644 index 0000000000000..68789f77f750c --- /dev/null +++ b/src/test/ui/on-unimplemented/slice-index.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `i32: std::slice::SliceIndex<[i32]>` is not satisfied + --> $DIR/slice-index.rs:21:5 + | +21 | x[1i32]; //~ ERROR E0277 + | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | + = help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32` + = note: required because of the requirements on the impl of `std::ops::Index` for `[i32]` + +error[E0277]: the trait bound `std::ops::RangeTo: std::slice::SliceIndex<[i32]>` is not satisfied + --> $DIR/slice-index.rs:24:5 + | +24 | x[..1i32]; //~ ERROR E0277 + | ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | + = help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `std::ops::RangeTo` + = note: required because of the requirements on the impl of `std::ops::Index>` for `[i32]` + +error: aborting due to 2 previous errors +