diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a907f50a11b..148e0a24ec3 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -800,11 +800,17 @@ impl<'a> Parser<'a> { &mut self, cast_expr: P, ) -> PResult<'a, P> { + let span = cast_expr.span; + let maybe_ascription_span = if let ExprKind::Type(ascripted_expr, _) = &cast_expr.kind { + Some(ascripted_expr.span.shrink_to_hi().with_hi(span.hi())) + } else { + None + }; + // Save the memory location of expr before parsing any following postfix operators. // This will be compared with the memory location of the output expression. // If they different we can assume we parsed another expression because the existing expression is not reallocated. let addr_before = &*cast_expr as *const _ as usize; - let span = cast_expr.span; let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?; let changed = addr_before != &*with_postfix as *const _ as usize; @@ -825,11 +831,8 @@ impl<'a> Parser<'a> { } ); let mut err = self.struct_span_err(span, &msg); - // If type ascription is "likely an error", the user will already be getting a useful - // help message, and doesn't need a second. - if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) { - self.maybe_annotate_with_ascription(&mut err, false); - } else { + + let suggest_parens = |err: &mut DiagnosticBuilder<'_, _>| { let suggestions = vec![ (span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), ")".to_string()), @@ -839,6 +842,32 @@ impl<'a> Parser<'a> { suggestions, Applicability::MachineApplicable, ); + }; + + // If type ascription is "likely an error", the user will already be getting a useful + // help message, and doesn't need a second. + if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) { + self.maybe_annotate_with_ascription(&mut err, false); + } else if let Some(ascription_span) = maybe_ascription_span { + let is_nightly = self.sess.unstable_features.is_nightly_build(); + if is_nightly { + suggest_parens(&mut err); + } + err.span_suggestion( + ascription_span, + &format!( + "{}remove the type ascription", + if is_nightly { "alternatively, " } else { "" } + ), + String::new(), + if is_nightly { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable + }, + ); + } else { + suggest_parens(&mut err); } err.emit(); }; diff --git a/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr index e96b67da336..6823a426823 100644 --- a/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr +++ b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr @@ -19,6 +19,11 @@ help: try surrounding the expression in parentheses | LL | (vec![1, 2, 3]: Vec)[0]; | + + +help: alternatively, remove the type ascription + | +LL - vec![1, 2, 3]: Vec[0]; +LL + vec![1, 2, 3][0]; + | error: casts cannot be followed by indexing --> $DIR/issue-35813-postfix-after-cast.rs:17:5 @@ -41,6 +46,11 @@ help: try surrounding the expression in parentheses | LL | ((&[0i32]): &[i32; 1])[0]; | + + +help: alternatively, remove the type ascription + | +LL - (&[0i32]): &[i32; 1][0]; +LL + (&[0i32])[0]; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:39:13 @@ -52,6 +62,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0i32: i32: i32).count_ones(); | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32: i32.count_ones(); +LL + let _ = 0i32: i32.count_ones(); + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:41:13 @@ -63,6 +78,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0 as i32: i32).count_ones(); | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0 as i32: i32.count_ones(); +LL + let _ = 0 as i32.count_ones(); + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:43:13 @@ -107,6 +127,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0i32: i32).count_ones(): u32; | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32.count_ones(): u32; +LL + let _ = 0i32.count_ones(): u32; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:51:13 @@ -129,6 +154,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0i32: i32).count_ones() as u32; | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32.count_ones() as u32; +LL + let _ = 0i32.count_ones() as u32; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:55:13 @@ -151,6 +181,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0i32: i32: i32).count_ones() as u32 as i32; | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32: i32.count_ones() as u32 as i32; +LL + let _ = 0i32: i32.count_ones() as u32 as i32; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:62:13 @@ -198,6 +233,11 @@ help: try surrounding the expression in parentheses | LL | (0: i32).max(0); | + + +help: alternatively, remove the type ascription + | +LL - 0: i32.max(0); +LL + 0.max(0); + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:92:8 @@ -220,6 +260,11 @@ help: try surrounding the expression in parentheses | LL | if (5u64: u64).max(0) == 0 { | + + +help: alternatively, remove the type ascription + | +LL - if 5u64: u64.max(0) == 0 { +LL + if 5u64.max(0) == 0 { + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:102:9 @@ -242,6 +287,11 @@ help: try surrounding the expression in parentheses | LL | (5u64: u64).max(0) == 0 | + + +help: alternatively, remove the type ascription + | +LL - 5u64: u64.max(0) == 0 +LL + 5u64.max(0) == 0 + | error: casts cannot be followed by indexing --> $DIR/issue-35813-postfix-after-cast.rs:111:24 @@ -264,6 +314,11 @@ help: try surrounding the expression in parentheses | LL | static bar2: &[i32] = &((&[1i32,2,3]: &[i32; 3])[0..1]); | + + +help: alternatively, remove the type ascription + | +LL - static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); +LL + static bar2: &[i32] = &(&[1i32,2,3][0..1]); + | error: casts cannot be followed by `?` --> $DIR/issue-35813-postfix-after-cast.rs:119:5 @@ -286,6 +341,11 @@ help: try surrounding the expression in parentheses | LL | (Err(0u64): Result)?; | + + +help: alternatively, remove the type ascription + | +LL - Err(0u64): Result?; +LL + Err(0u64)?; + | error: casts cannot be followed by a function call --> $DIR/issue-35813-postfix-after-cast.rs:145:5 @@ -308,6 +368,11 @@ help: try surrounding the expression in parentheses | LL | (drop_ptr: fn(u8))(0); | + + +help: alternatively, remove the type ascription + | +LL - drop_ptr: fn(u8)(0); +LL + drop_ptr(0); + | error: casts cannot be followed by `.await` --> $DIR/issue-35813-postfix-after-cast.rs:152:5 @@ -330,6 +395,11 @@ help: try surrounding the expression in parentheses | LL | (Box::pin(noop()): Pin>).await; | + + +help: alternatively, remove the type ascription + | +LL - Box::pin(noop()): Pin>.await; +LL + Box::pin(noop()).await; + | error: casts cannot be followed by a field access --> $DIR/issue-35813-postfix-after-cast.rs:167:5 @@ -352,6 +422,11 @@ help: try surrounding the expression in parentheses | LL | (Foo::default(): Foo).bar; | + + +help: alternatively, remove the type ascription + | +LL - Foo::default(): Foo.bar; +LL + Foo::default().bar; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:84:9 @@ -374,6 +449,11 @@ help: try surrounding the expression in parentheses | LL | (if true { 33 } else { 44 }: i32).max(0) | + + +help: alternatively, remove the type ascription + | +LL - if true { 33 } else { 44 }: i32.max(0) +LL + if true { 33 } else { 44 }.max(0) + | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-35813-postfix-after-cast.rs:131:13