]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/parser/diagnostics.rs
Rollup merge of #94989 - compiler-errors:stream-alias, r=Dylan-DPC
[rust.git] / compiler / rustc_parse / src / parser / diagnostics.rs
1 use super::pat::Expected;
2 use super::ty::{AllowPlus, RecoverQuestionMark};
3 use super::{
4     BlockMode, CommaRecoveryMode, Parser, PathStyle, RecoverColon, RecoverComma, Restrictions,
5     SemiColonMode, SeqSep, TokenExpectType, TokenType,
6 };
7
8 use crate::lexer::UnmatchedBrace;
9 use rustc_ast as ast;
10 use rustc_ast::ptr::P;
11 use rustc_ast::token::{self, Lit, LitKind, TokenKind};
12 use rustc_ast::util::parser::AssocOp;
13 use rustc_ast::{
14     AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block,
15     BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Mutability, Param, Pat,
16     PatKind, Path, PathSegment, QSelf, Ty, TyKind,
17 };
18 use rustc_ast_pretty::pprust;
19 use rustc_data_structures::fx::FxHashSet;
20 use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
21 use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult};
22 use rustc_span::source_map::Spanned;
23 use rustc_span::symbol::{kw, Ident};
24 use rustc_span::{MultiSpan, Span, SpanSnippetError, DUMMY_SP};
25 use std::ops::{Deref, DerefMut};
26
27 use std::mem::take;
28
29 use tracing::{debug, trace};
30
31 const TURBOFISH_SUGGESTION_STR: &str =
32     "use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments";
33
34 /// Creates a placeholder argument.
35 pub(super) fn dummy_arg(ident: Ident) -> Param {
36     let pat = P(Pat {
37         id: ast::DUMMY_NODE_ID,
38         kind: PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None),
39         span: ident.span,
40         tokens: None,
41     });
42     let ty = Ty { kind: TyKind::Err, span: ident.span, id: ast::DUMMY_NODE_ID, tokens: None };
43     Param {
44         attrs: AttrVec::default(),
45         id: ast::DUMMY_NODE_ID,
46         pat,
47         span: ident.span,
48         ty: P(ty),
49         is_placeholder: false,
50     }
51 }
52
53 pub enum Error {
54     UselessDocComment,
55 }
56
57 impl Error {
58     fn span_err(
59         self,
60         sp: impl Into<MultiSpan>,
61         handler: &Handler,
62     ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
63         match self {
64             Error::UselessDocComment => {
65                 let mut err = struct_span_err!(
66                     handler,
67                     sp,
68                     E0585,
69                     "found a documentation comment that doesn't document anything",
70                 );
71                 err.help(
72                     "doc comments must come before what they document, maybe a comment was \
73                           intended with `//`?",
74                 );
75                 err
76             }
77         }
78     }
79 }
80
81 pub(super) trait RecoverQPath: Sized + 'static {
82     const PATH_STYLE: PathStyle = PathStyle::Expr;
83     fn to_ty(&self) -> Option<P<Ty>>;
84     fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self;
85 }
86
87 impl RecoverQPath for Ty {
88     const PATH_STYLE: PathStyle = PathStyle::Type;
89     fn to_ty(&self) -> Option<P<Ty>> {
90         Some(P(self.clone()))
91     }
92     fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
93         Self {
94             span: path.span,
95             kind: TyKind::Path(qself, path),
96             id: ast::DUMMY_NODE_ID,
97             tokens: None,
98         }
99     }
100 }
101
102 impl RecoverQPath for Pat {
103     fn to_ty(&self) -> Option<P<Ty>> {
104         self.to_ty()
105     }
106     fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
107         Self {
108             span: path.span,
109             kind: PatKind::Path(qself, path),
110             id: ast::DUMMY_NODE_ID,
111             tokens: None,
112         }
113     }
114 }
115
116 impl RecoverQPath for Expr {
117     fn to_ty(&self) -> Option<P<Ty>> {
118         self.to_ty()
119     }
120     fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
121         Self {
122             span: path.span,
123             kind: ExprKind::Path(qself, path),
124             attrs: AttrVec::new(),
125             id: ast::DUMMY_NODE_ID,
126             tokens: None,
127         }
128     }
129 }
130
131 /// Control whether the closing delimiter should be consumed when calling `Parser::consume_block`.
132 crate enum ConsumeClosingDelim {
133     Yes,
134     No,
135 }
136
137 #[derive(Clone, Copy)]
138 pub enum AttemptLocalParseRecovery {
139     Yes,
140     No,
141 }
142
143 impl AttemptLocalParseRecovery {
144     pub fn yes(&self) -> bool {
145         match self {
146             AttemptLocalParseRecovery::Yes => true,
147             AttemptLocalParseRecovery::No => false,
148         }
149     }
150
151     pub fn no(&self) -> bool {
152         match self {
153             AttemptLocalParseRecovery::Yes => false,
154             AttemptLocalParseRecovery::No => true,
155         }
156     }
157 }
158
159 // SnapshotParser is used to create a snapshot of the parser
160 // without causing duplicate errors being emitted when the `Parser`
161 // is dropped.
162 pub(super) struct SnapshotParser<'a> {
163     parser: Parser<'a>,
164     unclosed_delims: Vec<UnmatchedBrace>,
165 }
166
167 impl<'a> Deref for SnapshotParser<'a> {
168     type Target = Parser<'a>;
169
170     fn deref(&self) -> &Self::Target {
171         &self.parser
172     }
173 }
174
175 impl<'a> DerefMut for SnapshotParser<'a> {
176     fn deref_mut(&mut self) -> &mut Self::Target {
177         &mut self.parser
178     }
179 }
180
181 impl<'a> Parser<'a> {
182     pub(super) fn span_err<S: Into<MultiSpan>>(
183         &self,
184         sp: S,
185         err: Error,
186     ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
187         err.span_err(sp, self.diagnostic())
188     }
189
190     pub fn struct_span_err<S: Into<MultiSpan>>(
191         &self,
192         sp: S,
193         m: &str,
194     ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
195         self.sess.span_diagnostic.struct_span_err(sp, m)
196     }
197
198     pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
199         self.sess.span_diagnostic.span_bug(sp, m)
200     }
201
202     pub(super) fn diagnostic(&self) -> &'a Handler {
203         &self.sess.span_diagnostic
204     }
205
206     /// Relace `self` with `snapshot.parser` and extend `unclosed_delims` with `snapshot.unclosed_delims`.
207     /// This is to avoid losing unclosed delims errors `create_snapshot_for_diagnostic` clears.
208     pub(super) fn restore_snapshot(&mut self, snapshot: SnapshotParser<'a>) {
209         *self = snapshot.parser;
210         self.unclosed_delims.extend(snapshot.unclosed_delims.clone());
211     }
212
213     /// Create a snapshot of the `Parser`.
214     pub(super) fn create_snapshot_for_diagnostic(&self) -> SnapshotParser<'a> {
215         let mut snapshot = self.clone();
216         let unclosed_delims = self.unclosed_delims.clone();
217         // Clear `unclosed_delims` in snapshot to avoid
218         // duplicate errors being emitted when the `Parser`
219         // is dropped (which may or may not happen, depending
220         // if the parsing the snapshot is created for is successful)
221         snapshot.unclosed_delims.clear();
222         SnapshotParser { parser: snapshot, unclosed_delims }
223     }
224
225     pub(super) fn span_to_snippet(&self, span: Span) -> Result<String, SpanSnippetError> {
226         self.sess.source_map().span_to_snippet(span)
227     }
228
229     pub(super) fn expected_ident_found(&self) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
230         let mut err = self.struct_span_err(
231             self.token.span,
232             &format!("expected identifier, found {}", super::token_descr(&self.token)),
233         );
234         let valid_follow = &[
235             TokenKind::Eq,
236             TokenKind::Colon,
237             TokenKind::Comma,
238             TokenKind::Semi,
239             TokenKind::ModSep,
240             TokenKind::OpenDelim(token::DelimToken::Brace),
241             TokenKind::OpenDelim(token::DelimToken::Paren),
242             TokenKind::CloseDelim(token::DelimToken::Brace),
243             TokenKind::CloseDelim(token::DelimToken::Paren),
244         ];
245         match self.token.ident() {
246             Some((ident, false))
247                 if ident.is_raw_guess()
248                     && self.look_ahead(1, |t| valid_follow.contains(&t.kind)) =>
249             {
250                 err.span_suggestion_verbose(
251                     ident.span.shrink_to_lo(),
252                     &format!("escape `{}` to use it as an identifier", ident.name),
253                     "r#".to_owned(),
254                     Applicability::MaybeIncorrect,
255                 );
256             }
257             _ => {}
258         }
259         if let Some(token_descr) = super::token_descr_opt(&self.token) {
260             err.span_label(self.token.span, format!("expected identifier, found {}", token_descr));
261         } else {
262             err.span_label(self.token.span, "expected identifier");
263             if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
264                 err.span_suggestion(
265                     self.token.span,
266                     "remove this comma",
267                     String::new(),
268                     Applicability::MachineApplicable,
269                 );
270             }
271         }
272         err
273     }
274
275     pub(super) fn expected_one_of_not_found(
276         &mut self,
277         edible: &[TokenKind],
278         inedible: &[TokenKind],
279     ) -> PResult<'a, bool /* recovered */> {
280         debug!("expected_one_of_not_found(edible: {:?}, inedible: {:?})", edible, inedible);
281         fn tokens_to_string(tokens: &[TokenType]) -> String {
282             let mut i = tokens.iter();
283             // This might be a sign we need a connect method on `Iterator`.
284             let b = i.next().map_or_else(String::new, |t| t.to_string());
285             i.enumerate().fold(b, |mut b, (i, a)| {
286                 if tokens.len() > 2 && i == tokens.len() - 2 {
287                     b.push_str(", or ");
288                 } else if tokens.len() == 2 && i == tokens.len() - 2 {
289                     b.push_str(" or ");
290                 } else {
291                     b.push_str(", ");
292                 }
293                 b.push_str(&a.to_string());
294                 b
295             })
296         }
297
298         let mut expected = edible
299             .iter()
300             .map(|x| TokenType::Token(x.clone()))
301             .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
302             .chain(self.expected_tokens.iter().cloned())
303             .collect::<Vec<_>>();
304         expected.sort_by_cached_key(|x| x.to_string());
305         expected.dedup();
306
307         let sm = self.sess.source_map();
308         let msg = format!("expected `;`, found {}", super::token_descr(&self.token));
309         let appl = Applicability::MachineApplicable;
310         if expected.contains(&TokenType::Token(token::Semi)) {
311             if self.token.span == DUMMY_SP || self.prev_token.span == DUMMY_SP {
312                 // Likely inside a macro, can't provide meaningful suggestions.
313             } else if !sm.is_multiline(self.prev_token.span.until(self.token.span)) {
314                 // The current token is in the same line as the prior token, not recoverable.
315             } else if [token::Comma, token::Colon].contains(&self.token.kind)
316                 && self.prev_token.kind == token::CloseDelim(token::Paren)
317             {
318                 // Likely typo: The current token is on a new line and is expected to be
319                 // `.`, `;`, `?`, or an operator after a close delimiter token.
320                 //
321                 // let a = std::process::Command::new("echo")
322                 //         .arg("1")
323                 //         ,arg("2")
324                 //         ^
325                 // https://github.com/rust-lang/rust/issues/72253
326             } else if self.look_ahead(1, |t| {
327                 t == &token::CloseDelim(token::Brace)
328                     || t.can_begin_expr() && t.kind != token::Colon
329             }) && [token::Comma, token::Colon].contains(&self.token.kind)
330             {
331                 // Likely typo: `,` â†’ `;` or `:` â†’ `;`. This is triggered if the current token is
332                 // either `,` or `:`, and the next token could either start a new statement or is a
333                 // block close. For example:
334                 //
335                 //   let x = 32:
336                 //   let y = 42;
337                 self.bump();
338                 let sp = self.prev_token.span;
339                 self.struct_span_err(sp, &msg)
340                     .span_suggestion_short(sp, "change this to `;`", ";".to_string(), appl)
341                     .emit();
342                 return Ok(true);
343             } else if self.look_ahead(0, |t| {
344                 t == &token::CloseDelim(token::Brace)
345                     || (
346                         t.can_begin_expr() && t != &token::Semi && t != &token::Pound
347                         // Avoid triggering with too many trailing `#` in raw string.
348                     )
349             }) {
350                 // Missing semicolon typo. This is triggered if the next token could either start a
351                 // new statement or is a block close. For example:
352                 //
353                 //   let x = 32
354                 //   let y = 42;
355                 let sp = self.prev_token.span.shrink_to_hi();
356                 self.struct_span_err(sp, &msg)
357                     .span_label(self.token.span, "unexpected token")
358                     .span_suggestion_short(sp, "add `;` here", ";".to_string(), appl)
359                     .emit();
360                 return Ok(true);
361             }
362         }
363
364         let expect = tokens_to_string(&expected);
365         let actual = super::token_descr(&self.token);
366         let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
367             let short_expect = if expected.len() > 6 {
368                 format!("{} possible tokens", expected.len())
369             } else {
370                 expect.clone()
371             };
372             (
373                 format!("expected one of {expect}, found {actual}"),
374                 (self.prev_token.span.shrink_to_hi(), format!("expected one of {short_expect}")),
375             )
376         } else if expected.is_empty() {
377             (
378                 format!("unexpected token: {}", actual),
379                 (self.prev_token.span, "unexpected token after this".to_string()),
380             )
381         } else {
382             (
383                 format!("expected {expect}, found {actual}"),
384                 (self.prev_token.span.shrink_to_hi(), format!("expected {expect}")),
385             )
386         };
387         self.last_unexpected_token_span = Some(self.token.span);
388         let mut err = self.struct_span_err(self.token.span, &msg_exp);
389
390         // Add suggestion for a missing closing angle bracket if '>' is included in expected_tokens
391         // there are unclosed angle brackets
392         if self.unmatched_angle_bracket_count > 0
393             && self.token.kind == TokenKind::Eq
394             && expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Gt)))
395         {
396             err.span_label(self.prev_token.span, "maybe try to close unmatched angle bracket");
397         }
398
399         let sp = if self.token == token::Eof {
400             // This is EOF; don't want to point at the following char, but rather the last token.
401             self.prev_token.span
402         } else {
403             label_sp
404         };
405         match self.recover_closing_delimiter(
406             &expected
407                 .iter()
408                 .filter_map(|tt| match tt {
409                     TokenType::Token(t) => Some(t.clone()),
410                     _ => None,
411                 })
412                 .collect::<Vec<_>>(),
413             err,
414         ) {
415             Err(e) => err = e,
416             Ok(recovered) => {
417                 return Ok(recovered);
418             }
419         }
420
421         if self.check_too_many_raw_str_terminators(&mut err) {
422             return Err(err);
423         }
424
425         if self.prev_token.span == DUMMY_SP {
426             // Account for macro context where the previous span might not be
427             // available to avoid incorrect output (#54841).
428             err.span_label(self.token.span, label_exp);
429         } else if !sm.is_multiline(self.token.span.shrink_to_hi().until(sp.shrink_to_lo())) {
430             // When the spans are in the same line, it means that the only content between
431             // them is whitespace, point at the found token in that case:
432             //
433             // X |     () => { syntax error };
434             //   |                    ^^^^^ expected one of 8 possible tokens here
435             //
436             // instead of having:
437             //
438             // X |     () => { syntax error };
439             //   |                   -^^^^^ unexpected token
440             //   |                   |
441             //   |                   expected one of 8 possible tokens here
442             err.span_label(self.token.span, label_exp);
443         } else {
444             err.span_label(sp, label_exp);
445             err.span_label(self.token.span, "unexpected token");
446         }
447         self.maybe_annotate_with_ascription(&mut err, false);
448         Err(err)
449     }
450
451     fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool {
452         match (&self.prev_token.kind, &self.token.kind) {
453             (
454                 TokenKind::Literal(Lit {
455                     kind: LitKind::StrRaw(n_hashes) | LitKind::ByteStrRaw(n_hashes),
456                     ..
457                 }),
458                 TokenKind::Pound,
459             ) => {
460                 err.set_primary_message("too many `#` when terminating raw string");
461                 err.span_suggestion(
462                     self.token.span,
463                     "remove the extra `#`",
464                     String::new(),
465                     Applicability::MachineApplicable,
466                 );
467                 err.note(&format!("the raw string started with {n_hashes} `#`s"));
468                 true
469             }
470             _ => false,
471         }
472     }
473
474     pub fn maybe_suggest_struct_literal(
475         &mut self,
476         lo: Span,
477         s: BlockCheckMode,
478     ) -> Option<PResult<'a, P<Block>>> {
479         if self.token.is_ident() && self.look_ahead(1, |t| t == &token::Colon) {
480             // We might be having a struct literal where people forgot to include the path:
481             // fn foo() -> Foo {
482             //     field: value,
483             // }
484             let mut snapshot = self.create_snapshot_for_diagnostic();
485             let path =
486                 Path { segments: vec![], span: self.prev_token.span.shrink_to_lo(), tokens: None };
487             let struct_expr = snapshot.parse_struct_expr(None, path, AttrVec::new(), false);
488             let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No);
489             return Some(match (struct_expr, block_tail) {
490                 (Ok(expr), Err(mut err)) => {
491                     // We have encountered the following:
492                     // fn foo() -> Foo {
493                     //     field: value,
494                     // }
495                     // Suggest:
496                     // fn foo() -> Foo { Path {
497                     //     field: value,
498                     // } }
499                     err.delay_as_bug();
500                     self.struct_span_err(expr.span, "struct literal body without path")
501                         .multipart_suggestion(
502                             "you might have forgotten to add the struct literal inside the block",
503                             vec![
504                                 (expr.span.shrink_to_lo(), "{ SomeStruct ".to_string()),
505                                 (expr.span.shrink_to_hi(), " }".to_string()),
506                             ],
507                             Applicability::MaybeIncorrect,
508                         )
509                         .emit();
510                     self.restore_snapshot(snapshot);
511                     let mut tail = self.mk_block(
512                         vec![self.mk_stmt_err(expr.span)],
513                         s,
514                         lo.to(self.prev_token.span),
515                     );
516                     tail.could_be_bare_literal = true;
517                     Ok(tail)
518                 }
519                 (Err(err), Ok(tail)) => {
520                     // We have a block tail that contains a somehow valid type ascription expr.
521                     err.cancel();
522                     Ok(tail)
523                 }
524                 (Err(snapshot_err), Err(err)) => {
525                     // We don't know what went wrong, emit the normal error.
526                     snapshot_err.cancel();
527                     self.consume_block(token::Brace, ConsumeClosingDelim::Yes);
528                     Err(err)
529                 }
530                 (Ok(_), Ok(mut tail)) => {
531                     tail.could_be_bare_literal = true;
532                     Ok(tail)
533                 }
534             });
535         }
536         None
537     }
538
539     pub fn maybe_annotate_with_ascription(
540         &mut self,
541         err: &mut Diagnostic,
542         maybe_expected_semicolon: bool,
543     ) {
544         if let Some((sp, likely_path)) = self.last_type_ascription.take() {
545             let sm = self.sess.source_map();
546             let next_pos = sm.lookup_char_pos(self.token.span.lo());
547             let op_pos = sm.lookup_char_pos(sp.hi());
548
549             let allow_unstable = self.sess.unstable_features.is_nightly_build();
550
551             if likely_path {
552                 err.span_suggestion(
553                     sp,
554                     "maybe write a path separator here",
555                     "::".to_string(),
556                     if allow_unstable {
557                         Applicability::MaybeIncorrect
558                     } else {
559                         Applicability::MachineApplicable
560                     },
561                 );
562                 self.sess.type_ascription_path_suggestions.borrow_mut().insert(sp);
563             } else if op_pos.line != next_pos.line && maybe_expected_semicolon {
564                 err.span_suggestion(
565                     sp,
566                     "try using a semicolon",
567                     ";".to_string(),
568                     Applicability::MaybeIncorrect,
569                 );
570             } else if allow_unstable {
571                 err.span_label(sp, "tried to parse a type due to this type ascription");
572             } else {
573                 err.span_label(sp, "tried to parse a type due to this");
574             }
575             if allow_unstable {
576                 // Give extra information about type ascription only if it's a nightly compiler.
577                 err.note(
578                     "`#![feature(type_ascription)]` lets you annotate an expression with a type: \
579                      `<expr>: <type>`",
580                 );
581                 if !likely_path {
582                     // Avoid giving too much info when it was likely an unrelated typo.
583                     err.note(
584                         "see issue #23416 <https://github.com/rust-lang/rust/issues/23416> \
585                         for more information",
586                     );
587                 }
588             }
589         }
590     }
591
592     /// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
593     /// passes through any errors encountered. Used for error recovery.
594     pub(super) fn eat_to_tokens(&mut self, kets: &[&TokenKind]) {
595         if let Err(err) =
596             self.parse_seq_to_before_tokens(kets, SeqSep::none(), TokenExpectType::Expect, |p| {
597                 Ok(p.parse_token_tree())
598             })
599         {
600             err.cancel();
601         }
602     }
603
604     /// This function checks if there are trailing angle brackets and produces
605     /// a diagnostic to suggest removing them.
606     ///
607     /// ```ignore (diagnostic)
608     /// let _ = [1, 2, 3].into_iter().collect::<Vec<usize>>>>();
609     ///                                                    ^^ help: remove extra angle brackets
610     /// ```
611     ///
612     /// If `true` is returned, then trailing brackets were recovered, tokens were consumed
613     /// up until one of the tokens in 'end' was encountered, and an error was emitted.
614     pub(super) fn check_trailing_angle_brackets(
615         &mut self,
616         segment: &PathSegment,
617         end: &[&TokenKind],
618     ) -> bool {
619         // This function is intended to be invoked after parsing a path segment where there are two
620         // cases:
621         //
622         // 1. A specific token is expected after the path segment.
623         //    eg. `x.foo(`, `x.foo::<u32>(` (parenthesis - method call),
624         //        `Foo::`, or `Foo::<Bar>::` (mod sep - continued path).
625         // 2. No specific token is expected after the path segment.
626         //    eg. `x.foo` (field access)
627         //
628         // This function is called after parsing `.foo` and before parsing the token `end` (if
629         // present). This includes any angle bracket arguments, such as `.foo::<u32>` or
630         // `Foo::<Bar>`.
631
632         // We only care about trailing angle brackets if we previously parsed angle bracket
633         // arguments. This helps stop us incorrectly suggesting that extra angle brackets be
634         // removed in this case:
635         //
636         // `x.foo >> (3)` (where `x.foo` is a `u32` for example)
637         //
638         // This case is particularly tricky as we won't notice it just looking at the tokens -
639         // it will appear the same (in terms of upcoming tokens) as below (since the `::<u32>` will
640         // have already been parsed):
641         //
642         // `x.foo::<u32>>>(3)`
643         let parsed_angle_bracket_args =
644             segment.args.as_ref().map_or(false, |args| args.is_angle_bracketed());
645
646         debug!(
647             "check_trailing_angle_brackets: parsed_angle_bracket_args={:?}",
648             parsed_angle_bracket_args,
649         );
650         if !parsed_angle_bracket_args {
651             return false;
652         }
653
654         // Keep the span at the start so we can highlight the sequence of `>` characters to be
655         // removed.
656         let lo = self.token.span;
657
658         // We need to look-ahead to see if we have `>` characters without moving the cursor forward
659         // (since we might have the field access case and the characters we're eating are
660         // actual operators and not trailing characters - ie `x.foo >> 3`).
661         let mut position = 0;
662
663         // We can encounter `>` or `>>` tokens in any order, so we need to keep track of how
664         // many of each (so we can correctly pluralize our error messages) and continue to
665         // advance.
666         let mut number_of_shr = 0;
667         let mut number_of_gt = 0;
668         while self.look_ahead(position, |t| {
669             trace!("check_trailing_angle_brackets: t={:?}", t);
670             if *t == token::BinOp(token::BinOpToken::Shr) {
671                 number_of_shr += 1;
672                 true
673             } else if *t == token::Gt {
674                 number_of_gt += 1;
675                 true
676             } else {
677                 false
678             }
679         }) {
680             position += 1;
681         }
682
683         // If we didn't find any trailing `>` characters, then we have nothing to error about.
684         debug!(
685             "check_trailing_angle_brackets: number_of_gt={:?} number_of_shr={:?}",
686             number_of_gt, number_of_shr,
687         );
688         if number_of_gt < 1 && number_of_shr < 1 {
689             return false;
690         }
691
692         // Finally, double check that we have our end token as otherwise this is the
693         // second case.
694         if self.look_ahead(position, |t| {
695             trace!("check_trailing_angle_brackets: t={:?}", t);
696             end.contains(&&t.kind)
697         }) {
698             // Eat from where we started until the end token so that parsing can continue
699             // as if we didn't have those extra angle brackets.
700             self.eat_to_tokens(end);
701             let span = lo.until(self.token.span);
702
703             let total_num_of_gt = number_of_gt + number_of_shr * 2;
704             self.struct_span_err(
705                 span,
706                 &format!("unmatched angle bracket{}", pluralize!(total_num_of_gt)),
707             )
708             .span_suggestion(
709                 span,
710                 &format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)),
711                 String::new(),
712                 Applicability::MachineApplicable,
713             )
714             .emit();
715             return true;
716         }
717         false
718     }
719
720     /// Check if a method call with an intended turbofish has been written without surrounding
721     /// angle brackets.
722     pub(super) fn check_turbofish_missing_angle_brackets(&mut self, segment: &mut PathSegment) {
723         if token::ModSep == self.token.kind && segment.args.is_none() {
724             let snapshot = self.create_snapshot_for_diagnostic();
725             self.bump();
726             let lo = self.token.span;
727             match self.parse_angle_args(None) {
728                 Ok(args) => {
729                     let span = lo.to(self.prev_token.span);
730                     // Detect trailing `>` like in `x.collect::Vec<_>>()`.
731                     let mut trailing_span = self.prev_token.span.shrink_to_hi();
732                     while self.token.kind == token::BinOp(token::Shr)
733                         || self.token.kind == token::Gt
734                     {
735                         trailing_span = trailing_span.to(self.token.span);
736                         self.bump();
737                     }
738                     if self.token.kind == token::OpenDelim(token::Paren) {
739                         // Recover from bad turbofish: `foo.collect::Vec<_>()`.
740                         let args = AngleBracketedArgs { args, span }.into();
741                         segment.args = args;
742
743                         self.struct_span_err(
744                             span,
745                             "generic parameters without surrounding angle brackets",
746                         )
747                         .multipart_suggestion(
748                             "surround the type parameters with angle brackets",
749                             vec![
750                                 (span.shrink_to_lo(), "<".to_string()),
751                                 (trailing_span, ">".to_string()),
752                             ],
753                             Applicability::MachineApplicable,
754                         )
755                         .emit();
756                     } else {
757                         // This doesn't look like an invalid turbofish, can't recover parse state.
758                         self.restore_snapshot(snapshot);
759                     }
760                 }
761                 Err(err) => {
762                     // We couldn't parse generic parameters, unlikely to be a turbofish. Rely on
763                     // generic parse error instead.
764                     err.cancel();
765                     self.restore_snapshot(snapshot);
766                 }
767             }
768         }
769     }
770
771     /// When writing a turbofish with multiple type parameters missing the leading `::`, we will
772     /// encounter a parse error when encountering the first `,`.
773     pub(super) fn check_mistyped_turbofish_with_multiple_type_params(
774         &mut self,
775         mut e: DiagnosticBuilder<'a, ErrorGuaranteed>,
776         expr: &mut P<Expr>,
777     ) -> PResult<'a, ()> {
778         if let ExprKind::Binary(binop, _, _) = &expr.kind
779             && let ast::BinOpKind::Lt = binop.node
780             && self.eat(&token::Comma)
781         {
782             let x = self.parse_seq_to_before_end(
783                 &token::Gt,
784                 SeqSep::trailing_allowed(token::Comma),
785                 |p| p.parse_generic_arg(None),
786             );
787             match x {
788                 Ok((_, _, false)) => {
789                     if self.eat(&token::Gt) {
790                         e.span_suggestion_verbose(
791                             binop.span.shrink_to_lo(),
792                             TURBOFISH_SUGGESTION_STR,
793                             "::".to_string(),
794                             Applicability::MaybeIncorrect,
795                         )
796                         .emit();
797                         match self.parse_expr() {
798                             Ok(_) => {
799                                 *expr =
800                                     self.mk_expr_err(expr.span.to(self.prev_token.span));
801                                 return Ok(());
802                             }
803                             Err(err) => {
804                                 *expr = self.mk_expr_err(expr.span);
805                                 err.cancel();
806                             }
807                         }
808                     }
809                 }
810                 Err(err) => {
811                     err.cancel();
812                 }
813                 _ => {}
814             }
815         }
816         Err(e)
817     }
818
819     /// Check to see if a pair of chained operators looks like an attempt at chained comparison,
820     /// e.g. `1 < x <= 3`. If so, suggest either splitting the comparison into two, or
821     /// parenthesising the leftmost comparison.
822     fn attempt_chained_comparison_suggestion(
823         &mut self,
824         err: &mut Diagnostic,
825         inner_op: &Expr,
826         outer_op: &Spanned<AssocOp>,
827     ) -> bool /* advanced the cursor */ {
828         if let ExprKind::Binary(op, ref l1, ref r1) = inner_op.kind {
829             if let ExprKind::Field(_, ident) = l1.kind
830                 && ident.as_str().parse::<i32>().is_err()
831                 && !matches!(r1.kind, ExprKind::Lit(_))
832             {
833                 // The parser has encountered `foo.bar<baz`, the likelihood of the turbofish
834                 // suggestion being the only one to apply is high.
835                 return false;
836             }
837             let mut enclose = |left: Span, right: Span| {
838                 err.multipart_suggestion(
839                     "parenthesize the comparison",
840                     vec![
841                         (left.shrink_to_lo(), "(".to_string()),
842                         (right.shrink_to_hi(), ")".to_string()),
843                     ],
844                     Applicability::MaybeIncorrect,
845                 );
846             };
847             return match (op.node, &outer_op.node) {
848                 // `x == y == z`
849                 (BinOpKind::Eq, AssocOp::Equal) |
850                 // `x < y < z` and friends.
851                 (BinOpKind::Lt, AssocOp::Less | AssocOp::LessEqual) |
852                 (BinOpKind::Le, AssocOp::LessEqual | AssocOp::Less) |
853                 // `x > y > z` and friends.
854                 (BinOpKind::Gt, AssocOp::Greater | AssocOp::GreaterEqual) |
855                 (BinOpKind::Ge, AssocOp::GreaterEqual | AssocOp::Greater) => {
856                     let expr_to_str = |e: &Expr| {
857                         self.span_to_snippet(e.span)
858                             .unwrap_or_else(|_| pprust::expr_to_string(&e))
859                     };
860                     err.span_suggestion_verbose(
861                         inner_op.span.shrink_to_hi(),
862                         "split the comparison into two",
863                         format!(" && {}", expr_to_str(&r1)),
864                         Applicability::MaybeIncorrect,
865                     );
866                     false // Keep the current parse behavior, where the AST is `(x < y) < z`.
867                 }
868                 // `x == y < z`
869                 (BinOpKind::Eq, AssocOp::Less | AssocOp::LessEqual | AssocOp::Greater | AssocOp::GreaterEqual) => {
870                     // Consume `z`/outer-op-rhs.
871                     let snapshot = self.create_snapshot_for_diagnostic();
872                     match self.parse_expr() {
873                         Ok(r2) => {
874                             // We are sure that outer-op-rhs could be consumed, the suggestion is
875                             // likely correct.
876                             enclose(r1.span, r2.span);
877                             true
878                         }
879                         Err(expr_err) => {
880                             expr_err.cancel();
881                             self.restore_snapshot(snapshot);
882                             false
883                         }
884                     }
885                 }
886                 // `x > y == z`
887                 (BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge, AssocOp::Equal) => {
888                     let snapshot = self.create_snapshot_for_diagnostic();
889                     // At this point it is always valid to enclose the lhs in parentheses, no
890                     // further checks are necessary.
891                     match self.parse_expr() {
892                         Ok(_) => {
893                             enclose(l1.span, r1.span);
894                             true
895                         }
896                         Err(expr_err) => {
897                             expr_err.cancel();
898                             self.restore_snapshot(snapshot);
899                             false
900                         }
901                     }
902                 }
903                 _ => false,
904             };
905         }
906         false
907     }
908
909     /// Produces an error if comparison operators are chained (RFC #558).
910     /// We only need to check the LHS, not the RHS, because all comparison ops have same
911     /// precedence (see `fn precedence`) and are left-associative (see `fn fixity`).
912     ///
913     /// This can also be hit if someone incorrectly writes `foo<bar>()` when they should have used
914     /// the turbofish (`foo::<bar>()`) syntax. We attempt some heuristic recovery if that is the
915     /// case.
916     ///
917     /// Keep in mind that given that `outer_op.is_comparison()` holds and comparison ops are left
918     /// associative we can infer that we have:
919     ///
920     /// ```text
921     ///           outer_op
922     ///           /   \
923     ///     inner_op   r2
924     ///        /  \
925     ///      l1    r1
926     /// ```
927     pub(super) fn check_no_chained_comparison(
928         &mut self,
929         inner_op: &Expr,
930         outer_op: &Spanned<AssocOp>,
931     ) -> PResult<'a, Option<P<Expr>>> {
932         debug_assert!(
933             outer_op.node.is_comparison(),
934             "check_no_chained_comparison: {:?} is not comparison",
935             outer_op.node,
936         );
937
938         let mk_err_expr =
939             |this: &Self, span| Ok(Some(this.mk_expr(span, ExprKind::Err, AttrVec::new())));
940
941         match inner_op.kind {
942             ExprKind::Binary(op, ref l1, ref r1) if op.node.is_comparison() => {
943                 let mut err = self.struct_span_err(
944                     vec![op.span, self.prev_token.span],
945                     "comparison operators cannot be chained",
946                 );
947
948                 let suggest = |err: &mut Diagnostic| {
949                     err.span_suggestion_verbose(
950                         op.span.shrink_to_lo(),
951                         TURBOFISH_SUGGESTION_STR,
952                         "::".to_string(),
953                         Applicability::MaybeIncorrect,
954                     );
955                 };
956
957                 // Include `<` to provide this recommendation even in a case like
958                 // `Foo<Bar<Baz<Qux, ()>>>`
959                 if op.node == BinOpKind::Lt && outer_op.node == AssocOp::Less
960                     || outer_op.node == AssocOp::Greater
961                 {
962                     if outer_op.node == AssocOp::Less {
963                         let snapshot = self.create_snapshot_for_diagnostic();
964                         self.bump();
965                         // So far we have parsed `foo<bar<`, consume the rest of the type args.
966                         let modifiers =
967                             [(token::Lt, 1), (token::Gt, -1), (token::BinOp(token::Shr), -2)];
968                         self.consume_tts(1, &modifiers);
969
970                         if !&[token::OpenDelim(token::Paren), token::ModSep]
971                             .contains(&self.token.kind)
972                         {
973                             // We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the
974                             // parser and bail out.
975                             self.restore_snapshot(snapshot);
976                         }
977                     }
978                     return if token::ModSep == self.token.kind {
979                         // We have some certainty that this was a bad turbofish at this point.
980                         // `foo< bar >::`
981                         suggest(&mut err);
982
983                         let snapshot = self.create_snapshot_for_diagnostic();
984                         self.bump(); // `::`
985
986                         // Consume the rest of the likely `foo<bar>::new()` or return at `foo<bar>`.
987                         match self.parse_expr() {
988                             Ok(_) => {
989                                 // 99% certain that the suggestion is correct, continue parsing.
990                                 err.emit();
991                                 // FIXME: actually check that the two expressions in the binop are
992                                 // paths and resynthesize new fn call expression instead of using
993                                 // `ExprKind::Err` placeholder.
994                                 mk_err_expr(self, inner_op.span.to(self.prev_token.span))
995                             }
996                             Err(expr_err) => {
997                                 expr_err.cancel();
998                                 // Not entirely sure now, but we bubble the error up with the
999                                 // suggestion.
1000                                 self.restore_snapshot(snapshot);
1001                                 Err(err)
1002                             }
1003                         }
1004                     } else if token::OpenDelim(token::Paren) == self.token.kind {
1005                         // We have high certainty that this was a bad turbofish at this point.
1006                         // `foo< bar >(`
1007                         suggest(&mut err);
1008                         // Consume the fn call arguments.
1009                         match self.consume_fn_args() {
1010                             Err(()) => Err(err),
1011                             Ok(()) => {
1012                                 err.emit();
1013                                 // FIXME: actually check that the two expressions in the binop are
1014                                 // paths and resynthesize new fn call expression instead of using
1015                                 // `ExprKind::Err` placeholder.
1016                                 mk_err_expr(self, inner_op.span.to(self.prev_token.span))
1017                             }
1018                         }
1019                     } else {
1020                         if !matches!(l1.kind, ExprKind::Lit(_))
1021                             && !matches!(r1.kind, ExprKind::Lit(_))
1022                         {
1023                             // All we know is that this is `foo < bar >` and *nothing* else. Try to
1024                             // be helpful, but don't attempt to recover.
1025                             err.help(TURBOFISH_SUGGESTION_STR);
1026                             err.help("or use `(...)` if you meant to specify fn arguments");
1027                         }
1028
1029                         // If it looks like a genuine attempt to chain operators (as opposed to a
1030                         // misformatted turbofish, for instance), suggest a correct form.
1031                         if self.attempt_chained_comparison_suggestion(&mut err, inner_op, outer_op)
1032                         {
1033                             err.emit();
1034                             mk_err_expr(self, inner_op.span.to(self.prev_token.span))
1035                         } else {
1036                             // These cases cause too many knock-down errors, bail out (#61329).
1037                             Err(err)
1038                         }
1039                     };
1040                 }
1041                 let recover =
1042                     self.attempt_chained_comparison_suggestion(&mut err, inner_op, outer_op);
1043                 err.emit();
1044                 if recover {
1045                     return mk_err_expr(self, inner_op.span.to(self.prev_token.span));
1046                 }
1047             }
1048             _ => {}
1049         }
1050         Ok(None)
1051     }
1052
1053     fn consume_fn_args(&mut self) -> Result<(), ()> {
1054         let snapshot = self.create_snapshot_for_diagnostic();
1055         self.bump(); // `(`
1056
1057         // Consume the fn call arguments.
1058         let modifiers =
1059             [(token::OpenDelim(token::Paren), 1), (token::CloseDelim(token::Paren), -1)];
1060         self.consume_tts(1, &modifiers);
1061
1062         if self.token.kind == token::Eof {
1063             // Not entirely sure that what we consumed were fn arguments, rollback.
1064             self.restore_snapshot(snapshot);
1065             Err(())
1066         } else {
1067             // 99% certain that the suggestion is correct, continue parsing.
1068             Ok(())
1069         }
1070     }
1071
1072     pub(super) fn maybe_report_ambiguous_plus(
1073         &mut self,
1074         allow_plus: AllowPlus,
1075         impl_dyn_multi: bool,
1076         ty: &Ty,
1077     ) {
1078         if matches!(allow_plus, AllowPlus::No) && impl_dyn_multi {
1079             let sum_with_parens = format!("({})", pprust::ty_to_string(&ty));
1080             self.struct_span_err(ty.span, "ambiguous `+` in a type")
1081                 .span_suggestion(
1082                     ty.span,
1083                     "use parentheses to disambiguate",
1084                     sum_with_parens,
1085                     Applicability::MachineApplicable,
1086                 )
1087                 .emit();
1088         }
1089     }
1090
1091     /// Swift lets users write `Ty?` to mean `Option<Ty>`. Parse the construct and recover from it.
1092     pub(super) fn maybe_recover_from_question_mark(
1093         &mut self,
1094         ty: P<Ty>,
1095         recover_question_mark: RecoverQuestionMark,
1096     ) -> P<Ty> {
1097         if let RecoverQuestionMark::No = recover_question_mark {
1098             return ty;
1099         }
1100         if self.token == token::Question {
1101             self.bump();
1102             self.struct_span_err(self.prev_token.span, "invalid `?` in type")
1103                 .span_label(self.prev_token.span, "`?` is only allowed on expressions, not types")
1104                 .multipart_suggestion(
1105                     "if you meant to express that the type might not contain a value, use the `Option` wrapper type",
1106                     vec![
1107                         (ty.span.shrink_to_lo(), "Option<".to_string()),
1108                         (self.prev_token.span, ">".to_string()),
1109                     ],
1110                     Applicability::MachineApplicable,
1111                 )
1112                 .emit();
1113             self.mk_ty(ty.span.to(self.prev_token.span), TyKind::Err)
1114         } else {
1115             ty
1116         }
1117     }
1118
1119     pub(super) fn maybe_recover_from_bad_type_plus(
1120         &mut self,
1121         allow_plus: AllowPlus,
1122         ty: &Ty,
1123     ) -> PResult<'a, ()> {
1124         // Do not add `+` to expected tokens.
1125         if matches!(allow_plus, AllowPlus::No) || !self.token.is_like_plus() {
1126             return Ok(());
1127         }
1128
1129         self.bump(); // `+`
1130         let bounds = self.parse_generic_bounds(None)?;
1131         let sum_span = ty.span.to(self.prev_token.span);
1132
1133         let mut err = struct_span_err!(
1134             self.sess.span_diagnostic,
1135             sum_span,
1136             E0178,
1137             "expected a path on the left-hand side of `+`, not `{}`",
1138             pprust::ty_to_string(ty)
1139         );
1140
1141         match ty.kind {
1142             TyKind::Rptr(ref lifetime, ref mut_ty) => {
1143                 let sum_with_parens = pprust::to_string(|s| {
1144                     s.s.word("&");
1145                     s.print_opt_lifetime(lifetime);
1146                     s.print_mutability(mut_ty.mutbl, false);
1147                     s.popen();
1148                     s.print_type(&mut_ty.ty);
1149                     s.print_type_bounds(" +", &bounds);
1150                     s.pclose()
1151                 });
1152                 err.span_suggestion(
1153                     sum_span,
1154                     "try adding parentheses",
1155                     sum_with_parens,
1156                     Applicability::MachineApplicable,
1157                 );
1158             }
1159             TyKind::Ptr(..) | TyKind::BareFn(..) => {
1160                 err.span_label(sum_span, "perhaps you forgot parentheses?");
1161             }
1162             _ => {
1163                 err.span_label(sum_span, "expected a path");
1164             }
1165         }
1166         err.emit();
1167         Ok(())
1168     }
1169
1170     /// Tries to recover from associated item paths like `[T]::AssocItem` / `(T, U)::AssocItem`.
1171     /// Attempts to convert the base expression/pattern/type into a type, parses the `::AssocItem`
1172     /// tail, and combines them into a `<Ty>::AssocItem` expression/pattern/type.
1173     pub(super) fn maybe_recover_from_bad_qpath<T: RecoverQPath>(
1174         &mut self,
1175         base: P<T>,
1176         allow_recovery: bool,
1177     ) -> PResult<'a, P<T>> {
1178         // Do not add `::` to expected tokens.
1179         if allow_recovery && self.token == token::ModSep {
1180             if let Some(ty) = base.to_ty() {
1181                 return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
1182             }
1183         }
1184         Ok(base)
1185     }
1186
1187     /// Given an already parsed `Ty`, parses the `::AssocItem` tail and
1188     /// combines them into a `<Ty>::AssocItem` expression/pattern/type.
1189     pub(super) fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
1190         &mut self,
1191         ty_span: Span,
1192         ty: P<Ty>,
1193     ) -> PResult<'a, P<T>> {
1194         self.expect(&token::ModSep)?;
1195
1196         let mut path = ast::Path { segments: Vec::new(), span: DUMMY_SP, tokens: None };
1197         self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?;
1198         path.span = ty_span.to(self.prev_token.span);
1199
1200         let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty));
1201         self.struct_span_err(path.span, "missing angle brackets in associated item path")
1202             .span_suggestion(
1203                 // This is a best-effort recovery.
1204                 path.span,
1205                 "try",
1206                 format!("<{}>::{}", ty_str, pprust::path_to_string(&path)),
1207                 Applicability::MaybeIncorrect,
1208             )
1209             .emit();
1210
1211         let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`.
1212         Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path)))
1213     }
1214
1215     pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
1216         if self.token.kind == TokenKind::Semi {
1217             self.bump();
1218             let mut err = self.struct_span_err(self.prev_token.span, "expected item, found `;`");
1219             err.span_suggestion_short(
1220                 self.prev_token.span,
1221                 "remove this semicolon",
1222                 String::new(),
1223                 Applicability::MachineApplicable,
1224             );
1225             if !items.is_empty() {
1226                 let previous_item = &items[items.len() - 1];
1227                 let previous_item_kind_name = match previous_item.kind {
1228                     // Say "braced struct" because tuple-structs and
1229                     // braceless-empty-struct declarations do take a semicolon.
1230                     ItemKind::Struct(..) => Some("braced struct"),
1231                     ItemKind::Enum(..) => Some("enum"),
1232                     ItemKind::Trait(..) => Some("trait"),
1233                     ItemKind::Union(..) => Some("union"),
1234                     _ => None,
1235                 };
1236                 if let Some(name) = previous_item_kind_name {
1237                     err.help(&format!("{name} declarations are not followed by a semicolon"));
1238                 }
1239             }
1240             err.emit();
1241             true
1242         } else {
1243             false
1244         }
1245     }
1246
1247     /// Creates a `DiagnosticBuilder` for an unexpected token `t` and tries to recover if it is a
1248     /// closing delimiter.
1249     pub(super) fn unexpected_try_recover(
1250         &mut self,
1251         t: &TokenKind,
1252     ) -> PResult<'a, bool /* recovered */> {
1253         let token_str = pprust::token_kind_to_string(t);
1254         let this_token_str = super::token_descr(&self.token);
1255         let (prev_sp, sp) = match (&self.token.kind, self.subparser_name) {
1256             // Point at the end of the macro call when reaching end of macro arguments.
1257             (token::Eof, Some(_)) => {
1258                 let sp = self.sess.source_map().next_point(self.prev_token.span);
1259                 (sp, sp)
1260             }
1261             // We don't want to point at the following span after DUMMY_SP.
1262             // This happens when the parser finds an empty TokenStream.
1263             _ if self.prev_token.span == DUMMY_SP => (self.token.span, self.token.span),
1264             // EOF, don't want to point at the following char, but rather the last token.
1265             (token::Eof, None) => (self.prev_token.span, self.token.span),
1266             _ => (self.prev_token.span.shrink_to_hi(), self.token.span),
1267         };
1268         let msg = format!(
1269             "expected `{}`, found {}",
1270             token_str,
1271             match (&self.token.kind, self.subparser_name) {
1272                 (token::Eof, Some(origin)) => format!("end of {origin}"),
1273                 _ => this_token_str,
1274             },
1275         );
1276         let mut err = self.struct_span_err(sp, &msg);
1277         let label_exp = format!("expected `{token_str}`");
1278         match self.recover_closing_delimiter(&[t.clone()], err) {
1279             Err(e) => err = e,
1280             Ok(recovered) => {
1281                 return Ok(recovered);
1282             }
1283         }
1284         let sm = self.sess.source_map();
1285         if !sm.is_multiline(prev_sp.until(sp)) {
1286             // When the spans are in the same line, it means that the only content
1287             // between them is whitespace, point only at the found token.
1288             err.span_label(sp, label_exp);
1289         } else {
1290             err.span_label(prev_sp, label_exp);
1291             err.span_label(sp, "unexpected token");
1292         }
1293         Err(err)
1294     }
1295
1296     pub(super) fn expect_semi(&mut self) -> PResult<'a, ()> {
1297         if self.eat(&token::Semi) {
1298             return Ok(());
1299         }
1300         self.expect(&token::Semi).map(drop) // Error unconditionally
1301     }
1302
1303     /// Consumes alternative await syntaxes like `await!(<expr>)`, `await <expr>`,
1304     /// `await? <expr>`, `await(<expr>)`, and `await { <expr> }`.
1305     pub(super) fn recover_incorrect_await_syntax(
1306         &mut self,
1307         lo: Span,
1308         await_sp: Span,
1309         attrs: AttrVec,
1310     ) -> PResult<'a, P<Expr>> {
1311         let (hi, expr, is_question) = if self.token == token::Not {
1312             // Handle `await!(<expr>)`.
1313             self.recover_await_macro()?
1314         } else {
1315             self.recover_await_prefix(await_sp)?
1316         };
1317         let sp = self.error_on_incorrect_await(lo, hi, &expr, is_question);
1318         let kind = match expr.kind {
1319             // Avoid knock-down errors as we don't know whether to interpret this as `foo().await?`
1320             // or `foo()?.await` (the very reason we went with postfix syntax ðŸ˜…).
1321             ExprKind::Try(_) => ExprKind::Err,
1322             _ => ExprKind::Await(expr),
1323         };
1324         let expr = self.mk_expr(lo.to(sp), kind, attrs);
1325         self.maybe_recover_from_bad_qpath(expr, true)
1326     }
1327
1328     fn recover_await_macro(&mut self) -> PResult<'a, (Span, P<Expr>, bool)> {
1329         self.expect(&token::Not)?;
1330         self.expect(&token::OpenDelim(token::Paren))?;
1331         let expr = self.parse_expr()?;
1332         self.expect(&token::CloseDelim(token::Paren))?;
1333         Ok((self.prev_token.span, expr, false))
1334     }
1335
1336     fn recover_await_prefix(&mut self, await_sp: Span) -> PResult<'a, (Span, P<Expr>, bool)> {
1337         let is_question = self.eat(&token::Question); // Handle `await? <expr>`.
1338         let expr = if self.token == token::OpenDelim(token::Brace) {
1339             // Handle `await { <expr> }`.
1340             // This needs to be handled separately from the next arm to avoid
1341             // interpreting `await { <expr> }?` as `<expr>?.await`.
1342             self.parse_block_expr(None, self.token.span, BlockCheckMode::Default, AttrVec::new())
1343         } else {
1344             self.parse_expr()
1345         }
1346         .map_err(|mut err| {
1347             err.span_label(await_sp, "while parsing this incorrect await expression");
1348             err
1349         })?;
1350         Ok((expr.span, expr, is_question))
1351     }
1352
1353     fn error_on_incorrect_await(&self, lo: Span, hi: Span, expr: &Expr, is_question: bool) -> Span {
1354         let expr_str =
1355             self.span_to_snippet(expr.span).unwrap_or_else(|_| pprust::expr_to_string(&expr));
1356         let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" });
1357         let sp = lo.to(hi);
1358         let app = match expr.kind {
1359             ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
1360             _ => Applicability::MachineApplicable,
1361         };
1362         self.struct_span_err(sp, "incorrect use of `await`")
1363             .span_suggestion(sp, "`await` is a postfix operation", suggestion, app)
1364             .emit();
1365         sp
1366     }
1367
1368     /// If encountering `future.await()`, consumes and emits an error.
1369     pub(super) fn recover_from_await_method_call(&mut self) {
1370         if self.token == token::OpenDelim(token::Paren)
1371             && self.look_ahead(1, |t| t == &token::CloseDelim(token::Paren))
1372         {
1373             // future.await()
1374             let lo = self.token.span;
1375             self.bump(); // (
1376             let sp = lo.to(self.token.span);
1377             self.bump(); // )
1378             self.struct_span_err(sp, "incorrect use of `await`")
1379                 .span_suggestion(
1380                     sp,
1381                     "`await` is not a method call, remove the parentheses",
1382                     String::new(),
1383                     Applicability::MachineApplicable,
1384                 )
1385                 .emit();
1386         }
1387     }
1388
1389     pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P<Expr>> {
1390         let is_try = self.token.is_keyword(kw::Try);
1391         let is_questionmark = self.look_ahead(1, |t| t == &token::Not); //check for !
1392         let is_open = self.look_ahead(2, |t| t == &token::OpenDelim(token::Paren)); //check for (
1393
1394         if is_try && is_questionmark && is_open {
1395             let lo = self.token.span;
1396             self.bump(); //remove try
1397             self.bump(); //remove !
1398             let try_span = lo.to(self.token.span); //we take the try!( span
1399             self.bump(); //remove (
1400             let is_empty = self.token == token::CloseDelim(token::Paren); //check if the block is empty
1401             self.consume_block(token::Paren, ConsumeClosingDelim::No); //eat the block
1402             let hi = self.token.span;
1403             self.bump(); //remove )
1404             let mut err = self.struct_span_err(lo.to(hi), "use of deprecated `try` macro");
1405             err.note("in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated");
1406             let prefix = if is_empty { "" } else { "alternatively, " };
1407             if !is_empty {
1408                 err.multipart_suggestion(
1409                     "you can use the `?` operator instead",
1410                     vec![(try_span, "".to_owned()), (hi, "?".to_owned())],
1411                     Applicability::MachineApplicable,
1412                 );
1413             }
1414             err.span_suggestion(lo.shrink_to_lo(), &format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#".to_string(), Applicability::MachineApplicable);
1415             err.emit();
1416             Ok(self.mk_expr_err(lo.to(hi)))
1417         } else {
1418             Err(self.expected_expression_found()) // The user isn't trying to invoke the try! macro
1419         }
1420     }
1421
1422     /// Recovers a situation like `for ( $pat in $expr )`
1423     /// and suggest writing `for $pat in $expr` instead.
1424     ///
1425     /// This should be called before parsing the `$block`.
1426     pub(super) fn recover_parens_around_for_head(
1427         &mut self,
1428         pat: P<Pat>,
1429         begin_paren: Option<Span>,
1430     ) -> P<Pat> {
1431         match (&self.token.kind, begin_paren) {
1432             (token::CloseDelim(token::Paren), Some(begin_par_sp)) => {
1433                 self.bump();
1434
1435                 self.struct_span_err(
1436                     MultiSpan::from_spans(vec![begin_par_sp, self.prev_token.span]),
1437                     "unexpected parentheses surrounding `for` loop head",
1438                 )
1439                 .multipart_suggestion(
1440                     "remove parentheses in `for` loop",
1441                     vec![(begin_par_sp, String::new()), (self.prev_token.span, String::new())],
1442                     // With e.g. `for (x) in y)` this would replace `(x) in y)`
1443                     // with `x) in y)` which is syntactically invalid.
1444                     // However, this is prevented before we get here.
1445                     Applicability::MachineApplicable,
1446                 )
1447                 .emit();
1448
1449                 // Unwrap `(pat)` into `pat` to avoid the `unused_parens` lint.
1450                 pat.and_then(|pat| match pat.kind {
1451                     PatKind::Paren(pat) => pat,
1452                     _ => P(pat),
1453                 })
1454             }
1455             _ => pat,
1456         }
1457     }
1458
1459     pub(super) fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool {
1460         (self.token == token::Lt && // `foo:<bar`, likely a typoed turbofish.
1461             self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident()))
1462             || self.token.is_ident() &&
1463             matches!(node, ast::ExprKind::Path(..) | ast::ExprKind::Field(..)) &&
1464             !self.token.is_reserved_ident() &&           // v `foo:bar(baz)`
1465             self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren))
1466             || self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace)) // `foo:bar {`
1467             || self.look_ahead(1, |t| t == &token::Colon) &&     // `foo:bar::<baz`
1468             self.look_ahead(2, |t| t == &token::Lt) &&
1469             self.look_ahead(3, |t| t.is_ident())
1470             || self.look_ahead(1, |t| t == &token::Colon) &&  // `foo:bar:baz`
1471             self.look_ahead(2, |t| t.is_ident())
1472             || self.look_ahead(1, |t| t == &token::ModSep)
1473                 && (self.look_ahead(2, |t| t.is_ident()) ||   // `foo:bar::baz`
1474             self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::<baz>`
1475     }
1476
1477     pub(super) fn recover_seq_parse_error(
1478         &mut self,
1479         delim: token::DelimToken,
1480         lo: Span,
1481         result: PResult<'a, P<Expr>>,
1482     ) -> P<Expr> {
1483         match result {
1484             Ok(x) => x,
1485             Err(mut err) => {
1486                 err.emit();
1487                 // Recover from parse error, callers expect the closing delim to be consumed.
1488                 self.consume_block(delim, ConsumeClosingDelim::Yes);
1489                 self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err, AttrVec::new())
1490             }
1491         }
1492     }
1493
1494     pub(super) fn recover_closing_delimiter(
1495         &mut self,
1496         tokens: &[TokenKind],
1497         mut err: DiagnosticBuilder<'a, ErrorGuaranteed>,
1498     ) -> PResult<'a, bool> {
1499         let mut pos = None;
1500         // We want to use the last closing delim that would apply.
1501         for (i, unmatched) in self.unclosed_delims.iter().enumerate().rev() {
1502             if tokens.contains(&token::CloseDelim(unmatched.expected_delim))
1503                 && Some(self.token.span) > unmatched.unclosed_span
1504             {
1505                 pos = Some(i);
1506             }
1507         }
1508         match pos {
1509             Some(pos) => {
1510                 // Recover and assume that the detected unclosed delimiter was meant for
1511                 // this location. Emit the diagnostic and act as if the delimiter was
1512                 // present for the parser's sake.
1513
1514                 // Don't attempt to recover from this unclosed delimiter more than once.
1515                 let unmatched = self.unclosed_delims.remove(pos);
1516                 let delim = TokenType::Token(token::CloseDelim(unmatched.expected_delim));
1517                 if unmatched.found_delim.is_none() {
1518                     // We encountered `Eof`, set this fact here to avoid complaining about missing
1519                     // `fn main()` when we found place to suggest the closing brace.
1520                     *self.sess.reached_eof.borrow_mut() = true;
1521                 }
1522
1523                 // We want to suggest the inclusion of the closing delimiter where it makes
1524                 // the most sense, which is immediately after the last token:
1525                 //
1526                 //  {foo(bar {}}
1527                 //      ^      ^
1528                 //      |      |
1529                 //      |      help: `)` may belong here
1530                 //      |
1531                 //      unclosed delimiter
1532                 if let Some(sp) = unmatched.unclosed_span {
1533                     let mut primary_span: Vec<Span> =
1534                         err.span.primary_spans().iter().cloned().collect();
1535                     primary_span.push(sp);
1536                     let mut primary_span: MultiSpan = primary_span.into();
1537                     for span_label in err.span.span_labels() {
1538                         if let Some(label) = span_label.label {
1539                             primary_span.push_span_label(span_label.span, label);
1540                         }
1541                     }
1542                     err.set_span(primary_span);
1543                     err.span_label(sp, "unclosed delimiter");
1544                 }
1545                 // Backticks should be removed to apply suggestions.
1546                 let mut delim = delim.to_string();
1547                 delim.retain(|c| c != '`');
1548                 err.span_suggestion_short(
1549                     self.prev_token.span.shrink_to_hi(),
1550                     &format!("`{delim}` may belong here"),
1551                     delim,
1552                     Applicability::MaybeIncorrect,
1553                 );
1554                 if unmatched.found_delim.is_none() {
1555                     // Encountered `Eof` when lexing blocks. Do not recover here to avoid knockdown
1556                     // errors which would be emitted elsewhere in the parser and let other error
1557                     // recovery consume the rest of the file.
1558                     Err(err)
1559                 } else {
1560                     err.emit();
1561                     self.expected_tokens.clear(); // Reduce the number of errors.
1562                     Ok(true)
1563                 }
1564             }
1565             _ => Err(err),
1566         }
1567     }
1568
1569     /// Eats tokens until we can be relatively sure we reached the end of the
1570     /// statement. This is something of a best-effort heuristic.
1571     ///
1572     /// We terminate when we find an unmatched `}` (without consuming it).
1573     pub(super) fn recover_stmt(&mut self) {
1574         self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore)
1575     }
1576
1577     /// If `break_on_semi` is `Break`, then we will stop consuming tokens after
1578     /// finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
1579     /// approximate -- it can mean we break too early due to macros, but that
1580     /// should only lead to sub-optimal recovery, not inaccurate parsing).
1581     ///
1582     /// If `break_on_block` is `Break`, then we will stop consuming tokens
1583     /// after finding (and consuming) a brace-delimited block.
1584     pub(super) fn recover_stmt_(
1585         &mut self,
1586         break_on_semi: SemiColonMode,
1587         break_on_block: BlockMode,
1588     ) {
1589         let mut brace_depth = 0;
1590         let mut bracket_depth = 0;
1591         let mut in_block = false;
1592         debug!("recover_stmt_ enter loop (semi={:?}, block={:?})", break_on_semi, break_on_block);
1593         loop {
1594             debug!("recover_stmt_ loop {:?}", self.token);
1595             match self.token.kind {
1596                 token::OpenDelim(token::DelimToken::Brace) => {
1597                     brace_depth += 1;
1598                     self.bump();
1599                     if break_on_block == BlockMode::Break && brace_depth == 1 && bracket_depth == 0
1600                     {
1601                         in_block = true;
1602                     }
1603                 }
1604                 token::OpenDelim(token::DelimToken::Bracket) => {
1605                     bracket_depth += 1;
1606                     self.bump();
1607                 }
1608                 token::CloseDelim(token::DelimToken::Brace) => {
1609                     if brace_depth == 0 {
1610                         debug!("recover_stmt_ return - close delim {:?}", self.token);
1611                         break;
1612                     }
1613                     brace_depth -= 1;
1614                     self.bump();
1615                     if in_block && bracket_depth == 0 && brace_depth == 0 {
1616                         debug!("recover_stmt_ return - block end {:?}", self.token);
1617                         break;
1618                     }
1619                 }
1620                 token::CloseDelim(token::DelimToken::Bracket) => {
1621                     bracket_depth -= 1;
1622                     if bracket_depth < 0 {
1623                         bracket_depth = 0;
1624                     }
1625                     self.bump();
1626                 }
1627                 token::Eof => {
1628                     debug!("recover_stmt_ return - Eof");
1629                     break;
1630                 }
1631                 token::Semi => {
1632                     self.bump();
1633                     if break_on_semi == SemiColonMode::Break
1634                         && brace_depth == 0
1635                         && bracket_depth == 0
1636                     {
1637                         debug!("recover_stmt_ return - Semi");
1638                         break;
1639                     }
1640                 }
1641                 token::Comma
1642                     if break_on_semi == SemiColonMode::Comma
1643                         && brace_depth == 0
1644                         && bracket_depth == 0 =>
1645                 {
1646                     debug!("recover_stmt_ return - Semi");
1647                     break;
1648                 }
1649                 _ => self.bump(),
1650             }
1651         }
1652     }
1653
1654     pub(super) fn check_for_for_in_in_typo(&mut self, in_span: Span) {
1655         if self.eat_keyword(kw::In) {
1656             // a common typo: `for _ in in bar {}`
1657             self.struct_span_err(self.prev_token.span, "expected iterable, found keyword `in`")
1658                 .span_suggestion_short(
1659                     in_span.until(self.prev_token.span),
1660                     "remove the duplicated `in`",
1661                     String::new(),
1662                     Applicability::MachineApplicable,
1663                 )
1664                 .emit();
1665         }
1666     }
1667
1668     pub(super) fn eat_incorrect_doc_comment_for_param_type(&mut self) {
1669         if let token::DocComment(..) = self.token.kind {
1670             self.struct_span_err(
1671                 self.token.span,
1672                 "documentation comments cannot be applied to a function parameter's type",
1673             )
1674             .span_label(self.token.span, "doc comments are not allowed here")
1675             .emit();
1676             self.bump();
1677         } else if self.token == token::Pound
1678             && self.look_ahead(1, |t| *t == token::OpenDelim(token::Bracket))
1679         {
1680             let lo = self.token.span;
1681             // Skip every token until next possible arg.
1682             while self.token != token::CloseDelim(token::Bracket) {
1683                 self.bump();
1684             }
1685             let sp = lo.to(self.token.span);
1686             self.bump();
1687             self.struct_span_err(sp, "attributes cannot be applied to a function parameter's type")
1688                 .span_label(sp, "attributes are not allowed here")
1689                 .emit();
1690         }
1691     }
1692
1693     pub(super) fn parameter_without_type(
1694         &mut self,
1695         err: &mut Diagnostic,
1696         pat: P<ast::Pat>,
1697         require_name: bool,
1698         first_param: bool,
1699     ) -> Option<Ident> {
1700         // If we find a pattern followed by an identifier, it could be an (incorrect)
1701         // C-style parameter declaration.
1702         if self.check_ident()
1703             && self.look_ahead(1, |t| *t == token::Comma || *t == token::CloseDelim(token::Paren))
1704         {
1705             // `fn foo(String s) {}`
1706             let ident = self.parse_ident().unwrap();
1707             let span = pat.span.with_hi(ident.span.hi());
1708
1709             err.span_suggestion(
1710                 span,
1711                 "declare the type after the parameter binding",
1712                 String::from("<identifier>: <type>"),
1713                 Applicability::HasPlaceholders,
1714             );
1715             return Some(ident);
1716         } else if require_name
1717             && (self.token == token::Comma
1718                 || self.token == token::Lt
1719                 || self.token == token::CloseDelim(token::Paren))
1720         {
1721             let rfc_note = "anonymous parameters are removed in the 2018 edition (see RFC 1685)";
1722
1723             let (ident, self_sugg, param_sugg, type_sugg, self_span, param_span, type_span) =
1724                 match pat.kind {
1725                     PatKind::Ident(_, ident, _) => (
1726                         ident,
1727                         "self: ".to_string(),
1728                         ": TypeName".to_string(),
1729                         "_: ".to_string(),
1730                         pat.span.shrink_to_lo(),
1731                         pat.span.shrink_to_hi(),
1732                         pat.span.shrink_to_lo(),
1733                     ),
1734                     // Also catches `fn foo(&a)`.
1735                     PatKind::Ref(ref inner_pat, mutab)
1736                         if matches!(inner_pat.clone().into_inner().kind, PatKind::Ident(..)) =>
1737                     {
1738                         match inner_pat.clone().into_inner().kind {
1739                             PatKind::Ident(_, ident, _) => {
1740                                 let mutab = mutab.prefix_str();
1741                                 (
1742                                     ident,
1743                                     "self: ".to_string(),
1744                                     format!("{ident}: &{mutab}TypeName"),
1745                                     "_: ".to_string(),
1746                                     pat.span.shrink_to_lo(),
1747                                     pat.span,
1748                                     pat.span.shrink_to_lo(),
1749                                 )
1750                             }
1751                             _ => unreachable!(),
1752                         }
1753                     }
1754                     _ => {
1755                         // Otherwise, try to get a type and emit a suggestion.
1756                         if let Some(ty) = pat.to_ty() {
1757                             err.span_suggestion_verbose(
1758                                 pat.span,
1759                                 "explicitly ignore the parameter name",
1760                                 format!("_: {}", pprust::ty_to_string(&ty)),
1761                                 Applicability::MachineApplicable,
1762                             );
1763                             err.note(rfc_note);
1764                         }
1765
1766                         return None;
1767                     }
1768                 };
1769
1770             // `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
1771             if first_param {
1772                 err.span_suggestion(
1773                     self_span,
1774                     "if this is a `self` type, give it a parameter name",
1775                     self_sugg,
1776                     Applicability::MaybeIncorrect,
1777                 );
1778             }
1779             // Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to
1780             // `fn foo(HashMap: TypeName<u32>)`.
1781             if self.token != token::Lt {
1782                 err.span_suggestion(
1783                     param_span,
1784                     "if this is a parameter name, give it a type",
1785                     param_sugg,
1786                     Applicability::HasPlaceholders,
1787                 );
1788             }
1789             err.span_suggestion(
1790                 type_span,
1791                 "if this is a type, explicitly ignore the parameter name",
1792                 type_sugg,
1793                 Applicability::MachineApplicable,
1794             );
1795             err.note(rfc_note);
1796
1797             // Don't attempt to recover by using the `X` in `X<Y>` as the parameter name.
1798             return if self.token == token::Lt { None } else { Some(ident) };
1799         }
1800         None
1801     }
1802
1803     pub(super) fn recover_arg_parse(&mut self) -> PResult<'a, (P<ast::Pat>, P<ast::Ty>)> {
1804         let pat = self.parse_pat_no_top_alt(Some("argument name"))?;
1805         self.expect(&token::Colon)?;
1806         let ty = self.parse_ty()?;
1807
1808         struct_span_err!(
1809             self.diagnostic(),
1810             pat.span,
1811             E0642,
1812             "patterns aren't allowed in methods without bodies",
1813         )
1814         .span_suggestion_short(
1815             pat.span,
1816             "give this argument a name or use an underscore to ignore it",
1817             "_".to_owned(),
1818             Applicability::MachineApplicable,
1819         )
1820         .emit();
1821
1822         // Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
1823         let pat =
1824             P(Pat { kind: PatKind::Wild, span: pat.span, id: ast::DUMMY_NODE_ID, tokens: None });
1825         Ok((pat, ty))
1826     }
1827
1828     pub(super) fn recover_bad_self_param(&mut self, mut param: Param) -> PResult<'a, Param> {
1829         let sp = param.pat.span;
1830         param.ty.kind = TyKind::Err;
1831         self.struct_span_err(sp, "unexpected `self` parameter in function")
1832             .span_label(sp, "must be the first parameter of an associated function")
1833             .emit();
1834         Ok(param)
1835     }
1836
1837     pub(super) fn consume_block(
1838         &mut self,
1839         delim: token::DelimToken,
1840         consume_close: ConsumeClosingDelim,
1841     ) {
1842         let mut brace_depth = 0;
1843         loop {
1844             if self.eat(&token::OpenDelim(delim)) {
1845                 brace_depth += 1;
1846             } else if self.check(&token::CloseDelim(delim)) {
1847                 if brace_depth == 0 {
1848                     if let ConsumeClosingDelim::Yes = consume_close {
1849                         // Some of the callers of this method expect to be able to parse the
1850                         // closing delimiter themselves, so we leave it alone. Otherwise we advance
1851                         // the parser.
1852                         self.bump();
1853                     }
1854                     return;
1855                 } else {
1856                     self.bump();
1857                     brace_depth -= 1;
1858                     continue;
1859                 }
1860             } else if self.token == token::Eof || self.eat(&token::CloseDelim(token::NoDelim)) {
1861                 return;
1862             } else {
1863                 self.bump();
1864             }
1865         }
1866     }
1867
1868     pub(super) fn expected_expression_found(&self) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
1869         let (span, msg) = match (&self.token.kind, self.subparser_name) {
1870             (&token::Eof, Some(origin)) => {
1871                 let sp = self.sess.source_map().next_point(self.prev_token.span);
1872                 (sp, format!("expected expression, found end of {origin}"))
1873             }
1874             _ => (
1875                 self.token.span,
1876                 format!("expected expression, found {}", super::token_descr(&self.token),),
1877             ),
1878         };
1879         let mut err = self.struct_span_err(span, &msg);
1880         let sp = self.sess.source_map().start_point(self.token.span);
1881         if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
1882             self.sess.expr_parentheses_needed(&mut err, *sp);
1883         }
1884         err.span_label(span, "expected expression");
1885         err
1886     }
1887
1888     fn consume_tts(
1889         &mut self,
1890         mut acc: i64, // `i64` because malformed code can have more closing delims than opening.
1891         // Not using `FxHashMap` due to `token::TokenKind: !Eq + !Hash`.
1892         modifier: &[(token::TokenKind, i64)],
1893     ) {
1894         while acc > 0 {
1895             if let Some((_, val)) = modifier.iter().find(|(t, _)| *t == self.token.kind) {
1896                 acc += *val;
1897             }
1898             if self.token.kind == token::Eof {
1899                 break;
1900             }
1901             self.bump();
1902         }
1903     }
1904
1905     /// Replace duplicated recovered parameters with `_` pattern to avoid unnecessary errors.
1906     ///
1907     /// This is necessary because at this point we don't know whether we parsed a function with
1908     /// anonymous parameters or a function with names but no types. In order to minimize
1909     /// unnecessary errors, we assume the parameters are in the shape of `fn foo(a, b, c)` where
1910     /// the parameters are *names* (so we don't emit errors about not being able to find `b` in
1911     /// the local scope), but if we find the same name multiple times, like in `fn foo(i8, i8)`,
1912     /// we deduplicate them to not complain about duplicated parameter names.
1913     pub(super) fn deduplicate_recovered_params_names(&self, fn_inputs: &mut Vec<Param>) {
1914         let mut seen_inputs = FxHashSet::default();
1915         for input in fn_inputs.iter_mut() {
1916             let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) =
1917                 (&input.pat.kind, &input.ty.kind)
1918             {
1919                 Some(*ident)
1920             } else {
1921                 None
1922             };
1923             if let Some(ident) = opt_ident {
1924                 if seen_inputs.contains(&ident) {
1925                     input.pat.kind = PatKind::Wild;
1926                 }
1927                 seen_inputs.insert(ident);
1928             }
1929         }
1930     }
1931
1932     /// Handle encountering a symbol in a generic argument list that is not a `,` or `>`. In this
1933     /// case, we emit an error and try to suggest enclosing a const argument in braces if it looks
1934     /// like the user has forgotten them.
1935     pub fn handle_ambiguous_unbraced_const_arg(
1936         &mut self,
1937         args: &mut Vec<AngleBracketedArg>,
1938     ) -> PResult<'a, bool> {
1939         // If we haven't encountered a closing `>`, then the argument is malformed.
1940         // It's likely that the user has written a const expression without enclosing it
1941         // in braces, so we try to recover here.
1942         let arg = args.pop().unwrap();
1943         // FIXME: for some reason using `unexpected` or `expected_one_of_not_found` has
1944         // adverse side-effects to subsequent errors and seems to advance the parser.
1945         // We are causing this error here exclusively in case that a `const` expression
1946         // could be recovered from the current parser state, even if followed by more
1947         // arguments after a comma.
1948         let mut err = self.struct_span_err(
1949             self.token.span,
1950             &format!("expected one of `,` or `>`, found {}", super::token_descr(&self.token)),
1951         );
1952         err.span_label(self.token.span, "expected one of `,` or `>`");
1953         match self.recover_const_arg(arg.span(), err) {
1954             Ok(arg) => {
1955                 args.push(AngleBracketedArg::Arg(arg));
1956                 if self.eat(&token::Comma) {
1957                     return Ok(true); // Continue
1958                 }
1959             }
1960             Err(mut err) => {
1961                 args.push(arg);
1962                 // We will emit a more generic error later.
1963                 err.delay_as_bug();
1964             }
1965         }
1966         return Ok(false); // Don't continue.
1967     }
1968
1969     /// Attempt to parse a generic const argument that has not been enclosed in braces.
1970     /// There are a limited number of expressions that are permitted without being encoded
1971     /// in braces:
1972     /// - Literals.
1973     /// - Single-segment paths (i.e. standalone generic const parameters).
1974     /// All other expressions that can be parsed will emit an error suggesting the expression be
1975     /// wrapped in braces.
1976     pub fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, P<Expr>> {
1977         let start = self.token.span;
1978         let expr = self.parse_expr_res(Restrictions::CONST_EXPR, None).map_err(|mut err| {
1979             err.span_label(
1980                 start.shrink_to_lo(),
1981                 "while parsing a const generic argument starting here",
1982             );
1983             err
1984         })?;
1985         if !self.expr_is_valid_const_arg(&expr) {
1986             self.struct_span_err(
1987                 expr.span,
1988                 "expressions must be enclosed in braces to be used as const generic \
1989                     arguments",
1990             )
1991             .multipart_suggestion(
1992                 "enclose the `const` expression in braces",
1993                 vec![
1994                     (expr.span.shrink_to_lo(), "{ ".to_string()),
1995                     (expr.span.shrink_to_hi(), " }".to_string()),
1996                 ],
1997                 Applicability::MachineApplicable,
1998             )
1999             .emit();
2000         }
2001         Ok(expr)
2002     }
2003
2004     fn recover_const_param_decl(&mut self, ty_generics: Option<&Generics>) -> Option<GenericArg> {
2005         let snapshot = self.create_snapshot_for_diagnostic();
2006         let param = match self.parse_const_param(vec![]) {
2007             Ok(param) => param,
2008             Err(err) => {
2009                 err.cancel();
2010                 self.restore_snapshot(snapshot);
2011                 return None;
2012             }
2013         };
2014         let mut err =
2015             self.struct_span_err(param.span(), "unexpected `const` parameter declaration");
2016         err.span_label(param.span(), "expected a `const` expression, not a parameter declaration");
2017         if let (Some(generics), Ok(snippet)) =
2018             (ty_generics, self.sess.source_map().span_to_snippet(param.span()))
2019         {
2020             let (span, sugg) = match &generics.params[..] {
2021                 [] => (generics.span, format!("<{snippet}>")),
2022                 [.., generic] => (generic.span().shrink_to_hi(), format!(", {snippet}")),
2023             };
2024             err.multipart_suggestion(
2025                 "`const` parameters must be declared for the `impl`",
2026                 vec![(span, sugg), (param.span(), param.ident.to_string())],
2027                 Applicability::MachineApplicable,
2028             );
2029         }
2030         let value = self.mk_expr_err(param.span());
2031         err.emit();
2032         Some(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }))
2033     }
2034
2035     pub fn recover_const_param_declaration(
2036         &mut self,
2037         ty_generics: Option<&Generics>,
2038     ) -> PResult<'a, Option<GenericArg>> {
2039         // We have to check for a few different cases.
2040         if let Some(arg) = self.recover_const_param_decl(ty_generics) {
2041             return Ok(Some(arg));
2042         }
2043
2044         // We haven't consumed `const` yet.
2045         let start = self.token.span;
2046         self.bump(); // `const`
2047
2048         // Detect and recover from the old, pre-RFC2000 syntax for const generics.
2049         let mut err = self
2050             .struct_span_err(start, "expected lifetime, type, or constant, found keyword `const`");
2051         if self.check_const_arg() {
2052             err.span_suggestion_verbose(
2053                 start.until(self.token.span),
2054                 "the `const` keyword is only needed in the definition of the type",
2055                 String::new(),
2056                 Applicability::MaybeIncorrect,
2057             );
2058             err.emit();
2059             Ok(Some(GenericArg::Const(self.parse_const_arg()?)))
2060         } else {
2061             let after_kw_const = self.token.span;
2062             self.recover_const_arg(after_kw_const, err).map(Some)
2063         }
2064     }
2065
2066     /// Try to recover from possible generic const argument without `{` and `}`.
2067     ///
2068     /// When encountering code like `foo::< bar + 3 >` or `foo::< bar - baz >` we suggest
2069     /// `foo::<{ bar + 3 }>` and `foo::<{ bar - baz }>`, respectively. We only provide a suggestion
2070     /// if we think that that the resulting expression would be well formed.
2071     pub fn recover_const_arg(
2072         &mut self,
2073         start: Span,
2074         mut err: DiagnosticBuilder<'a, ErrorGuaranteed>,
2075     ) -> PResult<'a, GenericArg> {
2076         let is_op_or_dot = AssocOp::from_token(&self.token)
2077             .and_then(|op| {
2078                 if let AssocOp::Greater
2079                 | AssocOp::Less
2080                 | AssocOp::ShiftRight
2081                 | AssocOp::GreaterEqual
2082                 // Don't recover from `foo::<bar = baz>`, because this could be an attempt to
2083                 // assign a value to a defaulted generic parameter.
2084                 | AssocOp::Assign
2085                 | AssocOp::AssignOp(_) = op
2086                 {
2087                     None
2088                 } else {
2089                     Some(op)
2090                 }
2091             })
2092             .is_some()
2093             || self.token.kind == TokenKind::Dot;
2094         // This will be true when a trait object type `Foo +` or a path which was a `const fn` with
2095         // type params has been parsed.
2096         let was_op =
2097             matches!(self.prev_token.kind, token::BinOp(token::Plus | token::Shr) | token::Gt);
2098         if !is_op_or_dot && !was_op {
2099             // We perform these checks and early return to avoid taking a snapshot unnecessarily.
2100             return Err(err);
2101         }
2102         let snapshot = self.create_snapshot_for_diagnostic();
2103         if is_op_or_dot {
2104             self.bump();
2105         }
2106         match self.parse_expr_res(Restrictions::CONST_EXPR, None) {
2107             Ok(expr) => {
2108                 // Find a mistake like `MyTrait<Assoc == S::Assoc>`.
2109                 if token::EqEq == snapshot.token.kind {
2110                     err.span_suggestion(
2111                         snapshot.token.span,
2112                         "if you meant to use an associated type binding, replace `==` with `=`",
2113                         "=".to_string(),
2114                         Applicability::MaybeIncorrect,
2115                     );
2116                     let value = self.mk_expr_err(start.to(expr.span));
2117                     err.emit();
2118                     return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }));
2119                 } else if token::Colon == snapshot.token.kind
2120                     && expr.span.lo() == snapshot.token.span.hi()
2121                     && matches!(expr.kind, ExprKind::Path(..))
2122                 {
2123                     // Find a mistake like "foo::var:A".
2124                     err.span_suggestion(
2125                         snapshot.token.span,
2126                         "write a path separator here",
2127                         "::".to_string(),
2128                         Applicability::MaybeIncorrect,
2129                     );
2130                     err.emit();
2131                     return Ok(GenericArg::Type(self.mk_ty(start.to(expr.span), TyKind::Err)));
2132                 } else if token::Comma == self.token.kind || self.token.kind.should_end_const_arg()
2133                 {
2134                     // Avoid the following output by checking that we consumed a full const arg:
2135                     // help: expressions must be enclosed in braces to be used as const generic
2136                     //       arguments
2137                     //    |
2138                     // LL |     let sr: Vec<{ (u32, _, _) = vec![] };
2139                     //    |                 ^                      ^
2140                     return Ok(self.dummy_const_arg_needs_braces(err, start.to(expr.span)));
2141                 }
2142             }
2143             Err(err) => {
2144                 err.cancel();
2145             }
2146         }
2147         self.restore_snapshot(snapshot);
2148         Err(err)
2149     }
2150
2151     /// Creates a dummy const argument, and reports that the expression must be enclosed in braces
2152     pub fn dummy_const_arg_needs_braces(
2153         &self,
2154         mut err: DiagnosticBuilder<'a, ErrorGuaranteed>,
2155         span: Span,
2156     ) -> GenericArg {
2157         err.multipart_suggestion(
2158             "expressions must be enclosed in braces to be used as const generic \
2159              arguments",
2160             vec![(span.shrink_to_lo(), "{ ".to_string()), (span.shrink_to_hi(), " }".to_string())],
2161             Applicability::MaybeIncorrect,
2162         );
2163         let value = self.mk_expr_err(span);
2164         err.emit();
2165         GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })
2166     }
2167
2168     /// Get the diagnostics for the cases where `move async` is found.
2169     ///
2170     /// `move_async_span` starts at the 'm' of the move keyword and ends with the 'c' of the async keyword
2171     pub(super) fn incorrect_move_async_order_found(
2172         &self,
2173         move_async_span: Span,
2174     ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
2175         let mut err =
2176             self.struct_span_err(move_async_span, "the order of `move` and `async` is incorrect");
2177         err.span_suggestion_verbose(
2178             move_async_span,
2179             "try switching the order",
2180             "async move".to_owned(),
2181             Applicability::MaybeIncorrect,
2182         );
2183         err
2184     }
2185
2186     /// Some special error handling for the "top-level" patterns in a match arm,
2187     /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
2188     crate fn maybe_recover_colon_colon_in_pat_typo(
2189         &mut self,
2190         mut first_pat: P<Pat>,
2191         ra: RecoverColon,
2192         expected: Expected,
2193     ) -> P<Pat> {
2194         if RecoverColon::Yes != ra || token::Colon != self.token.kind {
2195             return first_pat;
2196         }
2197         if !matches!(first_pat.kind, PatKind::Ident(_, _, None) | PatKind::Path(..))
2198             || !self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
2199         {
2200             return first_pat;
2201         }
2202         // The pattern looks like it might be a path with a `::` -> `:` typo:
2203         // `match foo { bar:baz => {} }`
2204         let span = self.token.span;
2205         // We only emit "unexpected `:`" error here if we can successfully parse the
2206         // whole pattern correctly in that case.
2207         let snapshot = self.create_snapshot_for_diagnostic();
2208
2209         // Create error for "unexpected `:`".
2210         match self.expected_one_of_not_found(&[], &[]) {
2211             Err(mut err) => {
2212                 self.bump(); // Skip the `:`.
2213                 match self.parse_pat_no_top_alt(expected) {
2214                     Err(inner_err) => {
2215                         // Carry on as if we had not done anything, callers will emit a
2216                         // reasonable error.
2217                         inner_err.cancel();
2218                         err.cancel();
2219                         self.restore_snapshot(snapshot);
2220                     }
2221                     Ok(mut pat) => {
2222                         // We've parsed the rest of the pattern.
2223                         let new_span = first_pat.span.to(pat.span);
2224                         let mut show_sugg = false;
2225                         // Try to construct a recovered pattern.
2226                         match &mut pat.kind {
2227                             PatKind::Struct(qself @ None, path, ..)
2228                             | PatKind::TupleStruct(qself @ None, path, _)
2229                             | PatKind::Path(qself @ None, path) => match &first_pat.kind {
2230                                 PatKind::Ident(_, ident, _) => {
2231                                     path.segments.insert(0, PathSegment::from_ident(*ident));
2232                                     path.span = new_span;
2233                                     show_sugg = true;
2234                                     first_pat = pat;
2235                                 }
2236                                 PatKind::Path(old_qself, old_path) => {
2237                                     path.segments = old_path
2238                                         .segments
2239                                         .iter()
2240                                         .cloned()
2241                                         .chain(take(&mut path.segments))
2242                                         .collect();
2243                                     path.span = new_span;
2244                                     *qself = old_qself.clone();
2245                                     first_pat = pat;
2246                                     show_sugg = true;
2247                                 }
2248                                 _ => {}
2249                             },
2250                             PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => {
2251                                 match &first_pat.kind {
2252                                     PatKind::Ident(_, old_ident, _) => {
2253                                         let path = PatKind::Path(
2254                                             None,
2255                                             Path {
2256                                                 span: new_span,
2257                                                 segments: vec![
2258                                                     PathSegment::from_ident(*old_ident),
2259                                                     PathSegment::from_ident(*ident),
2260                                                 ],
2261                                                 tokens: None,
2262                                             },
2263                                         );
2264                                         first_pat = self.mk_pat(new_span, path);
2265                                         show_sugg = true;
2266                                     }
2267                                     PatKind::Path(old_qself, old_path) => {
2268                                         let mut segments = old_path.segments.clone();
2269                                         segments.push(PathSegment::from_ident(*ident));
2270                                         let path = PatKind::Path(
2271                                             old_qself.clone(),
2272                                             Path { span: new_span, segments, tokens: None },
2273                                         );
2274                                         first_pat = self.mk_pat(new_span, path);
2275                                         show_sugg = true;
2276                                     }
2277                                     _ => {}
2278                                 }
2279                             }
2280                             _ => {}
2281                         }
2282                         if show_sugg {
2283                             err.span_suggestion(
2284                                 span,
2285                                 "maybe write a path separator here",
2286                                 "::".to_string(),
2287                                 Applicability::MaybeIncorrect,
2288                             );
2289                         } else {
2290                             first_pat = self.mk_pat(new_span, PatKind::Wild);
2291                         }
2292                         err.emit();
2293                     }
2294                 }
2295             }
2296             _ => {
2297                 // Carry on as if we had not done anything. This should be unreachable.
2298                 self.restore_snapshot(snapshot);
2299             }
2300         };
2301         first_pat
2302     }
2303
2304     crate fn maybe_recover_unexpected_block_label(&mut self) -> bool {
2305         let Some(label) = self.eat_label().filter(|_| {
2306             self.eat(&token::Colon) && self.token.kind == token::OpenDelim(token::Brace)
2307         }) else {
2308             return false;
2309         };
2310         let span = label.ident.span.to(self.prev_token.span);
2311         let mut err = self.struct_span_err(span, "block label not supported here");
2312         err.span_label(span, "not supported here");
2313         err.tool_only_span_suggestion(
2314             label.ident.span.until(self.token.span),
2315             "remove this block label",
2316             String::new(),
2317             Applicability::MachineApplicable,
2318         );
2319         err.emit();
2320         true
2321     }
2322
2323     /// Some special error handling for the "top-level" patterns in a match arm,
2324     /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
2325     crate fn maybe_recover_unexpected_comma(
2326         &mut self,
2327         lo: Span,
2328         rc: RecoverComma,
2329         rt: CommaRecoveryMode,
2330     ) -> PResult<'a, ()> {
2331         if rc == RecoverComma::No || self.token != token::Comma {
2332             return Ok(());
2333         }
2334
2335         // An unexpected comma after a top-level pattern is a clue that the
2336         // user (perhaps more accustomed to some other language) forgot the
2337         // parentheses in what should have been a tuple pattern; return a
2338         // suggestion-enhanced error here rather than choking on the comma later.
2339         let comma_span = self.token.span;
2340         self.bump();
2341         if let Err(err) = self.skip_pat_list() {
2342             // We didn't expect this to work anyway; we just wanted to advance to the
2343             // end of the comma-sequence so we know the span to suggest parenthesizing.
2344             err.cancel();
2345         }
2346         let seq_span = lo.to(self.prev_token.span);
2347         let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
2348         if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
2349             err.multipart_suggestion(
2350                 &format!(
2351                     "try adding parentheses to match on a tuple{}",
2352                     if let CommaRecoveryMode::LikelyTuple = rt { "" } else { "..." },
2353                 ),
2354                 vec![
2355                     (seq_span.shrink_to_lo(), "(".to_string()),
2356                     (seq_span.shrink_to_hi(), ")".to_string()),
2357                 ],
2358                 Applicability::MachineApplicable,
2359             );
2360             if let CommaRecoveryMode::EitherTupleOrPipe = rt {
2361                 err.span_suggestion(
2362                     seq_span,
2363                     "...or a vertical bar to match on multiple alternatives",
2364                     seq_snippet.replace(',', " |"),
2365                     Applicability::MachineApplicable,
2366                 );
2367             }
2368         }
2369         Err(err)
2370     }
2371
2372     /// Parse and throw away a parenthesized comma separated
2373     /// sequence of patterns until `)` is reached.
2374     fn skip_pat_list(&mut self) -> PResult<'a, ()> {
2375         while !self.check(&token::CloseDelim(token::Paren)) {
2376             self.parse_pat_no_top_alt(None)?;
2377             if !self.eat(&token::Comma) {
2378                 return Ok(());
2379             }
2380         }
2381         Ok(())
2382     }
2383 }