about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs39
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs8
2 files changed, 30 insertions, 17 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 4121a759c37..19d6de09dae 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -27,7 +27,7 @@ use std::mem::take;
 use tracing::{debug, trace};
 
 const TURBOFISH_SUGGESTION_STR: &str =
-    "use `::<...>` instead of `<...>` to specify type or const arguments";
+    "use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments";
 
 /// Creates a placeholder argument.
 pub(super) fn dummy_arg(ident: Ident) -> Param {
@@ -731,21 +731,28 @@ impl<'a> Parser<'a> {
                     match x {
                         Ok((_, _, false)) => {
                             if self.eat(&token::Gt) {
-                                match self.parse_expr() {
-                                    Ok(_) => {
-                                        e.span_suggestion_verbose(
-                                            binop.span.shrink_to_lo(),
-                                            TURBOFISH_SUGGESTION_STR,
-                                            "::".to_string(),
-                                            Applicability::MaybeIncorrect,
-                                        );
-                                        e.emit();
-                                        *expr =
-                                            self.mk_expr_err(expr.span.to(self.prev_token.span));
-                                        return Ok(());
-                                    }
-                                    Err(mut err) => {
-                                        err.cancel();
+                                let turbo_err = e.span_suggestion_verbose(
+                                    binop.span.shrink_to_lo(),
+                                    TURBOFISH_SUGGESTION_STR,
+                                    "::".to_string(),
+                                    Applicability::MaybeIncorrect,
+                                );
+                                if self.check(&TokenKind::Semi) {
+                                    turbo_err.emit();
+                                    *expr = self.mk_expr_err(expr.span);
+                                    return Ok(());
+                                } else {
+                                    match self.parse_expr() {
+                                        Ok(_) => {
+                                            turbo_err.emit();
+                                            *expr = self
+                                                .mk_expr_err(expr.span.to(self.prev_token.span));
+                                            return Ok(());
+                                        }
+                                        Err(mut err) => {
+                                            turbo_err.cancel();
+                                            err.cancel();
+                                        }
                                     }
                                 }
                             }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index f706a98a4fc..6991670f800 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1443,7 +1443,7 @@ impl<'a> Parser<'a> {
         &mut self,
         label: Label,
         attrs: AttrVec,
-        consume_colon: bool,
+        mut consume_colon: bool,
     ) -> PResult<'a, P<Expr>> {
         let lo = label.ident.span;
         let label = Some(label);
@@ -1456,6 +1456,12 @@ impl<'a> Parser<'a> {
             self.parse_loop_expr(label, lo, attrs)
         } else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() {
             self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
+        } else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) {
+            // We're probably inside of a `Path<'a>` that needs a turbofish, so suppress the
+            // "must be followed by a colon" error.
+            self.diagnostic().delay_span_bug(lo, "this label wasn't parsed correctly");
+            consume_colon = false;
+            Ok(self.mk_expr_err(lo))
         } else {
             let msg = "expected `while`, `for`, `loop` or `{` after a label";
             self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();