Disable usage on trait impls and aliases

This commit is contained in:
mejrs 2025-03-29 11:46:03 +01:00
parent 8586cad77c
commit 9abaa9d4df
7 changed files with 68 additions and 35 deletions

View file

@ -553,6 +553,13 @@ impl<'tcx> OnUnimplementedDirective {
}
pub fn of_item(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<Option<Self>, 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 },
);

View file

@ -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<T: Alias>(v: &T) {
}
pub fn main() {
foo(&1);
}

View file

@ -0,0 +1,17 @@
// used to ICE, see <https://github.com/rust-lang/rust/issues/130627>
// 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<T: Alias>(v: &T) {}
pub fn main() {
foo(&1);
//~^ ERROR the trait bound `{integer}: Alias` is not satisfied
}

View file

@ -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<T: Alias>(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`.

View file

@ -2,7 +2,7 @@ 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 {B} {C}
| ----------------- ^^^^^^^^^^^^^^^^^^ the trait `Foo<usize>` is not implemented for `(i32, i32, i32)`
| |
| required by a bound introduced by this call
|

View file

@ -15,11 +15,10 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
--> $DIR/multiple-impls.rs:36:33
|
LL | Index::index(&[] as &[i32], Foo(2u32));
| ------------ ^^^^^^^^^ on impl for Foo
| ------------ ^^^^^^^^^ the trait `Index<Foo<u32>>` is not implemented for `[i32]`
| |
| 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]` implements `Index<Bar<usize>>`
`[i32]` implements `Index<Foo<usize>>`
@ -28,11 +27,10 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
--> $DIR/multiple-impls.rs:39:33
|
LL | Index::index(&[] as &[i32], Bar(2u32));
| ------------ ^^^^^^^^^ on impl for Bar
| ------------ ^^^^^^^^^ the trait `Index<Bar<u32>>` is not implemented for `[i32]`
| |
| 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]` implements `Index<Bar<usize>>`
`[i32]` implements `Index<Foo<usize>>`
@ -52,9 +50,8 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
--> $DIR/multiple-impls.rs:36:5
|
LL | Index::index(&[] as &[i32], Foo(2u32));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index<Foo<u32>>` is not implemented for `[i32]`
|
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
= help: the following other types implement trait `Index<Idx>`:
`[i32]` implements `Index<Bar<usize>>`
`[i32]` implements `Index<Foo<usize>>`
@ -63,9 +60,8 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
--> $DIR/multiple-impls.rs:39:5
|
LL | Index::index(&[] as &[i32], Bar(2u32));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index<Bar<u32>>` is not implemented for `[i32]`
|
= help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
= help: the following other types implement trait `Index<Idx>`:
`[i32]` implements `Index<Bar<usize>>`
`[i32]` implements `Index<Foo<usize>>`

View file

@ -2,7 +2,7 @@ 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
| ------------------- ^^^^ the trait `Index<u32>` is not implemented for `[i32]`
| |
| required by a bound introduced by this call
|
@ -14,7 +14,7 @@ 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
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index<u32>` is not implemented for `[i32]`
|
= help: the trait `Index<u32>` is not implemented for `[i32]`
but trait `Index<usize>` is implemented for it