diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 0478f3a7f112..ca51f177f964 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -553,6 +553,13 @@ impl<'tcx> OnUnimplementedDirective { } pub fn of_item(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result, ErrorGuaranteed> { + if !tcx.is_trait(item_def_id) { + // It could be a trait_alias (`trait MyTrait = SomeOtherTrait`) + // or an implementation (`impl MyTrait for Foo {}`) + // + // We don't support those. + return Ok(None); + } if let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented) { return Self::parse_attribute(attr, false, tcx, item_def_id); } else { @@ -782,8 +789,10 @@ impl<'tcx> OnUnimplementedFormatString { Ok(result) } - fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuaranteed> { - let trait_def_id = if tcx.is_trait(item_def_id) { item_def_id } else { return Ok(()) }; + fn verify(&self, tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> Result<(), ErrorGuaranteed> { + if !tcx.is_trait(trait_def_id) { + return Ok(()); + }; let ctx = if self.is_diagnostic_namespace_variant { Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id } @@ -810,10 +819,10 @@ impl<'tcx> OnUnimplementedFormatString { // so that users are aware that something is not correct for e in errors { if self.is_diagnostic_namespace_variant { - if let Some(item_def_id) = item_def_id.as_local() { + if let Some(trait_def_id) = trait_def_id.as_local() { tcx.emit_node_span_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, - tcx.local_def_id_to_hir_id(item_def_id), + tcx.local_def_id_to_hir_id(trait_def_id), self.span, WrappedParserError { description: e.description, label: e.label }, ); diff --git a/tests/crashes/130627.rs b/tests/crashes/130627.rs deleted file mode 100644 index 59d3606592bf..000000000000 --- a/tests/crashes/130627.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: #130627 - -#![feature(trait_alias)] - -trait Test {} - -#[diagnostic::on_unimplemented( - message="message", - label="label", - note="note" -)] -trait Alias = Test; - -// Use trait alias as bound on type parameter. -fn foo(v: &T) { -} - -pub fn main() { - foo(&1); -} diff --git a/tests/ui/diagnostic_namespace/on_impl_trait.rs b/tests/ui/diagnostic_namespace/on_impl_trait.rs new file mode 100644 index 000000000000..32a492c53a95 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_impl_trait.rs @@ -0,0 +1,17 @@ +// used to ICE, see +// Instead it should just ignore the diagnostic attribute +#![feature(trait_alias)] + +trait Test {} + +#[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")] +//~^ WARN `#[diagnostic::on_unimplemented]` can only be applied to trait definitions +trait Alias = Test; + +// Use trait alias as bound on type parameter. +fn foo(v: &T) {} + +pub fn main() { + foo(&1); + //~^ ERROR the trait bound `{integer}: Alias` is not satisfied +} diff --git a/tests/ui/diagnostic_namespace/on_impl_trait.stderr b/tests/ui/diagnostic_namespace/on_impl_trait.stderr new file mode 100644 index 000000000000..59b9c31bc53e --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_impl_trait.stderr @@ -0,0 +1,31 @@ +warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions + --> $DIR/on_impl_trait.rs:7:1 + | +LL | #[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + +error[E0277]: the trait bound `{integer}: Alias` is not satisfied + --> $DIR/on_impl_trait.rs:15:9 + | +LL | foo(&1); + | --- ^^ the trait `Test` is not implemented for `{integer}` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/on_impl_trait.rs:5:1 + | +LL | trait Test {} + | ^^^^^^^^^^ + = note: required for `{integer}` to implement `Alias` +note: required by a bound in `foo` + --> $DIR/on_impl_trait.rs:12:11 + | +LL | fn foo(v: &T) {} + | ^^^^^ required by this bound in `foo` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr index 0eabe9714922..2d83845ecb82 100644 --- a/tests/ui/on-unimplemented/impl-substs.stderr +++ b/tests/ui/on-unimplemented/impl-substs.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `(i32, i32, i32): Foo` is not satisfied --> $DIR/impl-substs.rs:13:23 | LL | Foo::::foo((1i32, 1i32, 1i32)); - | ----------------- ^^^^^^^^^^^^^^^^^^ an impl did not match: usize {B} {C} + | ----------------- ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(i32, i32, i32)` | | | required by a bound introduced by this call | diff --git a/tests/ui/on-unimplemented/multiple-impls.stderr b/tests/ui/on-unimplemented/multiple-impls.stderr index ba4e43ff3594..2afc9b1bf3b8 100644 --- a/tests/ui/on-unimplemented/multiple-impls.stderr +++ b/tests/ui/on-unimplemented/multiple-impls.stderr @@ -15,11 +15,10 @@ error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:36:33 | LL | Index::index(&[] as &[i32], Foo(2u32)); - | ------------ ^^^^^^^^^ on impl for Foo + | ------------ ^^^^^^^^^ the trait `Index>` is not implemented for `[i32]` | | | required by a bound introduced by this call | - = help: the trait `Index>` is not implemented for `[i32]` = help: the following other types implement trait `Index`: `[i32]` implements `Index>` `[i32]` implements `Index>` @@ -28,11 +27,10 @@ error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:39:33 | LL | Index::index(&[] as &[i32], Bar(2u32)); - | ------------ ^^^^^^^^^ on impl for Bar + | ------------ ^^^^^^^^^ the trait `Index>` is not implemented for `[i32]` | | | required by a bound introduced by this call | - = help: the trait `Index>` is not implemented for `[i32]` = help: the following other types implement trait `Index`: `[i32]` implements `Index>` `[i32]` implements `Index>` @@ -52,9 +50,8 @@ error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:36:5 | LL | Index::index(&[] as &[i32], Foo(2u32)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index>` is not implemented for `[i32]` | - = help: the trait `Index>` is not implemented for `[i32]` = help: the following other types implement trait `Index`: `[i32]` implements `Index>` `[i32]` implements `Index>` @@ -63,9 +60,8 @@ error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:39:5 | LL | Index::index(&[] as &[i32], Bar(2u32)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index>` is not implemented for `[i32]` | - = help: the trait `Index>` is not implemented for `[i32]` = help: the following other types implement trait `Index`: `[i32]` implements `Index>` `[i32]` implements `Index>` diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr index 5e7e2c4ea774..922db9db116e 100644 --- a/tests/ui/on-unimplemented/on-impl.stderr +++ b/tests/ui/on-unimplemented/on-impl.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:22:47 | LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); - | ------------------- ^^^^ a usize is required to index into a slice + | ------------------- ^^^^ the trait `Index` is not implemented for `[i32]` | | | required by a bound introduced by this call | @@ -14,7 +14,7 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:22:5 | LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index` is not implemented for `[i32]` | = help: the trait `Index` is not implemented for `[i32]` but trait `Index` is implemented for it