From 3516a16eebc93c2ebcf049ce9bb83748f365a57d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 18 Mar 2022 20:45:15 -0700 Subject: suggest removing type ascription in bad position --- compiler/rustc_parse/src/parser/expr.rs | 41 ++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-) (limited to 'compiler/rustc_parse/src/parser') 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(); }; -- cgit 1.4.1-3-g733a5