forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#116537 - gurry:116473-ice-sugg-overlap, r=compiler-errors Fix suggestion span involving wrongly placed generic arg on variant Fixes rust-lang#116473 The span computation was wrong. It went from the end of the variant to the end of the (wrongly placed) args. However, the variant lived in a different expansion and this resulted in a nonsensical span that overlaps with another and thereby leads to the ICE. In the fix I've changed span computation to not be based on the location of the variant, but purely on the location of the args. I simply extend the start of the args span 2 positions to the left and that includes the `::` and that's all we need apparently. This approach produces a correct span regardless of which macro/expansion the args reside in and where the variant is.
- Loading branch information
Showing
3 changed files
with
356 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Regression test for ICE #116473. | ||
// The ICE occurs when arguments are specified on an enum variant | ||
// (which is illegal) and the variant and its preceding path are | ||
// located at different places such as in different macros or | ||
// different expansions of the same macro (i.e. when the macro | ||
// calls itself recursively) | ||
|
||
enum Enum<T1, T2> { VariantA { _v1: T1, _v2: T2 }, VariantB } | ||
|
||
type EnumUnit = Enum<(), ()>; | ||
|
||
// Recursive macro call using a tt metavariable for variant | ||
macro_rules! recursive_tt { | ||
() => (recursive_tt!(VariantB)); | ||
($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
//~^ ERROR type arguments are not allowed on this type | ||
//~| ERROR mismatched types | ||
} | ||
|
||
|
||
// Recursive macro call using an ident metavariable for variant | ||
// (the behaviour is different for tt and ident) | ||
macro_rules! recursive_ident { | ||
() => (recursive_ident!(VariantB)); | ||
($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
//~^ ERROR type arguments are not allowed on this type | ||
//~| ERROR mismatched types | ||
} | ||
|
||
|
||
// Mested macro calls (i.e. one calling another) using a tt | ||
// metavariable for variant | ||
macro_rules! nested1_tt { | ||
() => (nested2_tt!(VariantB)); | ||
} | ||
|
||
macro_rules! nested2_tt { | ||
($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
//~^ ERROR type arguments are not allowed on this type | ||
//~| ERROR mismatched types | ||
} | ||
|
||
|
||
// Mested macro calls using an ident metavariable for variant | ||
// (the behaviour is different for tt and ident) | ||
macro_rules! nested1_ident { | ||
() => (nested2_ident!(VariantB)); | ||
} | ||
|
||
macro_rules! nested2_ident { | ||
($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
//~^ ERROR type arguments are not allowed on this type | ||
//~| ERROR mismatched types | ||
} | ||
|
||
|
||
// Mested macro calls when args are passed as metavariable | ||
// instead of the enum variant | ||
macro_rules! nested1_tt_args_in_first_macro { | ||
() => (nested2_tt_args_in_first_macro!(i32, u32)); | ||
} | ||
|
||
macro_rules! nested2_tt_args_in_first_macro { | ||
($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} | ||
//~^ ERROR type arguments are not allowed on this type | ||
//~| ERROR mismatched types | ||
= 5 { true } else { false }); | ||
} | ||
|
||
// Mested macro calls when args are passed as metavariable | ||
// instead of the enum variant | ||
macro_rules! nested1_ident_args_in_first_macro { | ||
() => (nested2_ident_args_in_first_macro!(i32, u32)); | ||
} | ||
|
||
macro_rules! nested2_ident_args_in_first_macro { | ||
($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} | ||
//~^ ERROR type arguments are not allowed on this type | ||
//~| ERROR mismatched types | ||
= 5 { true } else { false }); | ||
} | ||
|
||
fn main() { | ||
// Macro cases | ||
recursive_tt!(); | ||
recursive_ident!(); | ||
nested1_tt!(); | ||
nested1_ident!(); | ||
nested1_tt_args_in_first_macro!(); | ||
nested1_ident_args_in_first_macro!(); | ||
|
||
// Regular, non-macro case | ||
if let EnumUnit::VariantB::<i32, u32> {} = 5 { true } else { false }; | ||
//~^ ERROR type arguments are not allowed on this type | ||
//~| ERROR mismatched types | ||
} |
255 changes: 255 additions & 0 deletions
255
tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,255 @@ | ||
error[E0109]: type arguments are not allowed on this type | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:15:51 | ||
| | ||
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
| -------- ^^^ ^^^ type argument not allowed | ||
| | | ||
| not allowed on this type | ||
... | ||
LL | recursive_tt!(); | ||
| --------------- | ||
| | | ||
| in this macro invocation | ||
| in this macro invocation | ||
| | ||
= note: enum variants can't have type parameters | ||
= note: this error originates in the macro `recursive_tt` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
help: you might have meant to specify type parameters on enum `Enum` | ||
| | ||
LL - ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
LL + ($variant:tt) => (if let EnumUnit::<i32, u32>::$variant {} = 5 { true } else { false }); | ||
| | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:15:30 | ||
| | ||
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}` | ||
| | | ||
| expected integer, found `Enum<(), ()>` | ||
... | ||
LL | recursive_tt!(); | ||
| --------------- in this macro invocation | ||
| | ||
= note: expected type `{integer}` | ||
found enum `Enum<(), ()>` | ||
= note: this error originates in the macro `recursive_tt` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
||
error[E0109]: type arguments are not allowed on this type | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:25:54 | ||
| | ||
LL | () => (recursive_ident!(VariantB)); | ||
| -------- not allowed on this type | ||
LL | ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
| ^^^ ^^^ type argument not allowed | ||
... | ||
LL | recursive_ident!(); | ||
| ------------------ | ||
| | | ||
| in this macro invocation | ||
| in this macro invocation | ||
| | ||
= note: enum variants can't have type parameters | ||
= note: this error originates in the macro `recursive_ident` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
help: you might have meant to specify type parameters on enum `Enum` | ||
| | ||
LL - ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
LL + ($variant:ident) => (if let EnumUnit::<i32, u32>::$variant {} = 5 { true } else { false }); | ||
| | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:25:33 | ||
| | ||
LL | ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}` | ||
| | | ||
| expected integer, found `Enum<(), ()>` | ||
... | ||
LL | recursive_ident!(); | ||
| ------------------ in this macro invocation | ||
| | ||
= note: expected type `{integer}` | ||
found enum `Enum<(), ()>` | ||
= note: this error originates in the macro `recursive_ident` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
||
error[E0109]: type arguments are not allowed on this type | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:38:51 | ||
| | ||
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
| -------- ^^^ ^^^ type argument not allowed | ||
| | | ||
| not allowed on this type | ||
... | ||
LL | nested1_tt!(); | ||
| ------------- | ||
| | | ||
| in this macro invocation | ||
| in this macro invocation | ||
| | ||
= note: enum variants can't have type parameters | ||
= note: this error originates in the macro `nested2_tt` which comes from the expansion of the macro `nested1_tt` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
help: you might have meant to specify type parameters on enum `Enum` | ||
| | ||
LL - ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
LL + ($variant:tt) => (if let EnumUnit::<i32, u32>::$variant {} = 5 { true } else { false }); | ||
| | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:38:30 | ||
| | ||
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}` | ||
| | | ||
| expected integer, found `Enum<(), ()>` | ||
... | ||
LL | nested1_tt!(); | ||
| ------------- in this macro invocation | ||
| | ||
= note: expected type `{integer}` | ||
found enum `Enum<(), ()>` | ||
= note: this error originates in the macro `nested2_tt` which comes from the expansion of the macro `nested1_tt` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
||
error[E0109]: type arguments are not allowed on this type | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:51:54 | ||
| | ||
LL | () => (nested2_ident!(VariantB)); | ||
| -------- not allowed on this type | ||
... | ||
LL | ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
| ^^^ ^^^ type argument not allowed | ||
... | ||
LL | nested1_ident!(); | ||
| ---------------- | ||
| | | ||
| in this macro invocation | ||
| in this macro invocation | ||
| | ||
= note: enum variants can't have type parameters | ||
= note: this error originates in the macro `nested2_ident` which comes from the expansion of the macro `nested1_ident` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
help: you might have meant to specify type parameters on enum `Enum` | ||
| | ||
LL - ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
LL + ($variant:ident) => (if let EnumUnit::<i32, u32>::$variant {} = 5 { true } else { false }); | ||
| | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:51:33 | ||
| | ||
LL | ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false }); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}` | ||
| | | ||
| expected integer, found `Enum<(), ()>` | ||
... | ||
LL | nested1_ident!(); | ||
| ---------------- in this macro invocation | ||
| | ||
= note: expected type `{integer}` | ||
found enum `Enum<(), ()>` | ||
= note: this error originates in the macro `nested2_ident` which comes from the expansion of the macro `nested1_ident` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
||
error[E0109]: type arguments are not allowed on this type | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:64:58 | ||
| | ||
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} | ||
| -------- ^^^^^ ^^^^^ type argument not allowed | ||
| | | ||
| not allowed on this type | ||
... | ||
LL | nested1_tt_args_in_first_macro!(); | ||
| --------------------------------- | ||
| | | ||
| in this macro invocation | ||
| in this macro invocation | ||
| | ||
= note: enum variants can't have type parameters | ||
= note: this error originates in the macro `nested1_tt_args_in_first_macro` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
help: you might have meant to specify type parameters on enum `Enum` | ||
| | ||
LL - ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} | ||
LL + ($arg1:tt, $arg2:tt) => (if let EnumUnit::<$arg1, $arg2>::VariantB {} | ||
| | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:64:37 | ||
| | ||
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected integer, found `Enum<(), ()>` | ||
... | ||
LL | = 5 { true } else { false }); | ||
| - this expression has type `{integer}` | ||
... | ||
LL | nested1_tt_args_in_first_macro!(); | ||
| --------------------------------- in this macro invocation | ||
| | ||
= note: expected type `{integer}` | ||
found enum `Enum<(), ()>` | ||
= note: this error originates in the macro `nested2_tt_args_in_first_macro` which comes from the expansion of the macro `nested1_tt_args_in_first_macro` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
||
error[E0109]: type arguments are not allowed on this type | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:77:64 | ||
| | ||
LL | ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} | ||
| -------- ^^^^^ ^^^^^ type argument not allowed | ||
| | | ||
| not allowed on this type | ||
... | ||
LL | nested1_ident_args_in_first_macro!(); | ||
| ------------------------------------ | ||
| | | ||
| in this macro invocation | ||
| in this macro invocation | ||
| | ||
= note: enum variants can't have type parameters | ||
= note: this error originates in the macro `nested2_ident_args_in_first_macro` which comes from the expansion of the macro `nested1_ident_args_in_first_macro` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
help: you might have meant to specify type parameters on enum `Enum` | ||
| | ||
LL - ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} | ||
LL + ($arg1:ident, $arg2:ident) => (if let EnumUnit::<$arg1, $arg2>::VariantB {} | ||
| | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:77:43 | ||
| | ||
LL | ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected integer, found `Enum<(), ()>` | ||
... | ||
LL | = 5 { true } else { false }); | ||
| - this expression has type `{integer}` | ||
... | ||
LL | nested1_ident_args_in_first_macro!(); | ||
| ------------------------------------ in this macro invocation | ||
| | ||
= note: expected type `{integer}` | ||
found enum `Enum<(), ()>` | ||
= note: this error originates in the macro `nested2_ident_args_in_first_macro` which comes from the expansion of the macro `nested1_ident_args_in_first_macro` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
||
error[E0109]: type arguments are not allowed on this type | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:93:33 | ||
| | ||
LL | if let EnumUnit::VariantB::<i32, u32> {} = 5 { true } else { false }; | ||
| -------- ^^^ ^^^ type argument not allowed | ||
| | | ||
| not allowed on this type | ||
| | ||
= note: enum variants can't have type parameters | ||
help: you might have meant to specify type parameters on enum `Enum` | ||
| | ||
LL - if let EnumUnit::VariantB::<i32, u32> {} = 5 { true } else { false }; | ||
LL + if let EnumUnit::<i32, u32>::VariantB {} = 5 { true } else { false }; | ||
| | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:93:12 | ||
| | ||
LL | if let EnumUnit::VariantB::<i32, u32> {} = 5 { true } else { false }; | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}` | ||
| | | ||
| expected integer, found `Enum<(), ()>` | ||
| | ||
= note: expected type `{integer}` | ||
found enum `Enum<(), ()>` | ||
|
||
error: aborting due to 14 previous errors | ||
|
||
Some errors have detailed explanations: E0109, E0308. | ||
For more information about an error, try `rustc --explain E0109`. |