Skip to content

Commit 5fc9dbd

Browse files
committed
Do not ICE with incorrect empty suggestion
When we have two types with the same name, one without type parameters and the other with type parameters and a derive macro, we were before incorrectly suggesting to remove type parameters from the former, which ICEd because we were suggesting to remove nothing. We now gate against this. The output is still not perfect. E0107 should explicitly detect this case and provide better context, but for now let's avoid the ICE.
1 parent 3811f40 commit 5fc9dbd

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,17 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
10441044
},
10451045
);
10461046

1047-
err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect);
1047+
if span.lo() == span.hi() {
1048+
// Avoid ICE when types with the same name with `derive`s are in the same scope:
1049+
// struct NotSM;
1050+
// #[derive(PartialEq, Eq)]
1051+
// struct NotSM<T>(T);
1052+
// With the above code, the suggestion is to remove the generics of the first
1053+
// `NotSM`, which doesn't *have* generics, so we're suggesting to remove no code
1054+
// with no code, which ICEs on nightly due to an `assert!`.
1055+
} else {
1056+
err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect);
1057+
}
10481058
} else if redundant_lifetime_args && redundant_type_or_const_args {
10491059
remove_lifetime_args(err);
10501060
remove_type_or_const_args(err);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Here, there are two types with the same name. One of these has a `derive` annotation, but in the
2+
// expansion these `impl`s are associated to the the *other* type. There is a suggestion to remove
3+
// unneded type parameters, but because we're now point at a type with no type parameters, the
4+
// suggestion would suggest removing code from an empty span, which would ICE in nightly.
5+
6+
struct NotSM;
7+
8+
#[derive(PartialEq, Eq)]
9+
//~^ ERROR struct takes 0 generic arguments
10+
//~| ERROR struct takes 0 generic arguments
11+
//~| ERROR struct takes 0 generic arguments
12+
//~| ERROR struct takes 0 generic arguments
13+
struct NotSM<T>(T);
14+
//~^ ERROR the name `NotSM` is defined multiple times
15+
//~| ERROR no field `0`
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
error[E0428]: the name `NotSM` is defined multiple times
2+
--> $DIR/multiple-types-with-same-name-and-derive.rs:13:1
3+
|
4+
LL | struct NotSM;
5+
| ------------- previous definition of the type `NotSM` here
6+
...
7+
LL | struct NotSM<T>(T);
8+
| ^^^^^^^^^^^^^^^^^^^ `NotSM` redefined here
9+
|
10+
= note: `NotSM` must be defined only once in the type namespace of this module
11+
12+
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
13+
--> $DIR/multiple-types-with-same-name-and-derive.rs:8:10
14+
|
15+
LL | #[derive(PartialEq, Eq)]
16+
| ^^^^^^^^^ expected 0 generic arguments
17+
|
18+
note: struct defined here, with 0 generic parameters
19+
--> $DIR/multiple-types-with-same-name-and-derive.rs:6:8
20+
|
21+
LL | struct NotSM;
22+
| ^^^^^
23+
24+
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
25+
--> $DIR/multiple-types-with-same-name-and-derive.rs:8:10
26+
|
27+
LL | #[derive(PartialEq, Eq)]
28+
| ^^^^^^^^^ expected 0 generic arguments
29+
|
30+
note: struct defined here, with 0 generic parameters
31+
--> $DIR/multiple-types-with-same-name-and-derive.rs:6:8
32+
|
33+
LL | struct NotSM;
34+
| ^^^^^
35+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
36+
37+
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
38+
--> $DIR/multiple-types-with-same-name-and-derive.rs:8:21
39+
|
40+
LL | #[derive(PartialEq, Eq)]
41+
| ^^ expected 0 generic arguments
42+
|
43+
note: struct defined here, with 0 generic parameters
44+
--> $DIR/multiple-types-with-same-name-and-derive.rs:6:8
45+
|
46+
LL | struct NotSM;
47+
| ^^^^^
48+
49+
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
50+
--> $DIR/multiple-types-with-same-name-and-derive.rs:8:10
51+
|
52+
LL | #[derive(PartialEq, Eq)]
53+
| ^^^^^^^^^ expected 0 generic arguments
54+
|
55+
note: struct defined here, with 0 generic parameters
56+
--> $DIR/multiple-types-with-same-name-and-derive.rs:6:8
57+
|
58+
LL | struct NotSM;
59+
| ^^^^^
60+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
61+
62+
error[E0609]: no field `0` on type `&NotSM`
63+
--> $DIR/multiple-types-with-same-name-and-derive.rs:13:17
64+
|
65+
LL | struct NotSM<T>(T);
66+
| ^ unknown field
67+
68+
error: aborting due to 6 previous errors
69+
70+
Some errors have detailed explanations: E0107, E0428, E0609.
71+
For more information about an error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)