]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/parse/diagnostics.rs
Auto merge of #61331 - estebank:fn-arg-parse-recovery, r=varkor
[rust.git] / src / libsyntax / parse / diagnostics.rs
1 use crate::ast::{
2     self, Arg, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
3     Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData,
4 };
5 use crate::parse::{SeqSep, token, PResult, Parser};
6 use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType};
7 use crate::print::pprust;
8 use crate::ptr::P;
9 use crate::source_map::Spanned;
10 use crate::symbol::{kw, sym};
11 use crate::ThinVec;
12 use crate::util::parser::AssocOp;
13 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
14 use rustc_data_structures::fx::FxHashSet;
15 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
16 use log::{debug, trace};
17
18 /// Creates a placeholder argument.
19 crate fn dummy_arg(ident: Ident) -> Arg {
20     let pat = P(Pat {
21         id: ast::DUMMY_NODE_ID,
22         node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None),
23         span: ident.span,
24     });
25     let ty = Ty {
26         node: TyKind::Err,
27         span: ident.span,
28         id: ast::DUMMY_NODE_ID
29     };
30     Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal }
31 }
32
33 pub enum Error {
34     FileNotFoundForModule {
35         mod_name: String,
36         default_path: String,
37         secondary_path: String,
38         dir_path: String,
39     },
40     DuplicatePaths {
41         mod_name: String,
42         default_path: String,
43         secondary_path: String,
44     },
45     UselessDocComment,
46     InclusiveRangeWithNoEnd,
47 }
48
49 impl Error {
50     fn span_err<S: Into<MultiSpan>>(
51         self,
52         sp: S,
53         handler: &errors::Handler,
54     ) -> DiagnosticBuilder<'_> {
55         match self {
56             Error::FileNotFoundForModule {
57                 ref mod_name,
58                 ref default_path,
59                 ref secondary_path,
60                 ref dir_path,
61             } => {
62                 let mut err = struct_span_err!(
63                     handler,
64                     sp,
65                     E0583,
66                     "file not found for module `{}`",
67                     mod_name,
68                 );
69                 err.help(&format!(
70                     "name the file either {} or {} inside the directory \"{}\"",
71                     default_path,
72                     secondary_path,
73                     dir_path,
74                 ));
75                 err
76             }
77             Error::DuplicatePaths { ref mod_name, ref default_path, ref secondary_path } => {
78                 let mut err = struct_span_err!(
79                     handler,
80                     sp,
81                     E0584,
82                     "file for module `{}` found at both {} and {}",
83                     mod_name,
84                     default_path,
85                     secondary_path,
86                 );
87                 err.help("delete or rename one of them to remove the ambiguity");
88                 err
89             }
90             Error::UselessDocComment => {
91                 let mut err = struct_span_err!(
92                     handler,
93                     sp,
94                     E0585,
95                     "found a documentation comment that doesn't document anything",
96                 );
97                 err.help("doc comments must come before what they document, maybe a comment was \
98                           intended with `//`?");
99                 err
100             }
101             Error::InclusiveRangeWithNoEnd => {
102                 let mut err = struct_span_err!(
103                     handler,
104                     sp,
105                     E0586,
106                     "inclusive range with no end",
107                 );
108                 err.help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)");
109                 err
110             }
111         }
112     }
113 }
114
115 pub trait RecoverQPath: Sized + 'static {
116     const PATH_STYLE: PathStyle = PathStyle::Expr;
117     fn to_ty(&self) -> Option<P<Ty>>;
118     fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self;
119 }
120
121 impl RecoverQPath for Ty {
122     const PATH_STYLE: PathStyle = PathStyle::Type;
123     fn to_ty(&self) -> Option<P<Ty>> {
124         Some(P(self.clone()))
125     }
126     fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
127         Self {
128             span: path.span,
129             node: TyKind::Path(qself, path),
130             id: ast::DUMMY_NODE_ID,
131         }
132     }
133 }
134
135 impl RecoverQPath for Pat {
136     fn to_ty(&self) -> Option<P<Ty>> {
137         self.to_ty()
138     }
139     fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
140         Self {
141             span: path.span,
142             node: PatKind::Path(qself, path),
143             id: ast::DUMMY_NODE_ID,
144         }
145     }
146 }
147
148 impl RecoverQPath for Expr {
149     fn to_ty(&self) -> Option<P<Ty>> {
150         self.to_ty()
151     }
152     fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
153         Self {
154             span: path.span,
155             node: ExprKind::Path(qself, path),
156             attrs: ThinVec::new(),
157             id: ast::DUMMY_NODE_ID,
158         }
159     }
160 }
161
162 impl<'a> Parser<'a> {
163     pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
164         self.span_fatal(self.span, m)
165     }
166
167     pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
168         self.sess.span_diagnostic.struct_span_fatal(sp, m)
169     }
170
171     pub fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
172         err.span_err(sp, self.diagnostic())
173     }
174
175     pub fn bug(&self, m: &str) -> ! {
176         self.sess.span_diagnostic.span_bug(self.span, m)
177     }
178
179     pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
180         self.sess.span_diagnostic.span_err(sp, m)
181     }
182
183     crate fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
184         self.sess.span_diagnostic.struct_span_err(sp, m)
185     }
186
187     crate fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
188         self.sess.span_diagnostic.span_bug(sp, m)
189     }
190
191     crate fn cancel(&self, err: &mut DiagnosticBuilder<'_>) {
192         self.sess.span_diagnostic.cancel(err)
193     }
194
195     crate fn diagnostic(&self) -> &'a errors::Handler {
196         &self.sess.span_diagnostic
197     }
198
199     crate fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
200         let mut err = self.struct_span_err(
201             self.span,
202             &format!("expected identifier, found {}", self.this_token_descr()),
203         );
204         if let token::Ident(ident, false) = &self.token {
205             if ident.is_raw_guess() {
206                 err.span_suggestion(
207                     self.span,
208                     "you can escape reserved keywords to use them as identifiers",
209                     format!("r#{}", ident),
210                     Applicability::MaybeIncorrect,
211                 );
212             }
213         }
214         if let Some(token_descr) = self.token_descr() {
215             err.span_label(self.span, format!("expected identifier, found {}", token_descr));
216         } else {
217             err.span_label(self.span, "expected identifier");
218             if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
219                 err.span_suggestion(
220                     self.span,
221                     "remove this comma",
222                     String::new(),
223                     Applicability::MachineApplicable,
224                 );
225             }
226         }
227         err
228     }
229
230     pub fn expected_one_of_not_found(
231         &mut self,
232         edible: &[token::Token],
233         inedible: &[token::Token],
234     ) -> PResult<'a, bool /* recovered */> {
235         fn tokens_to_string(tokens: &[TokenType]) -> String {
236             let mut i = tokens.iter();
237             // This might be a sign we need a connect method on Iterator.
238             let b = i.next()
239                      .map_or(String::new(), |t| t.to_string());
240             i.enumerate().fold(b, |mut b, (i, a)| {
241                 if tokens.len() > 2 && i == tokens.len() - 2 {
242                     b.push_str(", or ");
243                 } else if tokens.len() == 2 && i == tokens.len() - 2 {
244                     b.push_str(" or ");
245                 } else {
246                     b.push_str(", ");
247                 }
248                 b.push_str(&a.to_string());
249                 b
250             })
251         }
252
253         let mut expected = edible.iter()
254             .map(|x| TokenType::Token(x.clone()))
255             .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
256             .chain(self.expected_tokens.iter().cloned())
257             .collect::<Vec<_>>();
258         expected.sort_by_cached_key(|x| x.to_string());
259         expected.dedup();
260         let expect = tokens_to_string(&expected[..]);
261         let actual = self.this_token_to_string();
262         let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
263             let short_expect = if expected.len() > 6 {
264                 format!("{} possible tokens", expected.len())
265             } else {
266                 expect.clone()
267             };
268             (format!("expected one of {}, found `{}`", expect, actual),
269                 (self.sess.source_map().next_point(self.prev_span),
270                 format!("expected one of {} here", short_expect)))
271         } else if expected.is_empty() {
272             (format!("unexpected token: `{}`", actual),
273                 (self.prev_span, "unexpected token after this".to_string()))
274         } else {
275             (format!("expected {}, found `{}`", expect, actual),
276                 (self.sess.source_map().next_point(self.prev_span),
277                 format!("expected {} here", expect)))
278         };
279         self.last_unexpected_token_span = Some(self.span);
280         let mut err = self.fatal(&msg_exp);
281         if self.token.is_ident_named(sym::and) {
282             err.span_suggestion_short(
283                 self.span,
284                 "use `&&` instead of `and` for the boolean operator",
285                 "&&".to_string(),
286                 Applicability::MaybeIncorrect,
287             );
288         }
289         if self.token.is_ident_named(sym::or) {
290             err.span_suggestion_short(
291                 self.span,
292                 "use `||` instead of `or` for the boolean operator",
293                 "||".to_string(),
294                 Applicability::MaybeIncorrect,
295             );
296         }
297         let sp = if self.token == token::Token::Eof {
298             // This is EOF, don't want to point at the following char, but rather the last token
299             self.prev_span
300         } else {
301             label_sp
302         };
303         match self.recover_closing_delimiter(&expected.iter().filter_map(|tt| match tt {
304             TokenType::Token(t) => Some(t.clone()),
305             _ => None,
306         }).collect::<Vec<_>>(), err) {
307             Err(e) => err = e,
308             Ok(recovered) => {
309                 return Ok(recovered);
310             }
311         }
312
313         let is_semi_suggestable = expected.iter().any(|t| match t {
314             TokenType::Token(token::Semi) => true, // we expect a `;` here
315             _ => false,
316         }) && ( // a `;` would be expected before the current keyword
317             self.token.is_keyword(kw::Break) ||
318             self.token.is_keyword(kw::Continue) ||
319             self.token.is_keyword(kw::For) ||
320             self.token.is_keyword(kw::If) ||
321             self.token.is_keyword(kw::Let) ||
322             self.token.is_keyword(kw::Loop) ||
323             self.token.is_keyword(kw::Match) ||
324             self.token.is_keyword(kw::Return) ||
325             self.token.is_keyword(kw::While)
326         );
327         let cm = self.sess.source_map();
328         match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
329             (Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
330                 // The spans are in different lines, expected `;` and found `let` or `return`.
331                 // High likelihood that it is only a missing `;`.
332                 err.span_suggestion_short(
333                     label_sp,
334                     "a semicolon may be missing here",
335                     ";".to_string(),
336                     Applicability::MaybeIncorrect,
337                 );
338                 err.emit();
339                 return Ok(true);
340             }
341             (Ok(ref a), Ok(ref b)) if a.line == b.line => {
342                 // When the spans are in the same line, it means that the only content between
343                 // them is whitespace, point at the found token in that case:
344                 //
345                 // X |     () => { syntax error };
346                 //   |                    ^^^^^ expected one of 8 possible tokens here
347                 //
348                 // instead of having:
349                 //
350                 // X |     () => { syntax error };
351                 //   |                   -^^^^^ unexpected token
352                 //   |                   |
353                 //   |                   expected one of 8 possible tokens here
354                 err.span_label(self.span, label_exp);
355             }
356             _ if self.prev_span == syntax_pos::DUMMY_SP => {
357                 // Account for macro context where the previous span might not be
358                 // available to avoid incorrect output (#54841).
359                 err.span_label(self.span, "unexpected token");
360             }
361             _ => {
362                 err.span_label(sp, label_exp);
363                 err.span_label(self.span, "unexpected token");
364             }
365         }
366         Err(err)
367     }
368
369     /// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
370     /// passes through any errors encountered. Used for error recovery.
371     crate fn eat_to_tokens(&mut self, kets: &[&token::Token]) {
372         let handler = self.diagnostic();
373
374         if let Err(ref mut err) = self.parse_seq_to_before_tokens(
375             kets,
376             SeqSep::none(),
377             TokenExpectType::Expect,
378             |p| Ok(p.parse_token_tree()),
379         ) {
380             handler.cancel(err);
381         }
382     }
383
384     /// This function checks if there are trailing angle brackets and produces
385     /// a diagnostic to suggest removing them.
386     ///
387     /// ```ignore (diagnostic)
388     /// let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>();
389     ///                                                        ^^ help: remove extra angle brackets
390     /// ```
391     crate fn check_trailing_angle_brackets(&mut self, segment: &PathSegment, end: token::Token) {
392         // This function is intended to be invoked after parsing a path segment where there are two
393         // cases:
394         //
395         // 1. A specific token is expected after the path segment.
396         //    eg. `x.foo(`, `x.foo::<u32>(` (parenthesis - method call),
397         //        `Foo::`, or `Foo::<Bar>::` (mod sep - continued path).
398         // 2. No specific token is expected after the path segment.
399         //    eg. `x.foo` (field access)
400         //
401         // This function is called after parsing `.foo` and before parsing the token `end` (if
402         // present). This includes any angle bracket arguments, such as `.foo::<u32>` or
403         // `Foo::<Bar>`.
404
405         // We only care about trailing angle brackets if we previously parsed angle bracket
406         // arguments. This helps stop us incorrectly suggesting that extra angle brackets be
407         // removed in this case:
408         //
409         // `x.foo >> (3)` (where `x.foo` is a `u32` for example)
410         //
411         // This case is particularly tricky as we won't notice it just looking at the tokens -
412         // it will appear the same (in terms of upcoming tokens) as below (since the `::<u32>` will
413         // have already been parsed):
414         //
415         // `x.foo::<u32>>>(3)`
416         let parsed_angle_bracket_args = segment.args
417             .as_ref()
418             .map(|args| args.is_angle_bracketed())
419             .unwrap_or(false);
420
421         debug!(
422             "check_trailing_angle_brackets: parsed_angle_bracket_args={:?}",
423             parsed_angle_bracket_args,
424         );
425         if !parsed_angle_bracket_args {
426             return;
427         }
428
429         // Keep the span at the start so we can highlight the sequence of `>` characters to be
430         // removed.
431         let lo = self.span;
432
433         // We need to look-ahead to see if we have `>` characters without moving the cursor forward
434         // (since we might have the field access case and the characters we're eating are
435         // actual operators and not trailing characters - ie `x.foo >> 3`).
436         let mut position = 0;
437
438         // We can encounter `>` or `>>` tokens in any order, so we need to keep track of how
439         // many of each (so we can correctly pluralize our error messages) and continue to
440         // advance.
441         let mut number_of_shr = 0;
442         let mut number_of_gt = 0;
443         while self.look_ahead(position, |t| {
444             trace!("check_trailing_angle_brackets: t={:?}", t);
445             if *t == token::BinOp(token::BinOpToken::Shr) {
446                 number_of_shr += 1;
447                 true
448             } else if *t == token::Gt {
449                 number_of_gt += 1;
450                 true
451             } else {
452                 false
453             }
454         }) {
455             position += 1;
456         }
457
458         // If we didn't find any trailing `>` characters, then we have nothing to error about.
459         debug!(
460             "check_trailing_angle_brackets: number_of_gt={:?} number_of_shr={:?}",
461             number_of_gt, number_of_shr,
462         );
463         if number_of_gt < 1 && number_of_shr < 1 {
464             return;
465         }
466
467         // Finally, double check that we have our end token as otherwise this is the
468         // second case.
469         if self.look_ahead(position, |t| {
470             trace!("check_trailing_angle_brackets: t={:?}", t);
471             *t == end
472         }) {
473             // Eat from where we started until the end token so that parsing can continue
474             // as if we didn't have those extra angle brackets.
475             self.eat_to_tokens(&[&end]);
476             let span = lo.until(self.span);
477
478             let plural = number_of_gt > 1 || number_of_shr >= 1;
479             self.diagnostic()
480                 .struct_span_err(
481                     span,
482                     &format!("unmatched angle bracket{}", if plural { "s" } else { "" }),
483                 )
484                 .span_suggestion(
485                     span,
486                     &format!("remove extra angle bracket{}", if plural { "s" } else { "" }),
487                     String::new(),
488                     Applicability::MachineApplicable,
489                 )
490                 .emit();
491         }
492     }
493
494     /// Produce an error if comparison operators are chained (RFC #558).
495     /// We only need to check lhs, not rhs, because all comparison ops
496     /// have same precedence and are left-associative
497     crate fn check_no_chained_comparison(&self, lhs: &Expr, outer_op: &AssocOp) {
498         debug_assert!(outer_op.is_comparison(),
499                       "check_no_chained_comparison: {:?} is not comparison",
500                       outer_op);
501         match lhs.node {
502             ExprKind::Binary(op, _, _) if op.node.is_comparison() => {
503                 // respan to include both operators
504                 let op_span = op.span.to(self.span);
505                 let mut err = self.diagnostic().struct_span_err(op_span,
506                     "chained comparison operators require parentheses");
507                 if op.node == BinOpKind::Lt &&
508                     *outer_op == AssocOp::Less ||  // Include `<` to provide this recommendation
509                     *outer_op == AssocOp::Greater  // even in a case like the following:
510                 {                                  //     Foo<Bar<Baz<Qux, ()>>>
511                     err.help(
512                         "use `::<...>` instead of `<...>` if you meant to specify type arguments");
513                     err.help("or use `(...)` if you meant to specify fn arguments");
514                 }
515                 err.emit();
516             }
517             _ => {}
518         }
519     }
520
521     crate fn maybe_report_ambiguous_plus(
522         &mut self,
523         allow_plus: bool,
524         impl_dyn_multi: bool,
525         ty: &Ty,
526     ) {
527         if !allow_plus && impl_dyn_multi {
528             let sum_with_parens = format!("({})", pprust::ty_to_string(&ty));
529             self.struct_span_err(ty.span, "ambiguous `+` in a type")
530                 .span_suggestion(
531                     ty.span,
532                     "use parentheses to disambiguate",
533                     sum_with_parens,
534                     Applicability::MachineApplicable,
535                 )
536                 .emit();
537         }
538     }
539
540     crate fn maybe_report_invalid_custom_discriminants(
541         &mut self,
542         discriminant_spans: Vec<Span>,
543         variants: &[Spanned<ast::Variant_>],
544     ) {
545         let has_fields = variants.iter().any(|variant| match variant.node.data {
546             VariantData::Tuple(..) | VariantData::Struct(..) => true,
547             VariantData::Unit(..) => false,
548         });
549
550         if !discriminant_spans.is_empty() && has_fields {
551             let mut err = self.struct_span_err(
552                 discriminant_spans.clone(),
553                 "custom discriminant values are not allowed in enums with fields",
554             );
555             for sp in discriminant_spans {
556                 err.span_label(sp, "invalid custom discriminant");
557             }
558             for variant in variants.iter() {
559                 if let VariantData::Struct(fields, ..) | VariantData::Tuple(fields, ..) =
560                     &variant.node.data
561                 {
562                     let fields = if fields.len() > 1 {
563                         "fields"
564                     } else {
565                         "a field"
566                     };
567                     err.span_label(
568                         variant.span,
569                         &format!("variant with {fields} defined here", fields = fields),
570                     );
571
572                 }
573             }
574             err.emit();
575         }
576     }
577
578     crate fn maybe_recover_from_bad_type_plus(
579         &mut self,
580         allow_plus: bool,
581         ty: &Ty,
582     ) -> PResult<'a, ()> {
583         // Do not add `+` to expected tokens.
584         if !allow_plus || !self.token.is_like_plus() {
585             return Ok(());
586         }
587
588         self.bump(); // `+`
589         let bounds = self.parse_generic_bounds(None)?;
590         let sum_span = ty.span.to(self.prev_span);
591
592         let mut err = struct_span_err!(
593             self.sess.span_diagnostic,
594             sum_span,
595             E0178,
596             "expected a path on the left-hand side of `+`, not `{}`",
597             pprust::ty_to_string(ty)
598         );
599
600         match ty.node {
601             TyKind::Rptr(ref lifetime, ref mut_ty) => {
602                 let sum_with_parens = pprust::to_string(|s| {
603                     use crate::print::pprust::PrintState;
604
605                     s.s.word("&")?;
606                     s.print_opt_lifetime(lifetime)?;
607                     s.print_mutability(mut_ty.mutbl)?;
608                     s.popen()?;
609                     s.print_type(&mut_ty.ty)?;
610                     s.print_type_bounds(" +", &bounds)?;
611                     s.pclose()
612                 });
613                 err.span_suggestion(
614                     sum_span,
615                     "try adding parentheses",
616                     sum_with_parens,
617                     Applicability::MachineApplicable,
618                 );
619             }
620             TyKind::Ptr(..) | TyKind::BareFn(..) => {
621                 err.span_label(sum_span, "perhaps you forgot parentheses?");
622             }
623             _ => {
624                 err.span_label(sum_span, "expected a path");
625             }
626         }
627         err.emit();
628         Ok(())
629     }
630
631     /// Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
632     /// Attempt to convert the base expression/pattern/type into a type, parse the `::AssocItem`
633     /// tail, and combine them into a `<Ty>::AssocItem` expression/pattern/type.
634     crate fn maybe_recover_from_bad_qpath<T: RecoverQPath>(
635         &mut self,
636         base: P<T>,
637         allow_recovery: bool,
638     ) -> PResult<'a, P<T>> {
639         // Do not add `::` to expected tokens.
640         if allow_recovery && self.token == token::ModSep {
641             if let Some(ty) = base.to_ty() {
642                 return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
643             }
644         }
645         Ok(base)
646     }
647
648     /// Given an already parsed `Ty` parse the `::AssocItem` tail and
649     /// combine them into a `<Ty>::AssocItem` expression/pattern/type.
650     crate fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
651         &mut self,
652         ty_span: Span,
653         ty: P<Ty>,
654     ) -> PResult<'a, P<T>> {
655         self.expect(&token::ModSep)?;
656
657         let mut path = ast::Path {
658             segments: Vec::new(),
659             span: DUMMY_SP,
660         };
661         self.parse_path_segments(&mut path.segments, T::PATH_STYLE)?;
662         path.span = ty_span.to(self.prev_span);
663
664         let ty_str = self
665             .sess
666             .source_map()
667             .span_to_snippet(ty_span)
668             .unwrap_or_else(|_| pprust::ty_to_string(&ty));
669         self.diagnostic()
670             .struct_span_err(path.span, "missing angle brackets in associated item path")
671             .span_suggestion(
672                 // this is a best-effort recovery
673                 path.span,
674                 "try",
675                 format!("<{}>::{}", ty_str, path),
676                 Applicability::MaybeIncorrect,
677             )
678             .emit();
679
680         let path_span = ty_span.shrink_to_hi(); // use an empty path since `position` == 0
681         Ok(P(T::recovered(
682             Some(QSelf {
683                 ty,
684                 path_span,
685                 position: 0,
686             }),
687             path,
688         )))
689     }
690
691     crate fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
692         if self.eat(&token::Semi) {
693             let mut err = self.struct_span_err(self.prev_span, "expected item, found `;`");
694             err.span_suggestion_short(
695                 self.prev_span,
696                 "remove this semicolon",
697                 String::new(),
698                 Applicability::MachineApplicable,
699             );
700             if !items.is_empty() {
701                 let previous_item = &items[items.len() - 1];
702                 let previous_item_kind_name = match previous_item.node {
703                     // say "braced struct" because tuple-structs and
704                     // braceless-empty-struct declarations do take a semicolon
705                     ItemKind::Struct(..) => Some("braced struct"),
706                     ItemKind::Enum(..) => Some("enum"),
707                     ItemKind::Trait(..) => Some("trait"),
708                     ItemKind::Union(..) => Some("union"),
709                     _ => None,
710                 };
711                 if let Some(name) = previous_item_kind_name {
712                     err.help(&format!(
713                         "{} declarations are not followed by a semicolon",
714                         name
715                     ));
716                 }
717             }
718             err.emit();
719             true
720         } else {
721             false
722         }
723     }
724
725     /// Create a `DiagnosticBuilder` for an unexpected token `t` and try to recover if it is a
726     /// closing delimiter.
727     pub fn unexpected_try_recover(
728         &mut self,
729         t: &token::Token,
730     ) -> PResult<'a, bool /* recovered */> {
731         let token_str = pprust::token_to_string(t);
732         let this_token_str = self.this_token_descr();
733         let (prev_sp, sp) = match (&self.token, self.subparser_name) {
734             // Point at the end of the macro call when reaching end of macro arguments.
735             (token::Token::Eof, Some(_)) => {
736                 let sp = self.sess.source_map().next_point(self.span);
737                 (sp, sp)
738             }
739             // We don't want to point at the following span after DUMMY_SP.
740             // This happens when the parser finds an empty TokenStream.
741             _ if self.prev_span == DUMMY_SP => (self.span, self.span),
742             // EOF, don't want to point at the following char, but rather the last token.
743             (token::Token::Eof, None) => (self.prev_span, self.span),
744             _ => (self.sess.source_map().next_point(self.prev_span), self.span),
745         };
746         let msg = format!(
747             "expected `{}`, found {}",
748             token_str,
749             match (&self.token, self.subparser_name) {
750                 (token::Token::Eof, Some(origin)) => format!("end of {}", origin),
751                 _ => this_token_str,
752             },
753         );
754         let mut err = self.struct_span_err(sp, &msg);
755         let label_exp = format!("expected `{}`", token_str);
756         match self.recover_closing_delimiter(&[t.clone()], err) {
757             Err(e) => err = e,
758             Ok(recovered) => {
759                 return Ok(recovered);
760             }
761         }
762         let cm = self.sess.source_map();
763         match (cm.lookup_line(prev_sp.lo()), cm.lookup_line(sp.lo())) {
764             (Ok(ref a), Ok(ref b)) if a.line == b.line => {
765                 // When the spans are in the same line, it means that the only content
766                 // between them is whitespace, point only at the found token.
767                 err.span_label(sp, label_exp);
768             }
769             _ => {
770                 err.span_label(prev_sp, label_exp);
771                 err.span_label(sp, "unexpected token");
772             }
773         }
774         Err(err)
775     }
776
777     /// Consume alternative await syntaxes like `await <expr>`, `await? <expr>`, `await(<expr>)`
778     /// and `await { <expr> }`.
779     crate fn parse_incorrect_await_syntax(
780         &mut self,
781         lo: Span,
782         await_sp: Span,
783     ) -> PResult<'a, (Span, ExprKind)> {
784         let is_question = self.eat(&token::Question); // Handle `await? <expr>`.
785         let expr = if self.token == token::OpenDelim(token::Brace) {
786             // Handle `await { <expr> }`.
787             // This needs to be handled separatedly from the next arm to avoid
788             // interpreting `await { <expr> }?` as `<expr>?.await`.
789             self.parse_block_expr(
790                 None,
791                 self.span,
792                 BlockCheckMode::Default,
793                 ThinVec::new(),
794             )
795         } else {
796             self.parse_expr()
797         }.map_err(|mut err| {
798             err.span_label(await_sp, "while parsing this incorrect await expression");
799             err
800         })?;
801         let expr_str = self.sess.source_map().span_to_snippet(expr.span)
802             .unwrap_or_else(|_| pprust::expr_to_string(&expr));
803         let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" });
804         let sp = lo.to(expr.span);
805         let app = match expr.node {
806             ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
807             _ => Applicability::MachineApplicable,
808         };
809         self.struct_span_err(sp, "incorrect use of `await`")
810             .span_suggestion(sp, "`await` is a postfix operation", suggestion, app)
811             .emit();
812         Ok((sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr)))
813     }
814
815     /// If encountering `future.await()`, consume and emit error.
816     crate fn recover_from_await_method_call(&mut self) {
817         if self.token == token::OpenDelim(token::Paren) &&
818             self.look_ahead(1, |t| t == &token::CloseDelim(token::Paren))
819         {
820             // future.await()
821             let lo = self.span;
822             self.bump(); // (
823             let sp = lo.to(self.span);
824             self.bump(); // )
825             self.struct_span_err(sp, "incorrect use of `await`")
826                 .span_suggestion(
827                     sp,
828                     "`await` is not a method call, remove the parentheses",
829                     String::new(),
830                     Applicability::MachineApplicable,
831                 ).emit()
832         }
833     }
834
835     crate fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool {
836         self.token.is_ident() &&
837             if let ast::ExprKind::Path(..) = node { true } else { false } &&
838             !self.token.is_reserved_ident() &&           // v `foo:bar(baz)`
839             self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) ||
840             self.look_ahead(1, |t| t == &token::Lt) &&     // `foo:bar<baz`
841             self.look_ahead(2, |t| t.is_ident()) ||
842             self.look_ahead(1, |t| t == &token::Colon) &&  // `foo:bar:baz`
843             self.look_ahead(2, |t| t.is_ident()) ||
844             self.look_ahead(1, |t| t == &token::ModSep) &&  // `foo:bar::baz`
845             self.look_ahead(2, |t| t.is_ident())
846     }
847
848     crate fn bad_type_ascription(
849         &self,
850         err: &mut DiagnosticBuilder<'a>,
851         lhs_span: Span,
852         cur_op_span: Span,
853         next_sp: Span,
854         maybe_path: bool,
855     ) {
856         err.span_label(self.span, "expecting a type here because of type ascription");
857         let cm = self.sess.source_map();
858         let next_pos = cm.lookup_char_pos(next_sp.lo());
859         let op_pos = cm.lookup_char_pos(cur_op_span.hi());
860         if op_pos.line != next_pos.line {
861             err.span_suggestion(
862                 cur_op_span,
863                 "try using a semicolon",
864                 ";".to_string(),
865                 Applicability::MaybeIncorrect,
866             );
867         } else {
868             if maybe_path {
869                 err.span_suggestion(
870                     cur_op_span,
871                     "maybe you meant to write a path separator here",
872                     "::".to_string(),
873                     Applicability::MaybeIncorrect,
874                 );
875             } else {
876                 err.note("#![feature(type_ascription)] lets you annotate an \
877                           expression with a type: `<expr>: <type>`")
878                     .span_note(
879                         lhs_span,
880                         "this expression expects an ascribed type after the colon",
881                     )
882                     .help("this might be indicative of a syntax error elsewhere");
883             }
884         }
885     }
886
887     crate fn recover_seq_parse_error(
888         &mut self,
889         delim: token::DelimToken,
890         lo: Span,
891         result: PResult<'a, P<Expr>>,
892     ) -> P<Expr> {
893         match result {
894             Ok(x) => x,
895             Err(mut err) => {
896                 err.emit();
897                 // recover from parse error
898                 self.consume_block(delim);
899                 self.mk_expr(lo.to(self.prev_span), ExprKind::Err, ThinVec::new())
900             }
901         }
902     }
903
904     crate fn recover_closing_delimiter(
905         &mut self,
906         tokens: &[token::Token],
907         mut err: DiagnosticBuilder<'a>,
908     ) -> PResult<'a, bool> {
909         let mut pos = None;
910         // we want to use the last closing delim that would apply
911         for (i, unmatched) in self.unclosed_delims.iter().enumerate().rev() {
912             if tokens.contains(&token::CloseDelim(unmatched.expected_delim))
913                 && Some(self.span) > unmatched.unclosed_span
914             {
915                 pos = Some(i);
916             }
917         }
918         match pos {
919             Some(pos) => {
920                 // Recover and assume that the detected unclosed delimiter was meant for
921                 // this location. Emit the diagnostic and act as if the delimiter was
922                 // present for the parser's sake.
923
924                  // Don't attempt to recover from this unclosed delimiter more than once.
925                 let unmatched = self.unclosed_delims.remove(pos);
926                 let delim = TokenType::Token(token::CloseDelim(unmatched.expected_delim));
927
928                  // We want to suggest the inclusion of the closing delimiter where it makes
929                 // the most sense, which is immediately after the last token:
930                 //
931                 //  {foo(bar {}}
932                 //      -      ^
933                 //      |      |
934                 //      |      help: `)` may belong here (FIXME: #58270)
935                 //      |
936                 //      unclosed delimiter
937                 if let Some(sp) = unmatched.unclosed_span {
938                     err.span_label(sp, "unclosed delimiter");
939                 }
940                 err.span_suggestion_short(
941                     self.sess.source_map().next_point(self.prev_span),
942                     &format!("{} may belong here", delim.to_string()),
943                     delim.to_string(),
944                     Applicability::MaybeIncorrect,
945                 );
946                 err.emit();
947                 self.expected_tokens.clear();  // reduce errors
948                 Ok(true)
949             }
950             _ => Err(err),
951         }
952     }
953
954     /// Recover from `pub` keyword in places where it seems _reasonable_ but isn't valid.
955     crate fn eat_bad_pub(&mut self) {
956         if self.token.is_keyword(kw::Pub) {
957             match self.parse_visibility(false) {
958                 Ok(vis) => {
959                     self.diagnostic()
960                         .struct_span_err(vis.span, "unnecessary visibility qualifier")
961                         .span_label(vis.span, "`pub` not permitted here")
962                         .emit();
963                 }
964                 Err(mut err) => err.emit(),
965             }
966         }
967     }
968
969     // Eat tokens until we can be relatively sure we reached the end of the
970     // statement. This is something of a best-effort heuristic.
971     //
972     // We terminate when we find an unmatched `}` (without consuming it).
973     crate fn recover_stmt(&mut self) {
974         self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore)
975     }
976
977     // If `break_on_semi` is `Break`, then we will stop consuming tokens after
978     // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
979     // approximate - it can mean we break too early due to macros, but that
980     // should only lead to sub-optimal recovery, not inaccurate parsing).
981     //
982     // If `break_on_block` is `Break`, then we will stop consuming tokens
983     // after finding (and consuming) a brace-delimited block.
984     crate fn recover_stmt_(&mut self, break_on_semi: SemiColonMode, break_on_block: BlockMode) {
985         let mut brace_depth = 0;
986         let mut bracket_depth = 0;
987         let mut in_block = false;
988         debug!("recover_stmt_ enter loop (semi={:?}, block={:?})",
989                break_on_semi, break_on_block);
990         loop {
991             debug!("recover_stmt_ loop {:?}", self.token);
992             match self.token {
993                 token::OpenDelim(token::DelimToken::Brace) => {
994                     brace_depth += 1;
995                     self.bump();
996                     if break_on_block == BlockMode::Break &&
997                        brace_depth == 1 &&
998                        bracket_depth == 0 {
999                         in_block = true;
1000                     }
1001                 }
1002                 token::OpenDelim(token::DelimToken::Bracket) => {
1003                     bracket_depth += 1;
1004                     self.bump();
1005                 }
1006                 token::CloseDelim(token::DelimToken::Brace) => {
1007                     if brace_depth == 0 {
1008                         debug!("recover_stmt_ return - close delim {:?}", self.token);
1009                         break;
1010                     }
1011                     brace_depth -= 1;
1012                     self.bump();
1013                     if in_block && bracket_depth == 0 && brace_depth == 0 {
1014                         debug!("recover_stmt_ return - block end {:?}", self.token);
1015                         break;
1016                     }
1017                 }
1018                 token::CloseDelim(token::DelimToken::Bracket) => {
1019                     bracket_depth -= 1;
1020                     if bracket_depth < 0 {
1021                         bracket_depth = 0;
1022                     }
1023                     self.bump();
1024                 }
1025                 token::Eof => {
1026                     debug!("recover_stmt_ return - Eof");
1027                     break;
1028                 }
1029                 token::Semi => {
1030                     self.bump();
1031                     if break_on_semi == SemiColonMode::Break &&
1032                        brace_depth == 0 &&
1033                        bracket_depth == 0 {
1034                         debug!("recover_stmt_ return - Semi");
1035                         break;
1036                     }
1037                 }
1038                 token::Comma if break_on_semi == SemiColonMode::Comma &&
1039                        brace_depth == 0 &&
1040                        bracket_depth == 0 =>
1041                 {
1042                     debug!("recover_stmt_ return - Semi");
1043                     break;
1044                 }
1045                 _ => {
1046                     self.bump()
1047                 }
1048             }
1049         }
1050     }
1051
1052     crate fn check_for_for_in_in_typo(&mut self, in_span: Span) {
1053         if self.eat_keyword(kw::In) {
1054             // a common typo: `for _ in in bar {}`
1055             let mut err = self.sess.span_diagnostic.struct_span_err(
1056                 self.prev_span,
1057                 "expected iterable, found keyword `in`",
1058             );
1059             err.span_suggestion_short(
1060                 in_span.until(self.prev_span),
1061                 "remove the duplicated `in`",
1062                 String::new(),
1063                 Applicability::MachineApplicable,
1064             );
1065             err.emit();
1066         }
1067     }
1068
1069     crate fn expected_semi_or_open_brace(&mut self) -> PResult<'a, ast::TraitItem> {
1070         let token_str = self.this_token_descr();
1071         let mut err = self.fatal(&format!("expected `;` or `{{`, found {}", token_str));
1072         err.span_label(self.span, "expected `;` or `{`");
1073         Err(err)
1074     }
1075
1076     crate fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
1077         if let token::DocComment(_) = self.token {
1078             let mut err = self.diagnostic().struct_span_err(
1079                 self.span,
1080                 &format!("documentation comments cannot be applied to {}", applied_to),
1081             );
1082             err.span_label(self.span, "doc comments are not allowed here");
1083             err.emit();
1084             self.bump();
1085         } else if self.token == token::Pound && self.look_ahead(1, |t| {
1086             *t == token::OpenDelim(token::Bracket)
1087         }) {
1088             let lo = self.span;
1089             // Skip every token until next possible arg.
1090             while self.token != token::CloseDelim(token::Bracket) {
1091                 self.bump();
1092             }
1093             let sp = lo.to(self.span);
1094             self.bump();
1095             let mut err = self.diagnostic().struct_span_err(
1096                 sp,
1097                 &format!("attributes cannot be applied to {}", applied_to),
1098             );
1099             err.span_label(sp, "attributes are not allowed here");
1100             err.emit();
1101         }
1102     }
1103
1104     crate fn argument_without_type(
1105         &mut self,
1106         err: &mut DiagnosticBuilder<'_>,
1107         pat: P<ast::Pat>,
1108         require_name: bool,
1109         is_trait_item: bool,
1110     ) -> Option<Ident> {
1111         // If we find a pattern followed by an identifier, it could be an (incorrect)
1112         // C-style parameter declaration.
1113         if self.check_ident() && self.look_ahead(1, |t| {
1114             *t == token::Comma || *t == token::CloseDelim(token::Paren)
1115         }) { // `fn foo(String s) {}`
1116             let ident = self.parse_ident().unwrap();
1117             let span = pat.span.with_hi(ident.span.hi());
1118
1119             err.span_suggestion(
1120                 span,
1121                 "declare the type after the parameter binding",
1122                 String::from("<identifier>: <type>"),
1123                 Applicability::HasPlaceholders,
1124             );
1125             return Some(ident);
1126         } else if let PatKind::Ident(_, ident, _) = pat.node {
1127             if require_name && (
1128                 is_trait_item ||
1129                 self.token == token::Comma ||
1130                 self.token == token::CloseDelim(token::Paren)
1131             ) { // `fn foo(a, b) {}` or `fn foo(usize, usize) {}`
1132                 err.span_suggestion(
1133                     pat.span,
1134                     "if this was a parameter name, give it a type",
1135                     format!("{}: TypeName", ident),
1136                     Applicability::HasPlaceholders,
1137                 );
1138                 err.span_suggestion(
1139                     pat.span,
1140                     "if this is a type, explicitly ignore the parameter name",
1141                     format!("_: {}", ident),
1142                     Applicability::MachineApplicable,
1143                 );
1144                 err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
1145                 return Some(ident);
1146             }
1147         }
1148         None
1149     }
1150
1151     crate fn recover_arg_parse(&mut self) -> PResult<'a, (P<ast::Pat>, P<ast::Ty>)> {
1152         let pat = self.parse_pat(Some("argument name"))?;
1153         self.expect(&token::Colon)?;
1154         let ty = self.parse_ty()?;
1155
1156         let mut err = self.diagnostic().struct_span_err_with_code(
1157             pat.span,
1158             "patterns aren't allowed in methods without bodies",
1159             DiagnosticId::Error("E0642".into()),
1160         );
1161         err.span_suggestion_short(
1162             pat.span,
1163             "give this argument a name or use an underscore to ignore it",
1164             "_".to_owned(),
1165             Applicability::MachineApplicable,
1166         );
1167         err.emit();
1168
1169         // Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
1170         let pat = P(Pat {
1171             node: PatKind::Wild,
1172             span: pat.span,
1173             id: ast::DUMMY_NODE_ID
1174         });
1175         Ok((pat, ty))
1176     }
1177
1178     crate fn recover_bad_self_arg(
1179         &mut self,
1180         mut arg: ast::Arg,
1181         is_trait_item: bool,
1182     ) -> PResult<'a, ast::Arg> {
1183         let sp = arg.pat.span;
1184         arg.ty.node = TyKind::Err;
1185         let mut err = self.struct_span_err(sp, "unexpected `self` parameter in function");
1186         if is_trait_item {
1187             err.span_label(sp, "must be the first associated function parameter");
1188         } else {
1189             err.span_label(sp, "not valid as function parameter");
1190             err.note("`self` is only valid as the first parameter of an associated function");
1191         }
1192         err.emit();
1193         Ok(arg)
1194     }
1195
1196     crate fn consume_block(&mut self, delim: token::DelimToken) {
1197         let mut brace_depth = 0;
1198         loop {
1199             if self.eat(&token::OpenDelim(delim)) {
1200                 brace_depth += 1;
1201             } else if self.eat(&token::CloseDelim(delim)) {
1202                 if brace_depth == 0 {
1203                     return;
1204                 } else {
1205                     brace_depth -= 1;
1206                     continue;
1207                 }
1208             } else if self.token == token::Eof || self.eat(&token::CloseDelim(token::NoDelim)) {
1209                 return;
1210             } else {
1211                 self.bump();
1212             }
1213         }
1214     }
1215
1216     crate fn expected_expression_found(&self) -> DiagnosticBuilder<'a> {
1217         let (span, msg) = match (&self.token, self.subparser_name) {
1218             (&token::Token::Eof, Some(origin)) => {
1219                 let sp = self.sess.source_map().next_point(self.span);
1220                 (sp, format!("expected expression, found end of {}", origin))
1221             }
1222             _ => (self.span, format!(
1223                 "expected expression, found {}",
1224                 self.this_token_descr(),
1225             )),
1226         };
1227         let mut err = self.struct_span_err(span, &msg);
1228         let sp = self.sess.source_map().start_point(self.span);
1229         if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
1230             self.sess.expr_parentheses_needed(&mut err, *sp, None);
1231         }
1232         err.span_label(span, "expected expression");
1233         err
1234     }
1235
1236     /// Replace duplicated recovered arguments with `_` pattern to avoid unecessary errors.
1237     ///
1238     /// This is necessary because at this point we don't know whether we parsed a function with
1239     /// anonymous arguments or a function with names but no types. In order to minimize
1240     /// unecessary errors, we assume the arguments are in the shape of `fn foo(a, b, c)` where
1241     /// the arguments are *names* (so we don't emit errors about not being able to find `b` in
1242     /// the local scope), but if we find the same name multiple times, like in `fn foo(i8, i8)`,
1243     /// we deduplicate them to not complain about duplicated argument names.
1244     crate fn deduplicate_recovered_arg_names(&self, fn_inputs: &mut Vec<Arg>) {
1245         let mut seen_inputs = FxHashSet::default();
1246         for input in fn_inputs.iter_mut() {
1247             let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) = (
1248                 &input.pat.node, &input.ty.node,
1249             ) {
1250                 Some(*ident)
1251             } else {
1252                 None
1253             };
1254             if let Some(ident) = opt_ident {
1255                 if seen_inputs.contains(&ident) {
1256                     input.pat.node = PatKind::Wild;
1257                 }
1258                 seen_inputs.insert(ident);
1259             }
1260         }
1261     }
1262 }