Skip to content

Commit 36c1ac5

Browse files
authored
Unrolled build for rust-lang#116537
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.
2 parents be581d9 + 23a3b9e commit 36c1ac5

File tree

3 files changed

+356
-3
lines changed

3 files changed

+356
-3
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use rustc_middle::ty::{
3636
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
3737
use rustc_span::edit_distance::find_best_match_for_name;
3838
use rustc_span::symbol::{kw, Ident, Symbol};
39-
use rustc_span::{sym, Span, DUMMY_SP};
39+
use rustc_span::{sym, BytePos, Span, DUMMY_SP};
4040
use rustc_target::spec::abi;
4141
use rustc_trait_selection::traits::wf::object_region_bounds;
4242
use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCtxt};
@@ -1275,8 +1275,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
12751275
return;
12761276
};
12771277
// Get the span of the generics args *including* the leading `::`.
1278-
let args_span =
1279-
assoc_segment.ident.span.shrink_to_hi().to(args.span_ext);
1278+
// We do so by stretching args.span_ext to the left by 2. Earlier
1279+
// it was done based on the end of assoc segment but that sometimes
1280+
// led to impossible spans and caused issues like #116473
1281+
let args_span = args.span_ext.with_lo(args.span_ext.lo() - BytePos(2));
12801282
if tcx.generics_of(adt_def.did()).count() == 0 {
12811283
// FIXME(estebank): we could also verify that the arguments being
12821284
// work for the `enum`, instead of just looking if it takes *any*.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Regression test for ICE #116473.
2+
// The ICE occurs when arguments are specified on an enum variant
3+
// (which is illegal) and the variant and its preceding path are
4+
// located at different places such as in different macros or
5+
// different expansions of the same macro (i.e. when the macro
6+
// calls itself recursively)
7+
8+
enum Enum<T1, T2> { VariantA { _v1: T1, _v2: T2 }, VariantB }
9+
10+
type EnumUnit = Enum<(), ()>;
11+
12+
// Recursive macro call using a tt metavariable for variant
13+
macro_rules! recursive_tt {
14+
() => (recursive_tt!(VariantB));
15+
($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
16+
//~^ ERROR type arguments are not allowed on this type
17+
//~| ERROR mismatched types
18+
}
19+
20+
21+
// Recursive macro call using an ident metavariable for variant
22+
// (the behaviour is different for tt and ident)
23+
macro_rules! recursive_ident {
24+
() => (recursive_ident!(VariantB));
25+
($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
26+
//~^ ERROR type arguments are not allowed on this type
27+
//~| ERROR mismatched types
28+
}
29+
30+
31+
// Mested macro calls (i.e. one calling another) using a tt
32+
// metavariable for variant
33+
macro_rules! nested1_tt {
34+
() => (nested2_tt!(VariantB));
35+
}
36+
37+
macro_rules! nested2_tt {
38+
($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
39+
//~^ ERROR type arguments are not allowed on this type
40+
//~| ERROR mismatched types
41+
}
42+
43+
44+
// Mested macro calls using an ident metavariable for variant
45+
// (the behaviour is different for tt and ident)
46+
macro_rules! nested1_ident {
47+
() => (nested2_ident!(VariantB));
48+
}
49+
50+
macro_rules! nested2_ident {
51+
($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
52+
//~^ ERROR type arguments are not allowed on this type
53+
//~| ERROR mismatched types
54+
}
55+
56+
57+
// Mested macro calls when args are passed as metavariable
58+
// instead of the enum variant
59+
macro_rules! nested1_tt_args_in_first_macro {
60+
() => (nested2_tt_args_in_first_macro!(i32, u32));
61+
}
62+
63+
macro_rules! nested2_tt_args_in_first_macro {
64+
($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
65+
//~^ ERROR type arguments are not allowed on this type
66+
//~| ERROR mismatched types
67+
= 5 { true } else { false });
68+
}
69+
70+
// Mested macro calls when args are passed as metavariable
71+
// instead of the enum variant
72+
macro_rules! nested1_ident_args_in_first_macro {
73+
() => (nested2_ident_args_in_first_macro!(i32, u32));
74+
}
75+
76+
macro_rules! nested2_ident_args_in_first_macro {
77+
($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
78+
//~^ ERROR type arguments are not allowed on this type
79+
//~| ERROR mismatched types
80+
= 5 { true } else { false });
81+
}
82+
83+
fn main() {
84+
// Macro cases
85+
recursive_tt!();
86+
recursive_ident!();
87+
nested1_tt!();
88+
nested1_ident!();
89+
nested1_tt_args_in_first_macro!();
90+
nested1_ident_args_in_first_macro!();
91+
92+
// Regular, non-macro case
93+
if let EnumUnit::VariantB::<i32, u32> {} = 5 { true } else { false };
94+
//~^ ERROR type arguments are not allowed on this type
95+
//~| ERROR mismatched types
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
error[E0109]: type arguments are not allowed on this type
2+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:15:51
3+
|
4+
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
5+
| -------- ^^^ ^^^ type argument not allowed
6+
| |
7+
| not allowed on this type
8+
...
9+
LL | recursive_tt!();
10+
| ---------------
11+
| |
12+
| in this macro invocation
13+
| in this macro invocation
14+
|
15+
= note: enum variants can't have type parameters
16+
= note: this error originates in the macro `recursive_tt` (in Nightly builds, run with -Z macro-backtrace for more info)
17+
help: you might have meant to specify type parameters on enum `Enum`
18+
|
19+
LL - ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
20+
LL + ($variant:tt) => (if let EnumUnit::<i32, u32>::$variant {} = 5 { true } else { false });
21+
|
22+
23+
error[E0308]: mismatched types
24+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:15:30
25+
|
26+
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}`
28+
| |
29+
| expected integer, found `Enum<(), ()>`
30+
...
31+
LL | recursive_tt!();
32+
| --------------- in this macro invocation
33+
|
34+
= note: expected type `{integer}`
35+
found enum `Enum<(), ()>`
36+
= note: this error originates in the macro `recursive_tt` (in Nightly builds, run with -Z macro-backtrace for more info)
37+
38+
error[E0109]: type arguments are not allowed on this type
39+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:25:54
40+
|
41+
LL | () => (recursive_ident!(VariantB));
42+
| -------- not allowed on this type
43+
LL | ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
44+
| ^^^ ^^^ type argument not allowed
45+
...
46+
LL | recursive_ident!();
47+
| ------------------
48+
| |
49+
| in this macro invocation
50+
| in this macro invocation
51+
|
52+
= note: enum variants can't have type parameters
53+
= note: this error originates in the macro `recursive_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
54+
help: you might have meant to specify type parameters on enum `Enum`
55+
|
56+
LL - ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
57+
LL + ($variant:ident) => (if let EnumUnit::<i32, u32>::$variant {} = 5 { true } else { false });
58+
|
59+
60+
error[E0308]: mismatched types
61+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:25:33
62+
|
63+
LL | ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
64+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}`
65+
| |
66+
| expected integer, found `Enum<(), ()>`
67+
...
68+
LL | recursive_ident!();
69+
| ------------------ in this macro invocation
70+
|
71+
= note: expected type `{integer}`
72+
found enum `Enum<(), ()>`
73+
= note: this error originates in the macro `recursive_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
74+
75+
error[E0109]: type arguments are not allowed on this type
76+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:38:51
77+
|
78+
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
79+
| -------- ^^^ ^^^ type argument not allowed
80+
| |
81+
| not allowed on this type
82+
...
83+
LL | nested1_tt!();
84+
| -------------
85+
| |
86+
| in this macro invocation
87+
| in this macro invocation
88+
|
89+
= note: enum variants can't have type parameters
90+
= 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)
91+
help: you might have meant to specify type parameters on enum `Enum`
92+
|
93+
LL - ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
94+
LL + ($variant:tt) => (if let EnumUnit::<i32, u32>::$variant {} = 5 { true } else { false });
95+
|
96+
97+
error[E0308]: mismatched types
98+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:38:30
99+
|
100+
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
101+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}`
102+
| |
103+
| expected integer, found `Enum<(), ()>`
104+
...
105+
LL | nested1_tt!();
106+
| ------------- in this macro invocation
107+
|
108+
= note: expected type `{integer}`
109+
found enum `Enum<(), ()>`
110+
= 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)
111+
112+
error[E0109]: type arguments are not allowed on this type
113+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:51:54
114+
|
115+
LL | () => (nested2_ident!(VariantB));
116+
| -------- not allowed on this type
117+
...
118+
LL | ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
119+
| ^^^ ^^^ type argument not allowed
120+
...
121+
LL | nested1_ident!();
122+
| ----------------
123+
| |
124+
| in this macro invocation
125+
| in this macro invocation
126+
|
127+
= note: enum variants can't have type parameters
128+
= 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)
129+
help: you might have meant to specify type parameters on enum `Enum`
130+
|
131+
LL - ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
132+
LL + ($variant:ident) => (if let EnumUnit::<i32, u32>::$variant {} = 5 { true } else { false });
133+
|
134+
135+
error[E0308]: mismatched types
136+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:51:33
137+
|
138+
LL | ($variant:ident) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
139+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}`
140+
| |
141+
| expected integer, found `Enum<(), ()>`
142+
...
143+
LL | nested1_ident!();
144+
| ---------------- in this macro invocation
145+
|
146+
= note: expected type `{integer}`
147+
found enum `Enum<(), ()>`
148+
= 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)
149+
150+
error[E0109]: type arguments are not allowed on this type
151+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:64:58
152+
|
153+
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
154+
| -------- ^^^^^ ^^^^^ type argument not allowed
155+
| |
156+
| not allowed on this type
157+
...
158+
LL | nested1_tt_args_in_first_macro!();
159+
| ---------------------------------
160+
| |
161+
| in this macro invocation
162+
| in this macro invocation
163+
|
164+
= note: enum variants can't have type parameters
165+
= note: this error originates in the macro `nested1_tt_args_in_first_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
166+
help: you might have meant to specify type parameters on enum `Enum`
167+
|
168+
LL - ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
169+
LL + ($arg1:tt, $arg2:tt) => (if let EnumUnit::<$arg1, $arg2>::VariantB {}
170+
|
171+
172+
error[E0308]: mismatched types
173+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:64:37
174+
|
175+
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
176+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected integer, found `Enum<(), ()>`
177+
...
178+
LL | = 5 { true } else { false });
179+
| - this expression has type `{integer}`
180+
...
181+
LL | nested1_tt_args_in_first_macro!();
182+
| --------------------------------- in this macro invocation
183+
|
184+
= note: expected type `{integer}`
185+
found enum `Enum<(), ()>`
186+
= 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)
187+
188+
error[E0109]: type arguments are not allowed on this type
189+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:77:64
190+
|
191+
LL | ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
192+
| -------- ^^^^^ ^^^^^ type argument not allowed
193+
| |
194+
| not allowed on this type
195+
...
196+
LL | nested1_ident_args_in_first_macro!();
197+
| ------------------------------------
198+
| |
199+
| in this macro invocation
200+
| in this macro invocation
201+
|
202+
= note: enum variants can't have type parameters
203+
= 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)
204+
help: you might have meant to specify type parameters on enum `Enum`
205+
|
206+
LL - ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
207+
LL + ($arg1:ident, $arg2:ident) => (if let EnumUnit::<$arg1, $arg2>::VariantB {}
208+
|
209+
210+
error[E0308]: mismatched types
211+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:77:43
212+
|
213+
LL | ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
214+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected integer, found `Enum<(), ()>`
215+
...
216+
LL | = 5 { true } else { false });
217+
| - this expression has type `{integer}`
218+
...
219+
LL | nested1_ident_args_in_first_macro!();
220+
| ------------------------------------ in this macro invocation
221+
|
222+
= note: expected type `{integer}`
223+
found enum `Enum<(), ()>`
224+
= 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)
225+
226+
error[E0109]: type arguments are not allowed on this type
227+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:93:33
228+
|
229+
LL | if let EnumUnit::VariantB::<i32, u32> {} = 5 { true } else { false };
230+
| -------- ^^^ ^^^ type argument not allowed
231+
| |
232+
| not allowed on this type
233+
|
234+
= note: enum variants can't have type parameters
235+
help: you might have meant to specify type parameters on enum `Enum`
236+
|
237+
LL - if let EnumUnit::VariantB::<i32, u32> {} = 5 { true } else { false };
238+
LL + if let EnumUnit::<i32, u32>::VariantB {} = 5 { true } else { false };
239+
|
240+
241+
error[E0308]: mismatched types
242+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:93:12
243+
|
244+
LL | if let EnumUnit::VariantB::<i32, u32> {} = 5 { true } else { false };
245+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `{integer}`
246+
| |
247+
| expected integer, found `Enum<(), ()>`
248+
|
249+
= note: expected type `{integer}`
250+
found enum `Enum<(), ()>`
251+
252+
error: aborting due to 14 previous errors
253+
254+
Some errors have detailed explanations: E0109, E0308.
255+
For more information about an error, try `rustc --explain E0109`.

0 commit comments

Comments
 (0)