Skip to content

Commit 6cc3ceb

Browse files
committed
Disable usage on trait impls and aliases
1 parent 18398f3 commit 6cc3ceb

File tree

7 files changed

+68
-35
lines changed

7 files changed

+68
-35
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,13 @@ impl<'tcx> OnUnimplementedDirective {
553553
}
554554

555555
pub fn of_item(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<Option<Self>, ErrorGuaranteed> {
556+
if !tcx.is_trait(item_def_id) {
557+
// It could be a trait_alias (`trait MyTrait = SomeOtherTrait`)
558+
// or an implementation (`impl MyTrait for Foo {}`)
559+
//
560+
// We don't support those.
561+
return Ok(None);
562+
}
556563
if let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented) {
557564
return Self::parse_attribute(attr, false, tcx, item_def_id);
558565
} else {
@@ -782,8 +789,10 @@ impl<'tcx> OnUnimplementedFormatString {
782789
Ok(result)
783790
}
784791

785-
fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuaranteed> {
786-
let trait_def_id = if tcx.is_trait(item_def_id) { item_def_id } else { return Ok(()) };
792+
fn verify(&self, tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> Result<(), ErrorGuaranteed> {
793+
if !tcx.is_trait(trait_def_id) {
794+
return Ok(());
795+
};
787796

788797
let ctx = if self.is_diagnostic_namespace_variant {
789798
Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }
@@ -810,10 +819,10 @@ impl<'tcx> OnUnimplementedFormatString {
810819
// so that users are aware that something is not correct
811820
for e in errors {
812821
if self.is_diagnostic_namespace_variant {
813-
if let Some(item_def_id) = item_def_id.as_local() {
822+
if let Some(trait_def_id) = trait_def_id.as_local() {
814823
tcx.emit_node_span_lint(
815824
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
816-
tcx.local_def_id_to_hir_id(item_def_id),
825+
tcx.local_def_id_to_hir_id(trait_def_id),
817826
self.span,
818827
WrappedParserError { description: e.description, label: e.label },
819828
);

tests/crashes/130627.rs

-20
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// used to ICE, see <https://github.com/rust-lang/rust/issues/130627>
2+
// Instead it should just ignore the diagnostic attribute
3+
#![feature(trait_alias)]
4+
5+
trait Test {}
6+
7+
#[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")]
8+
//~^ WARN `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
9+
trait Alias = Test;
10+
11+
// Use trait alias as bound on type parameter.
12+
fn foo<T: Alias>(v: &T) {}
13+
14+
pub fn main() {
15+
foo(&1);
16+
//~^ ERROR the trait bound `{integer}: Alias` is not satisfied
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
2+
--> $DIR/on_impl_trait.rs:7:1
3+
|
4+
LL | #[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
8+
9+
error[E0277]: the trait bound `{integer}: Alias` is not satisfied
10+
--> $DIR/on_impl_trait.rs:15:9
11+
|
12+
LL | foo(&1);
13+
| --- ^^ the trait `Test` is not implemented for `{integer}`
14+
| |
15+
| required by a bound introduced by this call
16+
|
17+
help: this trait has no implementations, consider adding one
18+
--> $DIR/on_impl_trait.rs:5:1
19+
|
20+
LL | trait Test {}
21+
| ^^^^^^^^^^
22+
= note: required for `{integer}` to implement `Alias`
23+
note: required by a bound in `foo`
24+
--> $DIR/on_impl_trait.rs:12:11
25+
|
26+
LL | fn foo<T: Alias>(v: &T) {}
27+
| ^^^^^ required by this bound in `foo`
28+
29+
error: aborting due to 1 previous error; 1 warning emitted
30+
31+
For more information about this error, try `rustc --explain E0277`.

tests/ui/on-unimplemented/impl-substs.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `(i32, i32, i32): Foo<usize>` is not satisfied
22
--> $DIR/impl-substs.rs:13:23
33
|
44
LL | Foo::<usize>::foo((1i32, 1i32, 1i32));
5-
| ----------------- ^^^^^^^^^^^^^^^^^^ an impl did not match: usize {B} {C}
5+
| ----------------- ^^^^^^^^^^^^^^^^^^ the trait `Foo<usize>` is not implemented for `(i32, i32, i32)`
66
| |
77
| required by a bound introduced by this call
88
|

tests/ui/on-unimplemented/multiple-impls.stderr

+4-8
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
1515
--> $DIR/multiple-impls.rs:36:33
1616
|
1717
LL | Index::index(&[] as &[i32], Foo(2u32));
18-
| ------------ ^^^^^^^^^ on impl for Foo
18+
| ------------ ^^^^^^^^^ the trait `Index<Foo<u32>>` is not implemented for `[i32]`
1919
| |
2020
| required by a bound introduced by this call
2121
|
22-
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
2322
= help: the following other types implement trait `Index<Idx>`:
2423
`[i32]` implements `Index<Bar<usize>>`
2524
`[i32]` implements `Index<Foo<usize>>`
@@ -28,11 +27,10 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
2827
--> $DIR/multiple-impls.rs:39:33
2928
|
3029
LL | Index::index(&[] as &[i32], Bar(2u32));
31-
| ------------ ^^^^^^^^^ on impl for Bar
30+
| ------------ ^^^^^^^^^ the trait `Index<Bar<u32>>` is not implemented for `[i32]`
3231
| |
3332
| required by a bound introduced by this call
3433
|
35-
= help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
3634
= help: the following other types implement trait `Index<Idx>`:
3735
`[i32]` implements `Index<Bar<usize>>`
3836
`[i32]` implements `Index<Foo<usize>>`
@@ -52,9 +50,8 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
5250
--> $DIR/multiple-impls.rs:36:5
5351
|
5452
LL | Index::index(&[] as &[i32], Foo(2u32));
55-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index<Foo<u32>>` is not implemented for `[i32]`
5654
|
57-
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
5855
= help: the following other types implement trait `Index<Idx>`:
5956
`[i32]` implements `Index<Bar<usize>>`
6057
`[i32]` implements `Index<Foo<usize>>`
@@ -63,9 +60,8 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
6360
--> $DIR/multiple-impls.rs:39:5
6461
|
6562
LL | Index::index(&[] as &[i32], Bar(2u32));
66-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
63+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index<Bar<u32>>` is not implemented for `[i32]`
6764
|
68-
= help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
6965
= help: the following other types implement trait `Index<Idx>`:
7066
`[i32]` implements `Index<Bar<usize>>`
7167
`[i32]` implements `Index<Foo<usize>>`

tests/ui/on-unimplemented/on-impl.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
22
--> $DIR/on-impl.rs:22:47
33
|
44
LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
5-
| ------------------- ^^^^ a usize is required to index into a slice
5+
| ------------------- ^^^^ the trait `Index<u32>` is not implemented for `[i32]`
66
| |
77
| required by a bound introduced by this call
88
|
@@ -14,7 +14,7 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
1414
--> $DIR/on-impl.rs:22:5
1515
|
1616
LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Index<u32>` is not implemented for `[i32]`
1818
|
1919
= help: the trait `Index<u32>` is not implemented for `[i32]`
2020
but trait `Index<usize>` is implemented for it

0 commit comments

Comments
 (0)