Skip to content

Commit

Permalink
Rollup merge of #127988 - estebank:dupe-derive-params, r=fmease
Browse files Browse the repository at this point in the history
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.

Fix #108748.
  • Loading branch information
workingjubilee authored Sep 18, 2024
2 parents 4722ad1 + 682c5f4 commit 2a1dd35
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,18 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
},
);

err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect);
if span.is_empty() {
// HACK: Avoid ICE when types with the same name with `derive`s are in the same scope:
// struct NotSM;
// #[derive(PartialEq, Eq)]
// struct NotSM<T>(T);
// With the above code, the suggestion would be to remove the generics of the first
// `NotSM`, which doesn't *have* generics, so we would suggest to remove no code with
// no code, which would trigger an `assert!` later. Ideally, we would do something a
// bit more principled. See closed PR #109082.
} else {
err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect);
}
} else if redundant_lifetime_args && redundant_type_or_const_args {
remove_lifetime_args(err);
remove_type_or_const_args(err);
Expand Down
19 changes: 19 additions & 0 deletions tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Here, there are two types with the same name. One of these has a `derive` annotation, but in the
// expansion these `impl`s are associated to the the *other* type. There is a suggestion to remove
// unneded type parameters, but because we're now point at a type with no type parameters, the
// suggestion would suggest removing code from an empty span, which would ICE in nightly.
//
// issue: rust-lang/rust#108748

struct NotSM;

#[derive(PartialEq, Eq)]
//~^ ERROR struct takes 0 generic arguments
//~| ERROR struct takes 0 generic arguments
//~| ERROR struct takes 0 generic arguments
//~| ERROR struct takes 0 generic arguments
struct NotSM<T>(T);
//~^ ERROR the name `NotSM` is defined multiple times
//~| ERROR no field `0`

fn main() {}
71 changes: 71 additions & 0 deletions tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
error[E0428]: the name `NotSM` is defined multiple times
--> $DIR/multiple-types-with-same-name-and-derive.rs:15:1
|
LL | struct NotSM;
| ------------- previous definition of the type `NotSM` here
...
LL | struct NotSM<T>(T);
| ^^^^^^^^^^^^^^^^^^^ `NotSM` redefined here
|
= note: `NotSM` must be defined only once in the type namespace of this module

error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/multiple-types-with-same-name-and-derive.rs:10:10
|
LL | #[derive(PartialEq, Eq)]
| ^^^^^^^^^ expected 0 generic arguments
|
note: struct defined here, with 0 generic parameters
--> $DIR/multiple-types-with-same-name-and-derive.rs:8:8
|
LL | struct NotSM;
| ^^^^^

error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/multiple-types-with-same-name-and-derive.rs:10:10
|
LL | #[derive(PartialEq, Eq)]
| ^^^^^^^^^ expected 0 generic arguments
|
note: struct defined here, with 0 generic parameters
--> $DIR/multiple-types-with-same-name-and-derive.rs:8:8
|
LL | struct NotSM;
| ^^^^^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/multiple-types-with-same-name-and-derive.rs:10:21
|
LL | #[derive(PartialEq, Eq)]
| ^^ expected 0 generic arguments
|
note: struct defined here, with 0 generic parameters
--> $DIR/multiple-types-with-same-name-and-derive.rs:8:8
|
LL | struct NotSM;
| ^^^^^

error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/multiple-types-with-same-name-and-derive.rs:10:10
|
LL | #[derive(PartialEq, Eq)]
| ^^^^^^^^^ expected 0 generic arguments
|
note: struct defined here, with 0 generic parameters
--> $DIR/multiple-types-with-same-name-and-derive.rs:8:8
|
LL | struct NotSM;
| ^^^^^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0609]: no field `0` on type `&NotSM`
--> $DIR/multiple-types-with-same-name-and-derive.rs:15:17
|
LL | struct NotSM<T>(T);
| ^ unknown field

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0107, E0428, E0609.
For more information about an error, try `rustc --explain E0107`.

0 comments on commit 2a1dd35

Please sign in to comment.