Disable usage on trait impls and aliases
This commit is contained in:
parent
8586cad77c
commit
9abaa9d4df
7 changed files with 68 additions and 35 deletions
|
@ -553,6 +553,13 @@ impl<'tcx> OnUnimplementedDirective {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn of_item(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<Option<Self>, ErrorGuaranteed> {
|
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) {
|
if let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented) {
|
||||||
return Self::parse_attribute(attr, false, tcx, item_def_id);
|
return Self::parse_attribute(attr, false, tcx, item_def_id);
|
||||||
} else {
|
} else {
|
||||||
|
@ -782,8 +789,10 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuaranteed> {
|
fn verify(&self, tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> Result<(), ErrorGuaranteed> {
|
||||||
let trait_def_id = if tcx.is_trait(item_def_id) { item_def_id } else { return Ok(()) };
|
if !tcx.is_trait(trait_def_id) {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
let ctx = if self.is_diagnostic_namespace_variant {
|
let ctx = if self.is_diagnostic_namespace_variant {
|
||||||
Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }
|
Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }
|
||||||
|
@ -810,10 +819,10 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||||
// so that users are aware that something is not correct
|
// so that users are aware that something is not correct
|
||||||
for e in errors {
|
for e in errors {
|
||||||
if self.is_diagnostic_namespace_variant {
|
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(
|
tcx.emit_node_span_lint(
|
||||||
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
|
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,
|
self.span,
|
||||||
WrappedParserError { description: e.description, label: e.label },
|
WrappedParserError { description: e.description, label: e.label },
|
||||||
);
|
);
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
17
tests/ui/diagnostic_namespace/on_impl_trait.rs
Normal file
17
tests/ui/diagnostic_namespace/on_impl_trait.rs
Normal 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
|
||||||
|
}
|
31
tests/ui/diagnostic_namespace/on_impl_trait.stderr
Normal file
31
tests/ui/diagnostic_namespace/on_impl_trait.stderr
Normal 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`.
|
|
@ -2,7 +2,7 @@ error[E0277]: the trait bound `(i32, i32, i32): Foo<usize>` is not satisfied
|
||||||
--> $DIR/impl-substs.rs:13:23
|
--> $DIR/impl-substs.rs:13:23
|
||||||
|
|
|
|
||||||
LL | Foo::<usize>::foo((1i32, 1i32, 1i32));
|
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
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
|
|
|
@ -15,11 +15,10 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
|
||||||
--> $DIR/multiple-impls.rs:36:33
|
--> $DIR/multiple-impls.rs:36:33
|
||||||
|
|
|
|
||||||
LL | Index::index(&[] as &[i32], Foo(2u32));
|
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
|
| 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>`:
|
= help: the following other types implement trait `Index<Idx>`:
|
||||||
`[i32]` implements `Index<Bar<usize>>`
|
`[i32]` implements `Index<Bar<usize>>`
|
||||||
`[i32]` implements `Index<Foo<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
|
--> $DIR/multiple-impls.rs:39:33
|
||||||
|
|
|
|
||||||
LL | Index::index(&[] as &[i32], Bar(2u32));
|
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
|
| 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>`:
|
= help: the following other types implement trait `Index<Idx>`:
|
||||||
`[i32]` implements `Index<Bar<usize>>`
|
`[i32]` implements `Index<Bar<usize>>`
|
||||||
`[i32]` implements `Index<Foo<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
|
--> $DIR/multiple-impls.rs:36:5
|
||||||
|
|
|
|
||||||
LL | Index::index(&[] as &[i32], Foo(2u32));
|
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>`:
|
= help: the following other types implement trait `Index<Idx>`:
|
||||||
`[i32]` implements `Index<Bar<usize>>`
|
`[i32]` implements `Index<Bar<usize>>`
|
||||||
`[i32]` implements `Index<Foo<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
|
--> $DIR/multiple-impls.rs:39:5
|
||||||
|
|
|
|
||||||
LL | Index::index(&[] as &[i32], Bar(2u32));
|
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>`:
|
= help: the following other types implement trait `Index<Idx>`:
|
||||||
`[i32]` implements `Index<Bar<usize>>`
|
`[i32]` implements `Index<Bar<usize>>`
|
||||||
`[i32]` implements `Index<Foo<usize>>`
|
`[i32]` implements `Index<Foo<usize>>`
|
||||||
|
|
|
@ -2,7 +2,7 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
|
||||||
--> $DIR/on-impl.rs:22:47
|
--> $DIR/on-impl.rs:22:47
|
||||||
|
|
|
|
||||||
LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
|
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
|
| 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
|
--> $DIR/on-impl.rs:22:5
|
||||||
|
|
|
|
||||||
LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
|
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]`
|
= help: the trait `Index<u32>` is not implemented for `[i32]`
|
||||||
but trait `Index<usize>` is implemented for it
|
but trait `Index<usize>` is implemented for it
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue