Skip to content

Commit 051d117

Browse files
committed
Auto merge of rust-lang#95104 - compiler-errors:remove-ascription, r=davidtwco
suggest removing type ascription in bad parsing position Not sure how to test this with the non-nightly suggestion. Didn't add a new UI test because it already manifests in an existing UI test. Fixes rust-lang#95014
2 parents eded76b + 3516a16 commit 051d117

File tree

2 files changed

+115
-6
lines changed

2 files changed

+115
-6
lines changed

compiler/rustc_parse/src/parser/expr.rs

+35-6
Original file line numberDiff line numberDiff line change
@@ -800,11 +800,17 @@ impl<'a> Parser<'a> {
800800
&mut self,
801801
cast_expr: P<Expr>,
802802
) -> PResult<'a, P<Expr>> {
803+
let span = cast_expr.span;
804+
let maybe_ascription_span = if let ExprKind::Type(ascripted_expr, _) = &cast_expr.kind {
805+
Some(ascripted_expr.span.shrink_to_hi().with_hi(span.hi()))
806+
} else {
807+
None
808+
};
809+
803810
// Save the memory location of expr before parsing any following postfix operators.
804811
// This will be compared with the memory location of the output expression.
805812
// If they different we can assume we parsed another expression because the existing expression is not reallocated.
806813
let addr_before = &*cast_expr as *const _ as usize;
807-
let span = cast_expr.span;
808814
let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
809815
let changed = addr_before != &*with_postfix as *const _ as usize;
810816

@@ -825,11 +831,8 @@ impl<'a> Parser<'a> {
825831
}
826832
);
827833
let mut err = self.struct_span_err(span, &msg);
828-
// If type ascription is "likely an error", the user will already be getting a useful
829-
// help message, and doesn't need a second.
830-
if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) {
831-
self.maybe_annotate_with_ascription(&mut err, false);
832-
} else {
834+
835+
let suggest_parens = |err: &mut DiagnosticBuilder<'_, _>| {
833836
let suggestions = vec![
834837
(span.shrink_to_lo(), "(".to_string()),
835838
(span.shrink_to_hi(), ")".to_string()),
@@ -839,6 +842,32 @@ impl<'a> Parser<'a> {
839842
suggestions,
840843
Applicability::MachineApplicable,
841844
);
845+
};
846+
847+
// If type ascription is "likely an error", the user will already be getting a useful
848+
// help message, and doesn't need a second.
849+
if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) {
850+
self.maybe_annotate_with_ascription(&mut err, false);
851+
} else if let Some(ascription_span) = maybe_ascription_span {
852+
let is_nightly = self.sess.unstable_features.is_nightly_build();
853+
if is_nightly {
854+
suggest_parens(&mut err);
855+
}
856+
err.span_suggestion(
857+
ascription_span,
858+
&format!(
859+
"{}remove the type ascription",
860+
if is_nightly { "alternatively, " } else { "" }
861+
),
862+
String::new(),
863+
if is_nightly {
864+
Applicability::MaybeIncorrect
865+
} else {
866+
Applicability::MachineApplicable
867+
},
868+
);
869+
} else {
870+
suggest_parens(&mut err);
842871
}
843872
err.emit();
844873
};

src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr

+80
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ help: try surrounding the expression in parentheses
1919
|
2020
LL | (vec![1, 2, 3]: Vec<i32>)[0];
2121
| + +
22+
help: alternatively, remove the type ascription
23+
|
24+
LL - vec![1, 2, 3]: Vec<i32>[0];
25+
LL + vec![1, 2, 3][0];
26+
|
2227

2328
error: casts cannot be followed by indexing
2429
--> $DIR/issue-35813-postfix-after-cast.rs:17:5
@@ -41,6 +46,11 @@ help: try surrounding the expression in parentheses
4146
|
4247
LL | ((&[0i32]): &[i32; 1])[0];
4348
| + +
49+
help: alternatively, remove the type ascription
50+
|
51+
LL - (&[0i32]): &[i32; 1][0];
52+
LL + (&[0i32])[0];
53+
|
4454

4555
error: casts cannot be followed by a method call
4656
--> $DIR/issue-35813-postfix-after-cast.rs:39:13
@@ -52,6 +62,11 @@ help: try surrounding the expression in parentheses
5262
|
5363
LL | let _ = (0i32: i32: i32).count_ones();
5464
| + +
65+
help: alternatively, remove the type ascription
66+
|
67+
LL - let _ = 0i32: i32: i32.count_ones();
68+
LL + let _ = 0i32: i32.count_ones();
69+
|
5570

5671
error: casts cannot be followed by a method call
5772
--> $DIR/issue-35813-postfix-after-cast.rs:41:13
@@ -63,6 +78,11 @@ help: try surrounding the expression in parentheses
6378
|
6479
LL | let _ = (0 as i32: i32).count_ones();
6580
| + +
81+
help: alternatively, remove the type ascription
82+
|
83+
LL - let _ = 0 as i32: i32.count_ones();
84+
LL + let _ = 0 as i32.count_ones();
85+
|
6686

6787
error: casts cannot be followed by a method call
6888
--> $DIR/issue-35813-postfix-after-cast.rs:43:13
@@ -107,6 +127,11 @@ help: try surrounding the expression in parentheses
107127
|
108128
LL | let _ = (0i32: i32).count_ones(): u32;
109129
| + +
130+
help: alternatively, remove the type ascription
131+
|
132+
LL - let _ = 0i32: i32.count_ones(): u32;
133+
LL + let _ = 0i32.count_ones(): u32;
134+
|
110135

111136
error: casts cannot be followed by a method call
112137
--> $DIR/issue-35813-postfix-after-cast.rs:51:13
@@ -129,6 +154,11 @@ help: try surrounding the expression in parentheses
129154
|
130155
LL | let _ = (0i32: i32).count_ones() as u32;
131156
| + +
157+
help: alternatively, remove the type ascription
158+
|
159+
LL - let _ = 0i32: i32.count_ones() as u32;
160+
LL + let _ = 0i32.count_ones() as u32;
161+
|
132162

133163
error: casts cannot be followed by a method call
134164
--> $DIR/issue-35813-postfix-after-cast.rs:55:13
@@ -151,6 +181,11 @@ help: try surrounding the expression in parentheses
151181
|
152182
LL | let _ = (0i32: i32: i32).count_ones() as u32 as i32;
153183
| + +
184+
help: alternatively, remove the type ascription
185+
|
186+
LL - let _ = 0i32: i32: i32.count_ones() as u32 as i32;
187+
LL + let _ = 0i32: i32.count_ones() as u32 as i32;
188+
|
154189

155190
error: casts cannot be followed by a method call
156191
--> $DIR/issue-35813-postfix-after-cast.rs:62:13
@@ -198,6 +233,11 @@ help: try surrounding the expression in parentheses
198233
|
199234
LL | (0: i32).max(0);
200235
| + +
236+
help: alternatively, remove the type ascription
237+
|
238+
LL - 0: i32.max(0);
239+
LL + 0.max(0);
240+
|
201241

202242
error: casts cannot be followed by a method call
203243
--> $DIR/issue-35813-postfix-after-cast.rs:92:8
@@ -220,6 +260,11 @@ help: try surrounding the expression in parentheses
220260
|
221261
LL | if (5u64: u64).max(0) == 0 {
222262
| + +
263+
help: alternatively, remove the type ascription
264+
|
265+
LL - if 5u64: u64.max(0) == 0 {
266+
LL + if 5u64.max(0) == 0 {
267+
|
223268

224269
error: casts cannot be followed by a method call
225270
--> $DIR/issue-35813-postfix-after-cast.rs:102:9
@@ -242,6 +287,11 @@ help: try surrounding the expression in parentheses
242287
|
243288
LL | (5u64: u64).max(0) == 0
244289
| + +
290+
help: alternatively, remove the type ascription
291+
|
292+
LL - 5u64: u64.max(0) == 0
293+
LL + 5u64.max(0) == 0
294+
|
245295

246296
error: casts cannot be followed by indexing
247297
--> $DIR/issue-35813-postfix-after-cast.rs:111:24
@@ -264,6 +314,11 @@ help: try surrounding the expression in parentheses
264314
|
265315
LL | static bar2: &[i32] = &((&[1i32,2,3]: &[i32; 3])[0..1]);
266316
| + +
317+
help: alternatively, remove the type ascription
318+
|
319+
LL - static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
320+
LL + static bar2: &[i32] = &(&[1i32,2,3][0..1]);
321+
|
267322

268323
error: casts cannot be followed by `?`
269324
--> $DIR/issue-35813-postfix-after-cast.rs:119:5
@@ -286,6 +341,11 @@ help: try surrounding the expression in parentheses
286341
|
287342
LL | (Err(0u64): Result<u64,u64>)?;
288343
| + +
344+
help: alternatively, remove the type ascription
345+
|
346+
LL - Err(0u64): Result<u64,u64>?;
347+
LL + Err(0u64)?;
348+
|
289349

290350
error: casts cannot be followed by a function call
291351
--> $DIR/issue-35813-postfix-after-cast.rs:145:5
@@ -308,6 +368,11 @@ help: try surrounding the expression in parentheses
308368
|
309369
LL | (drop_ptr: fn(u8))(0);
310370
| + +
371+
help: alternatively, remove the type ascription
372+
|
373+
LL - drop_ptr: fn(u8)(0);
374+
LL + drop_ptr(0);
375+
|
311376

312377
error: casts cannot be followed by `.await`
313378
--> $DIR/issue-35813-postfix-after-cast.rs:152:5
@@ -330,6 +395,11 @@ help: try surrounding the expression in parentheses
330395
|
331396
LL | (Box::pin(noop()): Pin<Box<_>>).await;
332397
| + +
398+
help: alternatively, remove the type ascription
399+
|
400+
LL - Box::pin(noop()): Pin<Box<_>>.await;
401+
LL + Box::pin(noop()).await;
402+
|
333403

334404
error: casts cannot be followed by a field access
335405
--> $DIR/issue-35813-postfix-after-cast.rs:167:5
@@ -352,6 +422,11 @@ help: try surrounding the expression in parentheses
352422
|
353423
LL | (Foo::default(): Foo).bar;
354424
| + +
425+
help: alternatively, remove the type ascription
426+
|
427+
LL - Foo::default(): Foo.bar;
428+
LL + Foo::default().bar;
429+
|
355430

356431
error: casts cannot be followed by a method call
357432
--> $DIR/issue-35813-postfix-after-cast.rs:84:9
@@ -374,6 +449,11 @@ help: try surrounding the expression in parentheses
374449
|
375450
LL | (if true { 33 } else { 44 }: i32).max(0)
376451
| + +
452+
help: alternatively, remove the type ascription
453+
|
454+
LL - if true { 33 } else { 44 }: i32.max(0)
455+
LL + if true { 33 } else { 44 }.max(0)
456+
|
377457

378458
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
379459
--> $DIR/issue-35813-postfix-after-cast.rs:131:13

0 commit comments

Comments
 (0)