1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use rustc_target::spec::abi::{self, Abi};
12 use ast::{AngleBracketedArgs, ParenthesisedArgs, AttrStyle, BareFnTy};
13 use ast::{GenericBound, TraitBoundModifier};
15 use ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind};
17 use ast::{BlockCheckMode, CaptureBy, Movability};
18 use ast::{Constness, Crate};
21 use ast::{Expr, ExprKind, RangeLimits};
22 use ast::{Field, FnDecl, FnHeader};
23 use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
24 use ast::{GenericParam, GenericParamKind};
26 use ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
27 use ast::{Label, Lifetime, Lit, LitKind};
29 use ast::MacStmtStyle;
30 use ast::{Mac, Mac_, MacDelimiter};
31 use ast::{MutTy, Mutability};
32 use ast::{Pat, PatKind, PathSegment};
33 use ast::{PolyTraitRef, QSelf};
34 use ast::{Stmt, StmtKind};
35 use ast::{VariantData, StructField};
38 use ast::{TraitItem, TraitRef, TraitObjectSyntax};
39 use ast::{Ty, TyKind, TypeBinding, GenericBounds};
40 use ast::{Visibility, VisibilityKind, WhereClause, CrateSugar};
41 use ast::{UseTree, UseTreeKind};
42 use ast::{BinOpKind, UnOp};
43 use ast::{RangeEnd, RangeSyntax};
45 use source_map::{self, SourceMap, Spanned, respan};
46 use syntax_pos::{self, Span, MultiSpan, BytePos, FileName};
47 use errors::{self, Applicability, DiagnosticBuilder, DiagnosticId};
48 use parse::{self, SeqSep, classify, token};
49 use parse::lexer::TokenAndSpan;
50 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
51 use parse::token::DelimToken;
52 use parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership};
53 use util::parser::{AssocOp, Fixity};
58 use tokenstream::{self, DelimSpan, ThinTokenStream, TokenTree, TokenStream};
59 use symbol::{Symbol, keywords};
64 use std::path::{self, Path, PathBuf};
68 /// Whether the type alias or associated type is a concrete type or an existential type
70 /// Just a new name for the same type
72 /// Only trait impls of the type will be usable, not the actual type itself
73 Existential(GenericBounds),
77 struct Restrictions: u8 {
78 const STMT_EXPR = 1 << 0;
79 const NO_STRUCT_LITERAL = 1 << 1;
83 type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute>>);
85 /// How to parse a path.
86 #[derive(Copy, Clone, PartialEq)]
88 /// In some contexts, notably in expressions, paths with generic arguments are ambiguous
89 /// with something else. For example, in expressions `segment < ....` can be interpreted
90 /// as a comparison and `segment ( ....` can be interpreted as a function call.
91 /// In all such contexts the non-path interpretation is preferred by default for practical
92 /// reasons, but the path interpretation can be forced by the disambiguator `::`, e.g.
93 /// `x<y>` - comparisons, `x::<y>` - unambiguously a path.
95 /// In other contexts, notably in types, no ambiguity exists and paths can be written
96 /// without the disambiguator, e.g., `x<y>` - unambiguously a path.
97 /// Paths with disambiguators are still accepted, `x::<Y>` - unambiguously a path too.
99 /// A path with generic arguments disallowed, e.g., `foo::bar::Baz`, used in imports,
100 /// visibilities or attributes.
101 /// Technically, this variant is unnecessary and e.g., `Expr` can be used instead
102 /// (paths in "mod" contexts have to be checked later for absence of generic arguments
103 /// anyway, due to macros), but it is used to avoid weird suggestions about expected
104 /// tokens when something goes wrong.
108 #[derive(Clone, Copy, PartialEq, Debug)]
114 #[derive(Clone, Copy, PartialEq, Debug)]
120 /// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
121 /// dropped into the token stream, which happens while parsing the result of
122 /// macro expansion). Placement of these is not as complex as I feared it would
123 /// be. The important thing is to make sure that lookahead doesn't balk at
124 /// `token::Interpolated` tokens.
125 macro_rules! maybe_whole_expr {
127 if let token::Interpolated(nt) = $p.token.clone() {
129 token::NtExpr(ref e) | token::NtLiteral(ref e) => {
131 return Ok((*e).clone());
133 token::NtPath(ref path) => {
136 let kind = ExprKind::Path(None, (*path).clone());
137 return Ok($p.mk_expr(span, kind, ThinVec::new()));
139 token::NtBlock(ref block) => {
142 let kind = ExprKind::Block((*block).clone(), None);
143 return Ok($p.mk_expr(span, kind, ThinVec::new()));
151 /// As maybe_whole_expr, but for things other than expressions
152 macro_rules! maybe_whole {
153 ($p:expr, $constructor:ident, |$x:ident| $e:expr) => {
154 if let token::Interpolated(nt) = $p.token.clone() {
155 if let token::$constructor($x) = nt.0.clone() {
163 fn maybe_append(mut lhs: Vec<Attribute>, mut rhs: Option<Vec<Attribute>>) -> Vec<Attribute> {
164 if let Some(ref mut rhs) = rhs {
170 #[derive(Debug, Clone, Copy, PartialEq)]
181 trait RecoverQPath: Sized {
182 const PATH_STYLE: PathStyle = PathStyle::Expr;
183 fn to_ty(&self) -> Option<P<Ty>>;
184 fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self;
185 fn to_string(&self) -> String;
188 impl RecoverQPath for Ty {
189 const PATH_STYLE: PathStyle = PathStyle::Type;
190 fn to_ty(&self) -> Option<P<Ty>> {
191 Some(P(self.clone()))
193 fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
194 Self { span: path.span, node: TyKind::Path(qself, path), id: self.id }
196 fn to_string(&self) -> String {
197 pprust::ty_to_string(self)
201 impl RecoverQPath for Pat {
202 fn to_ty(&self) -> Option<P<Ty>> {
205 fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
206 Self { span: path.span, node: PatKind::Path(qself, path), id: self.id }
208 fn to_string(&self) -> String {
209 pprust::pat_to_string(self)
213 impl RecoverQPath for Expr {
214 fn to_ty(&self) -> Option<P<Ty>> {
217 fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
218 Self { span: path.span, node: ExprKind::Path(qself, path),
219 id: self.id, attrs: self.attrs.clone() }
221 fn to_string(&self) -> String {
222 pprust::expr_to_string(self)
226 /* ident is handled by common.rs */
229 pub struct Parser<'a> {
230 pub sess: &'a ParseSess,
231 /// the current token:
232 pub token: token::Token,
233 /// the span of the current token:
235 /// the span of the previous token:
236 meta_var_span: Option<Span>,
238 /// the previous token kind
239 prev_token_kind: PrevTokenKind,
240 restrictions: Restrictions,
241 /// Used to determine the path to externally loaded source files
242 crate directory: Directory<'a>,
243 /// Whether to parse sub-modules in other files.
244 pub recurse_into_file_modules: bool,
245 /// Name of the root module this parser originated from. If `None`, then the
246 /// name is not known. This does not change while the parser is descending
247 /// into modules, and sub-parsers have new values for this name.
248 pub root_module_name: Option<String>,
249 crate expected_tokens: Vec<TokenType>,
250 token_cursor: TokenCursor,
251 desugar_doc_comments: bool,
252 /// Whether we should configure out of line modules as we parse.
259 frame: TokenCursorFrame,
260 stack: Vec<TokenCursorFrame>,
264 struct TokenCursorFrame {
265 delim: token::DelimToken,
268 tree_cursor: tokenstream::Cursor,
270 last_token: LastToken,
273 /// This is used in `TokenCursorFrame` above to track tokens that are consumed
274 /// by the parser, and then that's transitively used to record the tokens that
275 /// each parse AST item is created with.
277 /// Right now this has two states, either collecting tokens or not collecting
278 /// tokens. If we're collecting tokens we just save everything off into a local
279 /// `Vec`. This should eventually though likely save tokens from the original
280 /// token stream and just use slicing of token streams to avoid creation of a
281 /// whole new vector.
283 /// The second state is where we're passively not recording tokens, but the last
284 /// token is still tracked for when we want to start recording tokens. This
285 /// "last token" means that when we start recording tokens we'll want to ensure
286 /// that this, the first token, is included in the output.
288 /// You can find some more example usage of this in the `collect_tokens` method
292 Collecting(Vec<TokenStream>),
293 Was(Option<TokenStream>),
296 impl TokenCursorFrame {
297 fn new(sp: DelimSpan, delim: DelimToken, tts: &ThinTokenStream) -> Self {
301 open_delim: delim == token::NoDelim,
302 tree_cursor: tts.stream().into_trees(),
303 close_delim: delim == token::NoDelim,
304 last_token: LastToken::Was(None),
310 fn next(&mut self) -> TokenAndSpan {
312 let tree = if !self.frame.open_delim {
313 self.frame.open_delim = true;
314 TokenTree::open_tt(self.frame.span.open, self.frame.delim)
315 } else if let Some(tree) = self.frame.tree_cursor.next() {
317 } else if !self.frame.close_delim {
318 self.frame.close_delim = true;
319 TokenTree::close_tt(self.frame.span.close, self.frame.delim)
320 } else if let Some(frame) = self.stack.pop() {
324 return TokenAndSpan { tok: token::Eof, sp: syntax_pos::DUMMY_SP }
327 match self.frame.last_token {
328 LastToken::Collecting(ref mut v) => v.push(tree.clone().into()),
329 LastToken::Was(ref mut t) => *t = Some(tree.clone().into()),
333 TokenTree::Token(sp, tok) => return TokenAndSpan { tok: tok, sp: sp },
334 TokenTree::Delimited(sp, delim, tts) => {
335 let frame = TokenCursorFrame::new(sp, delim, &tts);
336 self.stack.push(mem::replace(&mut self.frame, frame));
342 fn next_desugared(&mut self) -> TokenAndSpan {
343 let (sp, name) = match self.next() {
344 TokenAndSpan { sp, tok: token::DocComment(name) } => (sp, name),
348 let stripped = strip_doc_comment_decoration(&name.as_str());
350 // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
351 // required to wrap the text.
352 let mut num_of_hashes = 0;
354 for ch in stripped.chars() {
357 '#' if count > 0 => count + 1,
360 num_of_hashes = cmp::max(num_of_hashes, count);
363 let delim_span = DelimSpan::from_single(sp);
364 let body = TokenTree::Delimited(
367 [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"), false)),
368 TokenTree::Token(sp, token::Eq),
369 TokenTree::Token(sp, token::Literal(
370 token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))
372 .iter().cloned().collect::<TokenStream>().into(),
375 self.stack.push(mem::replace(&mut self.frame, TokenCursorFrame::new(
378 &if doc_comment_style(&name.as_str()) == AttrStyle::Inner {
379 [TokenTree::Token(sp, token::Pound), TokenTree::Token(sp, token::Not), body]
380 .iter().cloned().collect::<TokenStream>().into()
382 [TokenTree::Token(sp, token::Pound), body]
383 .iter().cloned().collect::<TokenStream>().into()
391 #[derive(Clone, PartialEq)]
392 crate enum TokenType {
394 Keyword(keywords::Keyword),
403 fn to_string(&self) -> String {
405 TokenType::Token(ref t) => format!("`{}`", pprust::token_to_string(t)),
406 TokenType::Keyword(kw) => format!("`{}`", kw.name()),
407 TokenType::Operator => "an operator".to_string(),
408 TokenType::Lifetime => "lifetime".to_string(),
409 TokenType::Ident => "identifier".to_string(),
410 TokenType::Path => "path".to_string(),
411 TokenType::Type => "type".to_string(),
416 /// Returns true if `IDENT t` can start a type - `IDENT::a::b`, `IDENT<u8, u8>`,
417 /// `IDENT<<u8 as Trait>::AssocTy>`.
419 /// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes
420 /// that IDENT is not the ident of a fn trait
421 fn can_continue_type_after_non_fn_ident(t: &token::Token) -> bool {
422 t == &token::ModSep || t == &token::Lt ||
423 t == &token::BinOp(token::Shl)
426 /// Information about the path to a module.
427 pub struct ModulePath {
430 pub result: Result<ModulePathSuccess, Error>,
433 pub struct ModulePathSuccess {
435 pub directory_ownership: DirectoryOwnership,
440 FileNotFoundForModule {
442 default_path: String,
443 secondary_path: String,
448 default_path: String,
449 secondary_path: String,
452 InclusiveRangeWithNoEnd,
456 fn span_err<S: Into<MultiSpan>>(self,
458 handler: &errors::Handler) -> DiagnosticBuilder {
460 Error::FileNotFoundForModule { ref mod_name,
464 let mut err = struct_span_err!(handler, sp, E0583,
465 "file not found for module `{}`", mod_name);
466 err.help(&format!("name the file either {} or {} inside the directory \"{}\"",
472 Error::DuplicatePaths { ref mod_name, ref default_path, ref secondary_path } => {
473 let mut err = struct_span_err!(handler, sp, E0584,
474 "file for module `{}` found at both {} and {}",
478 err.help("delete or rename one of them to remove the ambiguity");
481 Error::UselessDocComment => {
482 let mut err = struct_span_err!(handler, sp, E0585,
483 "found a documentation comment that doesn't document anything");
484 err.help("doc comments must come before what they document, maybe a comment was \
485 intended with `//`?");
488 Error::InclusiveRangeWithNoEnd => {
489 let mut err = struct_span_err!(handler, sp, E0586,
490 "inclusive range with no end");
491 err.help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)");
501 AttributesParsed(ThinVec<Attribute>),
502 AlreadyParsed(P<Expr>),
505 impl From<Option<ThinVec<Attribute>>> for LhsExpr {
506 fn from(o: Option<ThinVec<Attribute>>) -> Self {
507 if let Some(attrs) = o {
508 LhsExpr::AttributesParsed(attrs)
510 LhsExpr::NotYetParsed
515 impl From<P<Expr>> for LhsExpr {
516 fn from(expr: P<Expr>) -> Self {
517 LhsExpr::AlreadyParsed(expr)
521 /// Create a placeholder argument.
522 fn dummy_arg(span: Span) -> Arg {
523 let ident = Ident::new(keywords::Invalid.name(), span);
525 id: ast::DUMMY_NODE_ID,
526 node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None),
532 id: ast::DUMMY_NODE_ID
534 Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID }
537 #[derive(Copy, Clone, Debug)]
538 enum TokenExpectType {
543 impl<'a> Parser<'a> {
544 pub fn new(sess: &'a ParseSess,
546 directory: Option<Directory<'a>>,
547 recurse_into_file_modules: bool,
548 desugar_doc_comments: bool)
550 let mut parser = Parser {
552 token: token::Whitespace,
553 span: syntax_pos::DUMMY_SP,
554 prev_span: syntax_pos::DUMMY_SP,
556 prev_token_kind: PrevTokenKind::Other,
557 restrictions: Restrictions::empty(),
558 recurse_into_file_modules,
559 directory: Directory {
560 path: Cow::from(PathBuf::new()),
561 ownership: DirectoryOwnership::Owned { relative: None }
563 root_module_name: None,
564 expected_tokens: Vec::new(),
565 token_cursor: TokenCursor {
566 frame: TokenCursorFrame::new(
573 desugar_doc_comments,
577 let tok = parser.next_tok();
578 parser.token = tok.tok;
579 parser.span = tok.sp;
581 if let Some(directory) = directory {
582 parser.directory = directory;
583 } else if !parser.span.is_dummy() {
584 if let FileName::Real(mut path) = sess.source_map().span_to_unmapped_path(parser.span) {
586 parser.directory.path = Cow::from(path);
590 parser.process_potential_macro_variable();
594 fn next_tok(&mut self) -> TokenAndSpan {
595 let mut next = if self.desugar_doc_comments {
596 self.token_cursor.next_desugared()
598 self.token_cursor.next()
600 if next.sp.is_dummy() {
601 // Tweak the location for better diagnostics, but keep syntactic context intact.
602 next.sp = self.prev_span.with_ctxt(next.sp.ctxt());
607 /// Convert the current token to a string using self's reader
608 pub fn this_token_to_string(&self) -> String {
609 pprust::token_to_string(&self.token)
612 fn token_descr(&self) -> Option<&'static str> {
613 Some(match &self.token {
614 t if t.is_special_ident() => "reserved identifier",
615 t if t.is_used_keyword() => "keyword",
616 t if t.is_unused_keyword() => "reserved keyword",
617 token::DocComment(..) => "doc comment",
622 fn this_token_descr(&self) -> String {
623 if let Some(prefix) = self.token_descr() {
624 format!("{} `{}`", prefix, self.this_token_to_string())
626 format!("`{}`", self.this_token_to_string())
630 fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
631 let token_str = pprust::token_to_string(t);
632 Err(self.span_fatal(self.prev_span, &format!("unexpected token: `{}`", token_str)))
635 crate fn unexpected<T>(&mut self) -> PResult<'a, T> {
636 match self.expect_one_of(&[], &[]) {
638 Ok(_) => unreachable!(),
642 /// Expect and consume the token t. Signal an error if
643 /// the next token is not t.
644 pub fn expect(&mut self, t: &token::Token) -> PResult<'a, ()> {
645 if self.expected_tokens.is_empty() {
646 if self.token == *t {
650 let token_str = pprust::token_to_string(t);
651 let this_token_str = self.this_token_descr();
652 let mut err = self.fatal(&format!("expected `{}`, found {}",
656 let sp = if self.token == token::Token::Eof {
657 // EOF, don't want to point at the following char, but rather the last token
660 self.sess.source_map().next_point(self.prev_span)
662 let label_exp = format!("expected `{}`", token_str);
663 let cm = self.sess.source_map();
664 match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
665 (Ok(ref a), Ok(ref b)) if a.line == b.line => {
666 // When the spans are in the same line, it means that the only content
667 // between them is whitespace, point only at the found token.
668 err.span_label(self.span, label_exp);
671 err.span_label(sp, label_exp);
672 err.span_label(self.span, "unexpected token");
678 self.expect_one_of(slice::from_ref(t), &[])
682 /// Expect next token to be edible or inedible token. If edible,
683 /// then consume it; if inedible, then return without consuming
684 /// anything. Signal a fatal error if next token is unexpected.
685 pub fn expect_one_of(&mut self,
686 edible: &[token::Token],
687 inedible: &[token::Token]) -> PResult<'a, ()>{
688 fn tokens_to_string(tokens: &[TokenType]) -> String {
689 let mut i = tokens.iter();
690 // This might be a sign we need a connect method on Iterator.
692 .map_or(String::new(), |t| t.to_string());
693 i.enumerate().fold(b, |mut b, (i, a)| {
694 if tokens.len() > 2 && i == tokens.len() - 2 {
696 } else if tokens.len() == 2 && i == tokens.len() - 2 {
701 b.push_str(&a.to_string());
705 if edible.contains(&self.token) {
708 } else if inedible.contains(&self.token) {
709 // leave it in the input
712 let mut expected = edible.iter()
713 .map(|x| TokenType::Token(x.clone()))
714 .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
715 .chain(self.expected_tokens.iter().cloned())
716 .collect::<Vec<_>>();
717 expected.sort_by_cached_key(|x| x.to_string());
719 let expect = tokens_to_string(&expected[..]);
720 let actual = self.this_token_to_string();
721 let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
722 let short_expect = if expected.len() > 6 {
723 format!("{} possible tokens", expected.len())
727 (format!("expected one of {}, found `{}`", expect, actual),
728 (self.sess.source_map().next_point(self.prev_span),
729 format!("expected one of {} here", short_expect)))
730 } else if expected.is_empty() {
731 (format!("unexpected token: `{}`", actual),
732 (self.prev_span, "unexpected token after this".to_string()))
734 (format!("expected {}, found `{}`", expect, actual),
735 (self.sess.source_map().next_point(self.prev_span),
736 format!("expected {} here", expect)))
738 let mut err = self.fatal(&msg_exp);
739 if self.token.is_ident_named("and") {
740 err.span_suggestion_short_with_applicability(
742 "use `&&` instead of `and` for the boolean operator",
744 Applicability::MaybeIncorrect,
747 if self.token.is_ident_named("or") {
748 err.span_suggestion_short_with_applicability(
750 "use `||` instead of `or` for the boolean operator",
752 Applicability::MaybeIncorrect,
755 let sp = if self.token == token::Token::Eof {
756 // This is EOF, don't want to point at the following char, but rather the last token
762 let cm = self.sess.source_map();
763 match (cm.lookup_line(self.span.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 between
766 // them is whitespace, point at the found token in that case:
768 // X | () => { syntax error };
769 // | ^^^^^ expected one of 8 possible tokens here
771 // instead of having:
773 // X | () => { syntax error };
774 // | -^^^^^ unexpected token
776 // | expected one of 8 possible tokens here
777 err.span_label(self.span, label_exp);
779 _ if self.prev_span == syntax_pos::DUMMY_SP => {
780 // Account for macro context where the previous span might not be
781 // available to avoid incorrect output (#54841).
782 err.span_label(self.span, "unexpected token");
785 err.span_label(sp, label_exp);
786 err.span_label(self.span, "unexpected token");
793 /// returns the span of expr, if it was not interpolated or the span of the interpolated token
794 fn interpolated_or_expr_span(&self,
795 expr: PResult<'a, P<Expr>>)
796 -> PResult<'a, (Span, P<Expr>)> {
798 if self.prev_token_kind == PrevTokenKind::Interpolated {
806 fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
807 let mut err = self.struct_span_err(self.span,
808 &format!("expected identifier, found {}",
809 self.this_token_descr()));
810 if let Some(token_descr) = self.token_descr() {
811 err.span_label(self.span, format!("expected identifier, found {}", token_descr));
813 err.span_label(self.span, "expected identifier");
814 if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
815 err.span_suggestion_with_applicability(
819 Applicability::MachineApplicable,
826 pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
827 self.parse_ident_common(true)
830 fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
832 token::Ident(ident, _) => {
833 if self.token.is_reserved_ident() {
834 let mut err = self.expected_ident_found();
841 let span = self.span;
843 Ok(Ident::new(ident.name, span))
846 Err(if self.prev_token_kind == PrevTokenKind::DocComment {
847 self.span_fatal_err(self.prev_span, Error::UselessDocComment)
849 self.expected_ident_found()
855 /// Check if the next token is `tok`, and return `true` if so.
857 /// This method will automatically add `tok` to `expected_tokens` if `tok` is not
859 crate fn check(&mut self, tok: &token::Token) -> bool {
860 let is_present = self.token == *tok;
861 if !is_present { self.expected_tokens.push(TokenType::Token(tok.clone())); }
865 /// Consume token 'tok' if it exists. Returns true if the given
866 /// token was present, false otherwise.
867 pub fn eat(&mut self, tok: &token::Token) -> bool {
868 let is_present = self.check(tok);
869 if is_present { self.bump() }
873 fn check_keyword(&mut self, kw: keywords::Keyword) -> bool {
874 self.expected_tokens.push(TokenType::Keyword(kw));
875 self.token.is_keyword(kw)
878 /// If the next token is the given keyword, eat it and return
879 /// true. Otherwise, return false.
880 pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
881 if self.check_keyword(kw) {
889 fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> bool {
890 if self.token.is_keyword(kw) {
898 /// If the given word is not a keyword, signal an error.
899 /// If the next token is not the given word, signal an error.
900 /// Otherwise, eat it.
901 fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, ()> {
902 if !self.eat_keyword(kw) {
909 fn check_ident(&mut self) -> bool {
910 if self.token.is_ident() {
913 self.expected_tokens.push(TokenType::Ident);
918 fn check_path(&mut self) -> bool {
919 if self.token.is_path_start() {
922 self.expected_tokens.push(TokenType::Path);
927 fn check_type(&mut self) -> bool {
928 if self.token.can_begin_type() {
931 self.expected_tokens.push(TokenType::Type);
936 /// Expect and consume a `+`. if `+=` is seen, replace it with a `=`
937 /// and continue. If a `+` is not seen, return false.
939 /// This is using when token splitting += into +.
940 /// See issue 47856 for an example of when this may occur.
941 fn eat_plus(&mut self) -> bool {
942 self.expected_tokens.push(TokenType::Token(token::BinOp(token::Plus)));
944 token::BinOp(token::Plus) => {
948 token::BinOpEq(token::Plus) => {
949 let span = self.span.with_lo(self.span.lo() + BytePos(1));
950 self.bump_with(token::Eq, span);
958 /// Checks to see if the next token is either `+` or `+=`.
959 /// Otherwise returns false.
960 fn check_plus(&mut self) -> bool {
961 if self.token.is_like_plus() {
965 self.expected_tokens.push(TokenType::Token(token::BinOp(token::Plus)));
970 /// Expect and consume an `&`. If `&&` is seen, replace it with a single
971 /// `&` and continue. If an `&` is not seen, signal an error.
972 fn expect_and(&mut self) -> PResult<'a, ()> {
973 self.expected_tokens.push(TokenType::Token(token::BinOp(token::And)));
975 token::BinOp(token::And) => {
980 let span = self.span.with_lo(self.span.lo() + BytePos(1));
981 Ok(self.bump_with(token::BinOp(token::And), span))
983 _ => self.unexpected()
987 /// Expect and consume an `|`. If `||` is seen, replace it with a single
988 /// `|` and continue. If an `|` is not seen, signal an error.
989 fn expect_or(&mut self) -> PResult<'a, ()> {
990 self.expected_tokens.push(TokenType::Token(token::BinOp(token::Or)));
992 token::BinOp(token::Or) => {
997 let span = self.span.with_lo(self.span.lo() + BytePos(1));
998 Ok(self.bump_with(token::BinOp(token::Or), span))
1000 _ => self.unexpected()
1004 fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<ast::Name>) {
1006 None => {/* everything ok */}
1008 let text = suf.as_str();
1009 if text.is_empty() {
1010 self.span_bug(sp, "found empty literal suffix in Some")
1012 self.span_err(sp, &format!("{} with a suffix is invalid", kind));
1017 /// Attempt to consume a `<`. If `<<` is seen, replace it with a single
1018 /// `<` and continue. If a `<` is not seen, return false.
1020 /// This is meant to be used when parsing generics on a path to get the
1022 fn eat_lt(&mut self) -> bool {
1023 self.expected_tokens.push(TokenType::Token(token::Lt));
1029 token::BinOp(token::Shl) => {
1030 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1031 self.bump_with(token::Lt, span);
1038 fn expect_lt(&mut self) -> PResult<'a, ()> {
1046 /// Expect and consume a GT. if a >> is seen, replace it
1047 /// with a single > and continue. If a GT is not seen,
1048 /// signal an error.
1049 fn expect_gt(&mut self) -> PResult<'a, ()> {
1050 self.expected_tokens.push(TokenType::Token(token::Gt));
1056 token::BinOp(token::Shr) => {
1057 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1058 Ok(self.bump_with(token::Gt, span))
1060 token::BinOpEq(token::Shr) => {
1061 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1062 Ok(self.bump_with(token::Ge, span))
1065 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1066 Ok(self.bump_with(token::Eq, span))
1068 _ => self.unexpected()
1072 /// Eat and discard tokens until one of `kets` is encountered. Respects token trees,
1073 /// passes through any errors encountered. Used for error recovery.
1074 fn eat_to_tokens(&mut self, kets: &[&token::Token]) {
1075 let handler = self.diagnostic();
1077 if let Err(ref mut err) = self.parse_seq_to_before_tokens(kets,
1079 TokenExpectType::Expect,
1080 |p| Ok(p.parse_token_tree())) {
1081 handler.cancel(err);
1085 /// Parse a sequence, including the closing delimiter. The function
1086 /// f must consume tokens until reaching the next separator or
1087 /// closing bracket.
1088 pub fn parse_seq_to_end<T, F>(&mut self,
1092 -> PResult<'a, Vec<T>> where
1093 F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
1095 let val = self.parse_seq_to_before_end(ket, sep, f)?;
1100 /// Parse a sequence, not including the closing delimiter. The function
1101 /// f must consume tokens until reaching the next separator or
1102 /// closing bracket.
1103 pub fn parse_seq_to_before_end<T, F>(&mut self,
1107 -> PResult<'a, Vec<T>>
1108 where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>
1110 self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
1113 fn parse_seq_to_before_tokens<T, F>(
1115 kets: &[&token::Token],
1117 expect: TokenExpectType,
1119 ) -> PResult<'a, Vec<T>>
1120 where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>
1122 let mut first: bool = true;
1124 while !kets.iter().any(|k| {
1126 TokenExpectType::Expect => self.check(k),
1127 TokenExpectType::NoExpect => self.token == **k,
1131 token::CloseDelim(..) | token::Eof => break,
1134 if let Some(ref t) = sep.sep {
1138 if let Err(mut e) = self.expect(t) {
1139 // Attempt to keep parsing if it was a similar separator
1140 if let Some(ref tokens) = t.similar_tokens() {
1141 if tokens.contains(&self.token) {
1146 // Attempt to keep parsing if it was an omitted separator
1160 if sep.trailing_sep_allowed && kets.iter().any(|k| {
1162 TokenExpectType::Expect => self.check(k),
1163 TokenExpectType::NoExpect => self.token == **k,
1176 /// Parse a sequence, including the closing delimiter. The function
1177 /// f must consume tokens until reaching the next separator or
1178 /// closing bracket.
1179 fn parse_unspanned_seq<T, F>(&mut self,
1184 -> PResult<'a, Vec<T>> where
1185 F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
1188 let result = self.parse_seq_to_before_end(ket, sep, f)?;
1193 /// Advance the parser by one token
1194 pub fn bump(&mut self) {
1195 if self.prev_token_kind == PrevTokenKind::Eof {
1196 // Bumping after EOF is a bad sign, usually an infinite loop.
1197 self.bug("attempted to bump the parser past EOF (may be stuck in a loop)");
1200 self.prev_span = self.meta_var_span.take().unwrap_or(self.span);
1202 // Record last token kind for possible error recovery.
1203 self.prev_token_kind = match self.token {
1204 token::DocComment(..) => PrevTokenKind::DocComment,
1205 token::Comma => PrevTokenKind::Comma,
1206 token::BinOp(token::Plus) => PrevTokenKind::Plus,
1207 token::Interpolated(..) => PrevTokenKind::Interpolated,
1208 token::Eof => PrevTokenKind::Eof,
1209 token::Ident(..) => PrevTokenKind::Ident,
1210 _ => PrevTokenKind::Other,
1213 let next = self.next_tok();
1214 self.span = next.sp;
1215 self.token = next.tok;
1216 self.expected_tokens.clear();
1217 // check after each token
1218 self.process_potential_macro_variable();
1221 /// Advance the parser using provided token as a next one. Use this when
1222 /// consuming a part of a token. For example a single `<` from `<<`.
1223 fn bump_with(&mut self, next: token::Token, span: Span) {
1224 self.prev_span = self.span.with_hi(span.lo());
1225 // It would be incorrect to record the kind of the current token, but
1226 // fortunately for tokens currently using `bump_with`, the
1227 // prev_token_kind will be of no use anyway.
1228 self.prev_token_kind = PrevTokenKind::Other;
1231 self.expected_tokens.clear();
1234 pub fn look_ahead<R, F>(&self, dist: usize, f: F) -> R where
1235 F: FnOnce(&token::Token) -> R,
1238 return f(&self.token)
1241 f(&match self.token_cursor.frame.tree_cursor.look_ahead(dist - 1) {
1242 Some(tree) => match tree {
1243 TokenTree::Token(_, tok) => tok,
1244 TokenTree::Delimited(_, delim, _) => token::OpenDelim(delim),
1246 None => token::CloseDelim(self.token_cursor.frame.delim),
1250 fn look_ahead_span(&self, dist: usize) -> Span {
1255 match self.token_cursor.frame.tree_cursor.look_ahead(dist - 1) {
1256 Some(TokenTree::Token(span, _)) => span,
1257 Some(TokenTree::Delimited(span, ..)) => span.entire(),
1258 None => self.look_ahead_span(dist - 1),
1261 pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
1262 self.sess.span_diagnostic.struct_span_fatal(self.span, m)
1264 pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
1265 self.sess.span_diagnostic.struct_span_fatal(sp, m)
1267 fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
1268 err.span_err(sp, self.diagnostic())
1270 fn bug(&self, m: &str) -> ! {
1271 self.sess.span_diagnostic.span_bug(self.span, m)
1273 fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
1274 self.sess.span_diagnostic.span_err(sp, m)
1276 fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
1277 self.sess.span_diagnostic.struct_span_err(sp, m)
1279 crate fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
1280 self.sess.span_diagnostic.span_bug(sp, m)
1282 crate fn abort_if_errors(&self) {
1283 self.sess.span_diagnostic.abort_if_errors();
1286 fn cancel(&self, err: &mut DiagnosticBuilder) {
1287 self.sess.span_diagnostic.cancel(err)
1290 crate fn diagnostic(&self) -> &'a errors::Handler {
1291 &self.sess.span_diagnostic
1294 /// Is the current token one of the keywords that signals a bare function
1296 fn token_is_bare_fn_keyword(&mut self) -> bool {
1297 self.check_keyword(keywords::Fn) ||
1298 self.check_keyword(keywords::Unsafe) ||
1299 self.check_keyword(keywords::Extern) && self.is_extern_non_path()
1302 /// parse a `TyKind::BareFn` type:
1303 fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a, TyKind> {
1306 [unsafe] [extern "ABI"] fn (S) -> T
1316 let unsafety = self.parse_unsafety();
1317 let abi = if self.eat_keyword(keywords::Extern) {
1318 self.parse_opt_abi()?.unwrap_or(Abi::C)
1323 self.expect_keyword(keywords::Fn)?;
1324 let (inputs, variadic) = self.parse_fn_args(false, true)?;
1325 let ret_ty = self.parse_ret_ty(false)?;
1326 let decl = P(FnDecl {
1331 Ok(TyKind::BareFn(P(BareFnTy {
1339 /// Parse asyncness: `async` or nothing
1340 fn parse_asyncness(&mut self) -> IsAsync {
1341 if self.eat_keyword(keywords::Async) {
1343 closure_id: ast::DUMMY_NODE_ID,
1344 return_impl_trait_id: ast::DUMMY_NODE_ID,
1351 /// Parse unsafety: `unsafe` or nothing.
1352 fn parse_unsafety(&mut self) -> Unsafety {
1353 if self.eat_keyword(keywords::Unsafe) {
1360 /// Parse the items in a trait declaration
1361 pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
1362 maybe_whole!(self, NtTraitItem, |x| x);
1363 let attrs = self.parse_outer_attributes()?;
1364 let (mut item, tokens) = self.collect_tokens(|this| {
1365 this.parse_trait_item_(at_end, attrs)
1367 // See `parse_item` for why this clause is here.
1368 if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
1369 item.tokens = Some(tokens);
1374 fn parse_trait_item_(&mut self,
1376 mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> {
1379 let (name, node, generics) = if self.eat_keyword(keywords::Type) {
1380 self.parse_trait_item_assoc_ty()?
1381 } else if self.is_const_item() {
1382 self.expect_keyword(keywords::Const)?;
1383 let ident = self.parse_ident()?;
1384 self.expect(&token::Colon)?;
1385 let ty = self.parse_ty()?;
1386 let default = if self.eat(&token::Eq) {
1387 let expr = self.parse_expr()?;
1388 self.expect(&token::Semi)?;
1391 self.expect(&token::Semi)?;
1394 (ident, TraitItemKind::Const(ty, default), ast::Generics::default())
1395 } else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? {
1396 // trait item macro.
1397 (keywords::Invalid.ident(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
1399 let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
1401 let ident = self.parse_ident()?;
1402 let mut generics = self.parse_generics()?;
1404 let d = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
1405 // This is somewhat dubious; We don't want to allow
1406 // argument names to be left off if there is a
1409 // We don't allow argument names to be left off in edition 2018.
1410 p.parse_arg_general(p.span.rust_2018(), true)
1412 generics.where_clause = self.parse_where_clause()?;
1414 let sig = ast::MethodSig {
1424 let body = match self.token {
1428 debug!("parse_trait_methods(): parsing required method");
1431 token::OpenDelim(token::Brace) => {
1432 debug!("parse_trait_methods(): parsing provided method");
1434 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1435 attrs.extend(inner_attrs.iter().cloned());
1438 token::Interpolated(ref nt) => {
1440 token::NtBlock(..) => {
1442 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1443 attrs.extend(inner_attrs.iter().cloned());
1447 let token_str = self.this_token_descr();
1448 let mut err = self.fatal(&format!("expected `;` or `{{`, found {}",
1450 err.span_label(self.span, "expected `;` or `{`");
1456 let token_str = self.this_token_descr();
1457 let mut err = self.fatal(&format!("expected `;` or `{{`, found {}",
1459 err.span_label(self.span, "expected `;` or `{`");
1463 (ident, ast::TraitItemKind::Method(sig, body), generics)
1467 id: ast::DUMMY_NODE_ID,
1472 span: lo.to(self.prev_span),
1477 /// Parse optional return type [ -> TY ] in function decl
1478 fn parse_ret_ty(&mut self, allow_plus: bool) -> PResult<'a, FunctionRetTy> {
1479 if self.eat(&token::RArrow) {
1480 Ok(FunctionRetTy::Ty(self.parse_ty_common(allow_plus, true)?))
1482 Ok(FunctionRetTy::Default(self.span.shrink_to_lo()))
1487 pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
1488 self.parse_ty_common(true, true)
1491 /// Parse a type in restricted contexts where `+` is not permitted.
1492 /// Example 1: `&'a TYPE`
1493 /// `+` is prohibited to maintain operator priority (P(+) < P(&)).
1494 /// Example 2: `value1 as TYPE + value2`
1495 /// `+` is prohibited to avoid interactions with expression grammar.
1496 fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
1497 self.parse_ty_common(false, true)
1500 fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
1501 -> PResult<'a, P<Ty>> {
1502 maybe_whole!(self, NtTy, |x| x);
1505 let mut impl_dyn_multi = false;
1506 let node = if self.eat(&token::OpenDelim(token::Paren)) {
1507 // `(TYPE)` is a parenthesized type.
1508 // `(TYPE,)` is a tuple with a single field of type TYPE.
1509 let mut ts = vec![];
1510 let mut last_comma = false;
1511 while self.token != token::CloseDelim(token::Paren) {
1512 ts.push(self.parse_ty()?);
1513 if self.eat(&token::Comma) {
1520 let trailing_plus = self.prev_token_kind == PrevTokenKind::Plus;
1521 self.expect(&token::CloseDelim(token::Paren))?;
1523 if ts.len() == 1 && !last_comma {
1524 let ty = ts.into_iter().nth(0).unwrap().into_inner();
1525 let maybe_bounds = allow_plus && self.token.is_like_plus();
1527 // `(TY_BOUND_NOPAREN) + BOUND + ...`.
1528 TyKind::Path(None, ref path) if maybe_bounds => {
1529 self.parse_remaining_bounds(Vec::new(), path.clone(), lo, true)?
1531 TyKind::TraitObject(ref bounds, TraitObjectSyntax::None)
1532 if maybe_bounds && bounds.len() == 1 && !trailing_plus => {
1533 let path = match bounds[0] {
1534 GenericBound::Trait(ref pt, ..) => pt.trait_ref.path.clone(),
1535 GenericBound::Outlives(..) => self.bug("unexpected lifetime bound"),
1537 self.parse_remaining_bounds(Vec::new(), path, lo, true)?
1540 _ => TyKind::Paren(P(ty))
1545 } else if self.eat(&token::Not) {
1548 } else if self.eat(&token::BinOp(token::Star)) {
1550 TyKind::Ptr(self.parse_ptr()?)
1551 } else if self.eat(&token::OpenDelim(token::Bracket)) {
1553 let t = self.parse_ty()?;
1554 // Parse optional `; EXPR` in `[TYPE; EXPR]`
1555 let t = match self.maybe_parse_fixed_length_of_vec()? {
1556 None => TyKind::Slice(t),
1557 Some(length) => TyKind::Array(t, AnonConst {
1558 id: ast::DUMMY_NODE_ID,
1562 self.expect(&token::CloseDelim(token::Bracket))?;
1564 } else if self.check(&token::BinOp(token::And)) || self.check(&token::AndAnd) {
1567 self.parse_borrowed_pointee()?
1568 } else if self.eat_keyword_noexpect(keywords::Typeof) {
1570 // In order to not be ambiguous, the type must be surrounded by parens.
1571 self.expect(&token::OpenDelim(token::Paren))?;
1573 id: ast::DUMMY_NODE_ID,
1574 value: self.parse_expr()?,
1576 self.expect(&token::CloseDelim(token::Paren))?;
1578 } else if self.eat_keyword(keywords::Underscore) {
1579 // A type to be inferred `_`
1581 } else if self.token_is_bare_fn_keyword() {
1582 // Function pointer type
1583 self.parse_ty_bare_fn(Vec::new())?
1584 } else if self.check_keyword(keywords::For) {
1585 // Function pointer type or bound list (trait object type) starting with a poly-trait.
1586 // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
1587 // `for<'lt> Trait1<'lt> + Trait2 + 'a`
1589 let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
1590 if self.token_is_bare_fn_keyword() {
1591 self.parse_ty_bare_fn(lifetime_defs)?
1593 let path = self.parse_path(PathStyle::Type)?;
1594 let parse_plus = allow_plus && self.check_plus();
1595 self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)?
1597 } else if self.eat_keyword(keywords::Impl) {
1598 // Always parse bounds greedily for better error recovery.
1599 let bounds = self.parse_generic_bounds()?;
1600 impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
1601 TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)
1602 } else if self.check_keyword(keywords::Dyn) &&
1603 (self.span.rust_2018() ||
1604 self.look_ahead(1, |t| t.can_begin_bound() &&
1605 !can_continue_type_after_non_fn_ident(t))) {
1606 self.bump(); // `dyn`
1607 // Always parse bounds greedily for better error recovery.
1608 let bounds = self.parse_generic_bounds()?;
1609 impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
1610 TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
1611 } else if self.check(&token::Question) ||
1612 self.check_lifetime() && self.look_ahead(1, |t| t.is_like_plus()) {
1613 // Bound list (trait object type)
1614 TyKind::TraitObject(self.parse_generic_bounds_common(allow_plus)?,
1615 TraitObjectSyntax::None)
1616 } else if self.eat_lt() {
1618 let (qself, path) = self.parse_qpath(PathStyle::Type)?;
1619 TyKind::Path(Some(qself), path)
1620 } else if self.token.is_path_start() {
1622 let path = self.parse_path(PathStyle::Type)?;
1623 if self.eat(&token::Not) {
1624 // Macro invocation in type position
1625 let (delim, tts) = self.expect_delimited_token_tree()?;
1626 let node = Mac_ { path, tts, delim };
1627 TyKind::Mac(respan(lo.to(self.prev_span), node))
1629 // Just a type path or bound list (trait object type) starting with a trait.
1631 // `Trait1 + Trait2 + 'a`
1632 if allow_plus && self.check_plus() {
1633 self.parse_remaining_bounds(Vec::new(), path, lo, true)?
1635 TyKind::Path(None, path)
1639 let msg = format!("expected type, found {}", self.this_token_descr());
1640 return Err(self.fatal(&msg));
1643 let span = lo.to(self.prev_span);
1644 let ty = Ty { node, span, id: ast::DUMMY_NODE_ID };
1646 // Try to recover from use of `+` with incorrect priority.
1647 self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty);
1648 self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
1649 let ty = self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)?;
1654 fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: ast::Path,
1655 lo: Span, parse_plus: bool) -> PResult<'a, TyKind> {
1656 let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
1657 let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
1659 self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
1660 bounds.append(&mut self.parse_generic_bounds()?);
1662 Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
1665 fn maybe_report_ambiguous_plus(&mut self, allow_plus: bool, impl_dyn_multi: bool, ty: &Ty) {
1666 if !allow_plus && impl_dyn_multi {
1667 let sum_with_parens = format!("({})", pprust::ty_to_string(&ty));
1668 self.struct_span_err(ty.span, "ambiguous `+` in a type")
1669 .span_suggestion_with_applicability(
1671 "use parentheses to disambiguate",
1673 Applicability::MachineApplicable
1678 fn maybe_recover_from_bad_type_plus(&mut self, allow_plus: bool, ty: &Ty) -> PResult<'a, ()> {
1679 // Do not add `+` to expected tokens.
1680 if !allow_plus || !self.token.is_like_plus() {
1685 let bounds = self.parse_generic_bounds()?;
1686 let sum_span = ty.span.to(self.prev_span);
1688 let mut err = struct_span_err!(self.sess.span_diagnostic, sum_span, E0178,
1689 "expected a path on the left-hand side of `+`, not `{}`", pprust::ty_to_string(ty));
1692 TyKind::Rptr(ref lifetime, ref mut_ty) => {
1693 let sum_with_parens = pprust::to_string(|s| {
1694 use print::pprust::PrintState;
1697 s.print_opt_lifetime(lifetime)?;
1698 s.print_mutability(mut_ty.mutbl)?;
1700 s.print_type(&mut_ty.ty)?;
1701 s.print_type_bounds(" +", &bounds)?;
1704 err.span_suggestion_with_applicability(
1706 "try adding parentheses",
1708 Applicability::MachineApplicable
1711 TyKind::Ptr(..) | TyKind::BareFn(..) => {
1712 err.span_label(sum_span, "perhaps you forgot parentheses?");
1715 err.span_label(sum_span, "expected a path");
1722 // Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
1723 fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T, allow_recovery: bool)
1725 // Do not add `::` to expected tokens.
1726 if !allow_recovery || self.token != token::ModSep {
1729 let ty = match base.to_ty() {
1731 None => return Ok(base),
1734 self.bump(); // `::`
1735 let mut segments = Vec::new();
1736 self.parse_path_segments(&mut segments, T::PATH_STYLE, true)?;
1738 let span = ty.span.to(self.prev_span);
1739 let path_span = span.to(span); // use an empty path since `position` == 0
1740 let recovered = base.to_recovered(
1741 Some(QSelf { ty, path_span, position: 0 }),
1742 ast::Path { segments, span },
1746 .struct_span_err(span, "missing angle brackets in associated item path")
1747 .span_suggestion_with_applicability( // this is a best-effort recovery
1748 span, "try", recovered.to_string(), Applicability::MaybeIncorrect
1754 fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
1755 let opt_lifetime = if self.check_lifetime() { Some(self.expect_lifetime()) } else { None };
1756 let mutbl = self.parse_mutability();
1757 let ty = self.parse_ty_no_plus()?;
1758 return Ok(TyKind::Rptr(opt_lifetime, MutTy { ty: ty, mutbl: mutbl }));
1761 fn parse_ptr(&mut self) -> PResult<'a, MutTy> {
1762 let mutbl = if self.eat_keyword(keywords::Mut) {
1764 } else if self.eat_keyword(keywords::Const) {
1765 Mutability::Immutable
1767 let span = self.prev_span;
1769 "expected mut or const in raw pointer type (use \
1770 `*mut T` or `*const T` as appropriate)");
1771 Mutability::Immutable
1773 let t = self.parse_ty_no_plus()?;
1774 Ok(MutTy { ty: t, mutbl: mutbl })
1777 fn is_named_argument(&mut self) -> bool {
1778 let offset = match self.token {
1779 token::Interpolated(ref nt) => match nt.0 {
1780 token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
1783 token::BinOp(token::And) | token::AndAnd => 1,
1784 _ if self.token.is_keyword(keywords::Mut) => 1,
1788 self.look_ahead(offset, |t| t.is_ident()) &&
1789 self.look_ahead(offset + 1, |t| t == &token::Colon)
1792 /// Skip unexpected attributes and doc comments in this position and emit an appropriate error.
1793 fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
1794 if let token::DocComment(_) = self.token {
1795 let mut err = self.diagnostic().struct_span_err(
1797 &format!("documentation comments cannot be applied to {}", applied_to),
1799 err.span_label(self.span, "doc comments are not allowed here");
1802 } else if self.token == token::Pound && self.look_ahead(1, |t| {
1803 *t == token::OpenDelim(token::Bracket)
1806 // Skip every token until next possible arg.
1807 while self.token != token::CloseDelim(token::Bracket) {
1810 let sp = lo.to(self.span);
1812 let mut err = self.diagnostic().struct_span_err(
1814 &format!("attributes cannot be applied to {}", applied_to),
1816 err.span_label(sp, "attributes are not allowed here");
1821 /// This version of parse arg doesn't necessarily require
1822 /// identifier names.
1823 fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool) -> PResult<'a, Arg> {
1824 maybe_whole!(self, NtArg, |x| x);
1826 if let Ok(Some(_)) = self.parse_self_arg() {
1827 let mut err = self.struct_span_err(self.prev_span,
1828 "unexpected `self` argument in function");
1829 err.span_label(self.prev_span,
1830 "`self` is only valid as the first argument of an associated function");
1834 let (pat, ty) = if require_name || self.is_named_argument() {
1835 debug!("parse_arg_general parse_pat (require_name:{})",
1837 self.eat_incorrect_doc_comment("method arguments");
1838 let pat = self.parse_pat(Some("argument name"))?;
1840 if let Err(mut err) = self.expect(&token::Colon) {
1841 // If we find a pattern followed by an identifier, it could be an (incorrect)
1842 // C-style parameter declaration.
1843 if self.check_ident() && self.look_ahead(1, |t| {
1844 *t == token::Comma || *t == token::CloseDelim(token::Paren)
1846 let ident = self.parse_ident().unwrap();
1847 let span = pat.span.with_hi(ident.span.hi());
1849 err.span_suggestion_with_applicability(
1851 "declare the type after the parameter binding",
1852 String::from("<identifier>: <type>"),
1853 Applicability::HasPlaceholders,
1855 } else if require_name && is_trait_item {
1856 if let PatKind::Ident(_, ident, _) = pat.node {
1857 err.span_suggestion_with_applicability(
1859 "explicitly ignore parameter",
1860 format!("_: {}", ident),
1861 Applicability::MachineApplicable,
1865 err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
1871 self.eat_incorrect_doc_comment("a method argument's type");
1872 (pat, self.parse_ty()?)
1874 debug!("parse_arg_general ident_to_pat");
1875 let parser_snapshot_before_ty = self.clone();
1876 self.eat_incorrect_doc_comment("a method argument's type");
1877 let mut ty = self.parse_ty();
1878 if ty.is_ok() && self.token == token::Colon {
1879 // This wasn't actually a type, but a pattern looking like a type,
1880 // so we are going to rollback and re-parse for recovery.
1881 ty = self.unexpected();
1885 let ident = Ident::new(keywords::Invalid.name(), self.prev_span);
1887 id: ast::DUMMY_NODE_ID,
1888 node: PatKind::Ident(
1889 BindingMode::ByValue(Mutability::Immutable), ident, None),
1895 // Recover from attempting to parse the argument as a type without pattern.
1897 mem::replace(self, parser_snapshot_before_ty);
1898 let pat = self.parse_pat(Some("argument name"))?;
1899 self.expect(&token::Colon)?;
1900 let ty = self.parse_ty()?;
1902 let mut err = self.diagnostic().struct_span_err_with_code(
1904 "patterns aren't allowed in methods without bodies",
1905 DiagnosticId::Error("E0642".into()),
1907 err.span_suggestion_short_with_applicability(
1909 "give this argument a name or use an underscore to ignore it",
1911 Applicability::MachineApplicable,
1915 // Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
1917 node: PatKind::Wild,
1919 id: ast::DUMMY_NODE_ID
1926 Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID })
1929 /// Parse a single function argument
1930 crate fn parse_arg(&mut self) -> PResult<'a, Arg> {
1931 self.parse_arg_general(true, false)
1934 /// Parse an argument in a lambda header e.g., |arg, arg|
1935 fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
1936 let pat = self.parse_pat(Some("argument name"))?;
1937 let t = if self.eat(&token::Colon) {
1941 id: ast::DUMMY_NODE_ID,
1942 node: TyKind::Infer,
1943 span: self.prev_span,
1949 id: ast::DUMMY_NODE_ID
1953 fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::Expr>>> {
1954 if self.eat(&token::Semi) {
1955 Ok(Some(self.parse_expr()?))
1961 /// Matches token_lit = LIT_INTEGER | ...
1962 fn parse_lit_token(&mut self) -> PResult<'a, LitKind> {
1963 let out = match self.token {
1964 token::Interpolated(ref nt) => match nt.0 {
1965 token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node {
1966 ExprKind::Lit(ref lit) => { lit.node.clone() }
1967 _ => { return self.unexpected_last(&self.token); }
1969 _ => { return self.unexpected_last(&self.token); }
1971 token::Literal(lit, suf) => {
1972 let diag = Some((self.span, &self.sess.span_diagnostic));
1973 let (suffix_illegal, result) = parse::lit_token(lit, suf, diag);
1977 self.expect_no_suffix(sp, lit.literal_name(), suf)
1982 _ => { return self.unexpected_last(&self.token); }
1989 /// Matches lit = true | false | token_lit
1990 crate fn parse_lit(&mut self) -> PResult<'a, Lit> {
1992 let lit = if self.eat_keyword(keywords::True) {
1994 } else if self.eat_keyword(keywords::False) {
1995 LitKind::Bool(false)
1997 let lit = self.parse_lit_token()?;
2000 Ok(source_map::Spanned { node: lit, span: lo.to(self.prev_span) })
2003 /// matches '-' lit | lit (cf. ast_validation::AstValidator::check_expr_within_pat)
2004 crate fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
2005 maybe_whole_expr!(self);
2007 let minus_lo = self.span;
2008 let minus_present = self.eat(&token::BinOp(token::Minus));
2010 let literal = self.parse_lit()?;
2011 let hi = self.prev_span;
2012 let expr = self.mk_expr(lo.to(hi), ExprKind::Lit(literal), ThinVec::new());
2015 let minus_hi = self.prev_span;
2016 let unary = self.mk_unary(UnOp::Neg, expr);
2017 Ok(self.mk_expr(minus_lo.to(minus_hi), unary, ThinVec::new()))
2023 fn parse_path_segment_ident(&mut self) -> PResult<'a, ast::Ident> {
2025 token::Ident(ident, _) if self.token.is_path_segment_keyword() => {
2026 let span = self.span;
2028 Ok(Ident::new(ident.name, span))
2030 _ => self.parse_ident(),
2034 fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
2036 token::Ident(ident, false) if ident.name == keywords::Underscore.name() => {
2037 let span = self.span;
2039 Ok(Ident::new(ident.name, span))
2041 _ => self.parse_ident(),
2045 /// Parses qualified path.
2046 /// Assumes that the leading `<` has been parsed already.
2048 /// `qualified_path = <type [as trait_ref]>::path`
2053 /// `<T as U>::F::a<S>` (without disambiguator)
2054 /// `<T as U>::F::a::<S>` (with disambiguator)
2055 fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, ast::Path)> {
2056 let lo = self.prev_span;
2057 let ty = self.parse_ty()?;
2059 // `path` will contain the prefix of the path up to the `>`,
2060 // if any (e.g., `U` in the `<T as U>::*` examples
2061 // above). `path_span` has the span of that path, or an empty
2062 // span in the case of something like `<T>::Bar`.
2063 let (mut path, path_span);
2064 if self.eat_keyword(keywords::As) {
2065 let path_lo = self.span;
2066 path = self.parse_path(PathStyle::Type)?;
2067 path_span = path_lo.to(self.prev_span);
2069 path = ast::Path { segments: Vec::new(), span: syntax_pos::DUMMY_SP };
2070 path_span = self.span.to(self.span);
2073 self.expect(&token::Gt)?;
2074 self.expect(&token::ModSep)?;
2076 let qself = QSelf { ty, path_span, position: path.segments.len() };
2077 self.parse_path_segments(&mut path.segments, style, true)?;
2079 Ok((qself, ast::Path { segments: path.segments, span: lo.to(self.prev_span) }))
2082 /// Parses simple paths.
2084 /// `path = [::] segment+`
2085 /// `segment = ident | ident[::]<args> | ident[::](args) [-> type]`
2088 /// `a::b::C<D>` (without disambiguator)
2089 /// `a::b::C::<D>` (with disambiguator)
2090 /// `Fn(Args)` (without disambiguator)
2091 /// `Fn::(Args)` (with disambiguator)
2092 pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, ast::Path> {
2093 self.parse_path_common(style, true)
2096 crate fn parse_path_common(&mut self, style: PathStyle, enable_warning: bool)
2097 -> PResult<'a, ast::Path> {
2098 maybe_whole!(self, NtPath, |path| {
2099 if style == PathStyle::Mod &&
2100 path.segments.iter().any(|segment| segment.args.is_some()) {
2101 self.diagnostic().span_err(path.span, "unexpected generic arguments in path");
2106 let lo = self.meta_var_span.unwrap_or(self.span);
2107 let mut segments = Vec::new();
2108 let mod_sep_ctxt = self.span.ctxt();
2109 if self.eat(&token::ModSep) {
2110 segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
2112 self.parse_path_segments(&mut segments, style, enable_warning)?;
2114 Ok(ast::Path { segments, span: lo.to(self.prev_span) })
2117 /// Like `parse_path`, but also supports parsing `Word` meta items into paths for back-compat.
2118 /// This is used when parsing derive macro paths in `#[derive]` attributes.
2119 pub fn parse_path_allowing_meta(&mut self, style: PathStyle) -> PResult<'a, ast::Path> {
2120 let meta_ident = match self.token {
2121 token::Interpolated(ref nt) => match nt.0 {
2122 token::NtMeta(ref meta) => match meta.node {
2123 ast::MetaItemKind::Word => Some(meta.ident.clone()),
2130 if let Some(path) = meta_ident {
2134 self.parse_path(style)
2137 fn parse_path_segments(&mut self,
2138 segments: &mut Vec<PathSegment>,
2140 enable_warning: bool)
2141 -> PResult<'a, ()> {
2143 segments.push(self.parse_path_segment(style, enable_warning)?);
2145 if self.is_import_coupler() || !self.eat(&token::ModSep) {
2151 fn parse_path_segment(&mut self, style: PathStyle, enable_warning: bool)
2152 -> PResult<'a, PathSegment> {
2153 let ident = self.parse_path_segment_ident()?;
2155 let is_args_start = |token: &token::Token| match *token {
2156 token::Lt | token::BinOp(token::Shl) | token::OpenDelim(token::Paren) => true,
2159 let check_args_start = |this: &mut Self| {
2160 this.expected_tokens.extend_from_slice(
2161 &[TokenType::Token(token::Lt), TokenType::Token(token::OpenDelim(token::Paren))]
2163 is_args_start(&this.token)
2166 Ok(if style == PathStyle::Type && check_args_start(self) ||
2167 style != PathStyle::Mod && self.check(&token::ModSep)
2168 && self.look_ahead(1, |t| is_args_start(t)) {
2169 // Generic arguments are found - `<`, `(`, `::<` or `::(`.
2171 if self.eat(&token::ModSep) && style == PathStyle::Type && enable_warning {
2172 self.diagnostic().struct_span_warn(self.prev_span, "unnecessary path disambiguator")
2173 .span_label(self.prev_span, "try removing `::`").emit();
2176 let args = if self.eat_lt() {
2178 let (args, bindings) = self.parse_generic_args()?;
2180 let span = lo.to(self.prev_span);
2181 AngleBracketedArgs { args, bindings, span }.into()
2185 let inputs = self.parse_seq_to_before_tokens(
2186 &[&token::CloseDelim(token::Paren)],
2187 SeqSep::trailing_allowed(token::Comma),
2188 TokenExpectType::Expect,
2191 let span = lo.to(self.prev_span);
2192 let output = if self.eat(&token::RArrow) {
2193 Some(self.parse_ty_common(false, false)?)
2197 ParenthesisedArgs { inputs, output, span }.into()
2200 PathSegment { ident, args, id: ast::DUMMY_NODE_ID }
2202 // Generic arguments are not found.
2203 PathSegment::from_ident(ident)
2207 crate fn check_lifetime(&mut self) -> bool {
2208 self.expected_tokens.push(TokenType::Lifetime);
2209 self.token.is_lifetime()
2212 /// Parse single lifetime 'a or panic.
2213 crate fn expect_lifetime(&mut self) -> Lifetime {
2214 if let Some(ident) = self.token.lifetime() {
2215 let span = self.span;
2217 Lifetime { ident: Ident::new(ident.name, span), id: ast::DUMMY_NODE_ID }
2219 self.span_bug(self.span, "not a lifetime")
2223 fn eat_label(&mut self) -> Option<Label> {
2224 if let Some(ident) = self.token.lifetime() {
2225 let span = self.span;
2227 Some(Label { ident: Ident::new(ident.name, span) })
2233 /// Parse mutability (`mut` or nothing).
2234 fn parse_mutability(&mut self) -> Mutability {
2235 if self.eat_keyword(keywords::Mut) {
2238 Mutability::Immutable
2242 fn parse_field_name(&mut self) -> PResult<'a, Ident> {
2243 if let token::Literal(token::Integer(name), None) = self.token {
2245 Ok(Ident::new(name, self.prev_span))
2247 self.parse_ident_common(false)
2251 /// Parse ident (COLON expr)?
2252 fn parse_field(&mut self) -> PResult<'a, Field> {
2253 let attrs = self.parse_outer_attributes()?;
2256 // Check if a colon exists one ahead. This means we're parsing a fieldname.
2257 let (fieldname, expr, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
2258 let fieldname = self.parse_field_name()?;
2260 (fieldname, self.parse_expr()?, false)
2262 let fieldname = self.parse_ident_common(false)?;
2264 // Mimic `x: x` for the `x` field shorthand.
2265 let path = ast::Path::from_ident(fieldname);
2266 let expr = self.mk_expr(fieldname.span, ExprKind::Path(None, path), ThinVec::new());
2267 (fieldname, expr, true)
2271 span: lo.to(expr.span),
2274 attrs: attrs.into(),
2278 fn mk_expr(&mut self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
2279 P(Expr { node, span, attrs, id: ast::DUMMY_NODE_ID })
2282 fn mk_unary(&mut self, unop: ast::UnOp, expr: P<Expr>) -> ast::ExprKind {
2283 ExprKind::Unary(unop, expr)
2286 fn mk_binary(&mut self, binop: ast::BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
2287 ExprKind::Binary(binop, lhs, rhs)
2290 fn mk_call(&mut self, f: P<Expr>, args: Vec<P<Expr>>) -> ast::ExprKind {
2291 ExprKind::Call(f, args)
2294 fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::ExprKind {
2295 ExprKind::Index(expr, idx)
2298 fn mk_range(&mut self,
2299 start: Option<P<Expr>>,
2300 end: Option<P<Expr>>,
2301 limits: RangeLimits)
2302 -> PResult<'a, ast::ExprKind> {
2303 if end.is_none() && limits == RangeLimits::Closed {
2304 Err(self.span_fatal_err(self.span, Error::InclusiveRangeWithNoEnd))
2306 Ok(ExprKind::Range(start, end, limits))
2310 fn mk_assign_op(&mut self, binop: ast::BinOp,
2311 lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
2312 ExprKind::AssignOp(binop, lhs, rhs)
2315 pub fn mk_mac_expr(&mut self, span: Span, m: Mac_, attrs: ThinVec<Attribute>) -> P<Expr> {
2317 id: ast::DUMMY_NODE_ID,
2318 node: ExprKind::Mac(source_map::Spanned {node: m, span: span}),
2324 fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, ThinTokenStream)> {
2325 let delim = match self.token {
2326 token::OpenDelim(delim) => delim,
2328 let msg = "expected open delimiter";
2329 let mut err = self.fatal(msg);
2330 err.span_label(self.span, msg);
2334 let tts = match self.parse_token_tree() {
2335 TokenTree::Delimited(_, _, tts) => tts,
2336 _ => unreachable!(),
2338 let delim = match delim {
2339 token::Paren => MacDelimiter::Parenthesis,
2340 token::Bracket => MacDelimiter::Bracket,
2341 token::Brace => MacDelimiter::Brace,
2342 token::NoDelim => self.bug("unexpected no delimiter"),
2344 Ok((delim, tts.stream().into()))
2347 /// At the bottom (top?) of the precedence hierarchy,
2348 /// parse things like parenthesized exprs,
2349 /// macros, return, etc.
2351 /// N.B., this does not parse outer attributes,
2352 /// and is private because it only works
2353 /// correctly if called from parse_dot_or_call_expr().
2354 fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
2355 maybe_whole_expr!(self);
2357 // Outer attributes are already parsed and will be
2358 // added to the return value after the fact.
2360 // Therefore, prevent sub-parser from parsing
2361 // attributes by giving them a empty "already parsed" list.
2362 let mut attrs = ThinVec::new();
2365 let mut hi = self.span;
2369 // Note: when adding new syntax here, don't forget to adjust Token::can_begin_expr().
2371 token::OpenDelim(token::Paren) => {
2374 attrs.extend(self.parse_inner_attributes()?);
2376 // (e) is parenthesized e
2377 // (e,) is a tuple with only one field, e
2378 let mut es = vec![];
2379 let mut trailing_comma = false;
2380 while self.token != token::CloseDelim(token::Paren) {
2381 es.push(self.parse_expr()?);
2382 self.expect_one_of(&[], &[token::Comma, token::CloseDelim(token::Paren)])?;
2383 if self.eat(&token::Comma) {
2384 trailing_comma = true;
2386 trailing_comma = false;
2392 hi = self.prev_span;
2393 ex = if es.len() == 1 && !trailing_comma {
2394 ExprKind::Paren(es.into_iter().nth(0).unwrap())
2399 token::OpenDelim(token::Brace) => {
2400 return self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs);
2402 token::BinOp(token::Or) | token::OrOr => {
2403 return self.parse_lambda_expr(attrs);
2405 token::OpenDelim(token::Bracket) => {
2408 attrs.extend(self.parse_inner_attributes()?);
2410 if self.eat(&token::CloseDelim(token::Bracket)) {
2412 ex = ExprKind::Array(Vec::new());
2415 let first_expr = self.parse_expr()?;
2416 if self.eat(&token::Semi) {
2417 // Repeating array syntax: [ 0; 512 ]
2418 let count = AnonConst {
2419 id: ast::DUMMY_NODE_ID,
2420 value: self.parse_expr()?,
2422 self.expect(&token::CloseDelim(token::Bracket))?;
2423 ex = ExprKind::Repeat(first_expr, count);
2424 } else if self.eat(&token::Comma) {
2425 // Vector with two or more elements.
2426 let remaining_exprs = self.parse_seq_to_end(
2427 &token::CloseDelim(token::Bracket),
2428 SeqSep::trailing_allowed(token::Comma),
2429 |p| Ok(p.parse_expr()?)
2431 let mut exprs = vec![first_expr];
2432 exprs.extend(remaining_exprs);
2433 ex = ExprKind::Array(exprs);
2435 // Vector with one element.
2436 self.expect(&token::CloseDelim(token::Bracket))?;
2437 ex = ExprKind::Array(vec![first_expr]);
2440 hi = self.prev_span;
2444 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
2446 return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs));
2448 if self.span.rust_2018() && self.check_keyword(keywords::Async)
2450 if self.is_async_block() { // check for `async {` and `async move {`
2451 return self.parse_async_block(attrs);
2453 return self.parse_lambda_expr(attrs);
2456 if self.check_keyword(keywords::Move) || self.check_keyword(keywords::Static) {
2457 return self.parse_lambda_expr(attrs);
2459 if self.eat_keyword(keywords::If) {
2460 return self.parse_if_expr(attrs);
2462 if self.eat_keyword(keywords::For) {
2463 let lo = self.prev_span;
2464 return self.parse_for_expr(None, lo, attrs);
2466 if self.eat_keyword(keywords::While) {
2467 let lo = self.prev_span;
2468 return self.parse_while_expr(None, lo, attrs);
2470 if let Some(label) = self.eat_label() {
2471 let lo = label.ident.span;
2472 self.expect(&token::Colon)?;
2473 if self.eat_keyword(keywords::While) {
2474 return self.parse_while_expr(Some(label), lo, attrs)
2476 if self.eat_keyword(keywords::For) {
2477 return self.parse_for_expr(Some(label), lo, attrs)
2479 if self.eat_keyword(keywords::Loop) {
2480 return self.parse_loop_expr(Some(label), lo, attrs)
2482 if self.token == token::OpenDelim(token::Brace) {
2483 return self.parse_block_expr(Some(label),
2485 BlockCheckMode::Default,
2488 let msg = "expected `while`, `for`, `loop` or `{` after a label";
2489 let mut err = self.fatal(msg);
2490 err.span_label(self.span, msg);
2493 if self.eat_keyword(keywords::Loop) {
2494 let lo = self.prev_span;
2495 return self.parse_loop_expr(None, lo, attrs);
2497 if self.eat_keyword(keywords::Continue) {
2498 let label = self.eat_label();
2499 let ex = ExprKind::Continue(label);
2500 let hi = self.prev_span;
2501 return Ok(self.mk_expr(lo.to(hi), ex, attrs));
2503 if self.eat_keyword(keywords::Match) {
2504 let match_sp = self.prev_span;
2505 return self.parse_match_expr(attrs).map_err(|mut err| {
2506 err.span_label(match_sp, "while parsing this match expression");
2510 if self.eat_keyword(keywords::Unsafe) {
2511 return self.parse_block_expr(
2514 BlockCheckMode::Unsafe(ast::UserProvided),
2517 if self.is_do_catch_block() {
2518 let mut db = self.fatal("found removed `do catch` syntax");
2519 db.help("Following RFC #2388, the new non-placeholder syntax is `try`");
2522 if self.is_try_block() {
2524 assert!(self.eat_keyword(keywords::Try));
2525 return self.parse_try_block(lo, attrs);
2527 if self.eat_keyword(keywords::Return) {
2528 if self.token.can_begin_expr() {
2529 let e = self.parse_expr()?;
2531 ex = ExprKind::Ret(Some(e));
2533 ex = ExprKind::Ret(None);
2535 } else if self.eat_keyword(keywords::Break) {
2536 let label = self.eat_label();
2537 let e = if self.token.can_begin_expr()
2538 && !(self.token == token::OpenDelim(token::Brace)
2539 && self.restrictions.contains(
2540 Restrictions::NO_STRUCT_LITERAL)) {
2541 Some(self.parse_expr()?)
2545 ex = ExprKind::Break(label, e);
2546 hi = self.prev_span;
2547 } else if self.eat_keyword(keywords::Yield) {
2548 if self.token.can_begin_expr() {
2549 let e = self.parse_expr()?;
2551 ex = ExprKind::Yield(Some(e));
2553 ex = ExprKind::Yield(None);
2555 } else if self.token.is_keyword(keywords::Let) {
2556 // Catch this syntax error here, instead of in `parse_ident`, so
2557 // that we can explicitly mention that let is not to be used as an expression
2558 let mut db = self.fatal("expected expression, found statement (`let`)");
2559 db.span_label(self.span, "expected expression");
2560 db.note("variable declaration using `let` is a statement");
2562 } else if self.token.is_path_start() {
2563 let pth = self.parse_path(PathStyle::Expr)?;
2565 // `!`, as an operator, is prefix, so we know this isn't that
2566 if self.eat(&token::Not) {
2567 // MACRO INVOCATION expression
2568 let (delim, tts) = self.expect_delimited_token_tree()?;
2569 let hi = self.prev_span;
2570 let node = Mac_ { path: pth, tts, delim };
2571 return Ok(self.mk_mac_expr(lo.to(hi), node, attrs))
2573 if self.check(&token::OpenDelim(token::Brace)) {
2574 // This is a struct literal, unless we're prohibited
2575 // from parsing struct literals here.
2576 let prohibited = self.restrictions.contains(
2577 Restrictions::NO_STRUCT_LITERAL
2580 return self.parse_struct_expr(lo, pth, attrs);
2585 ex = ExprKind::Path(None, pth);
2587 match self.parse_literal_maybe_minus() {
2590 ex = expr.node.clone();
2593 self.cancel(&mut err);
2594 let msg = format!("expected expression, found {}",
2595 self.this_token_descr());
2596 let mut err = self.fatal(&msg);
2597 err.span_label(self.span, "expected expression");
2605 let expr = Expr { node: ex, span: lo.to(hi), id: ast::DUMMY_NODE_ID, attrs };
2606 let expr = self.maybe_recover_from_bad_qpath(expr, true)?;
2611 fn parse_struct_expr(&mut self, lo: Span, pth: ast::Path, mut attrs: ThinVec<Attribute>)
2612 -> PResult<'a, P<Expr>> {
2613 let struct_sp = lo.to(self.prev_span);
2615 let mut fields = Vec::new();
2616 let mut base = None;
2618 attrs.extend(self.parse_inner_attributes()?);
2620 while self.token != token::CloseDelim(token::Brace) {
2621 if self.eat(&token::DotDot) {
2622 let exp_span = self.prev_span;
2623 match self.parse_expr() {
2629 self.recover_stmt();
2632 if self.token == token::Comma {
2633 let mut err = self.sess.span_diagnostic.mut_span_err(
2634 exp_span.to(self.prev_span),
2635 "cannot use a comma after the base struct",
2637 err.span_suggestion_short_with_applicability(
2639 "remove this comma",
2641 Applicability::MachineApplicable
2643 err.note("the base struct must always be the last field");
2645 self.recover_stmt();
2650 match self.parse_field() {
2651 Ok(f) => fields.push(f),
2653 e.span_label(struct_sp, "while parsing this struct");
2656 // If the next token is a comma, then try to parse
2657 // what comes next as additional fields, rather than
2658 // bailing out until next `}`.
2659 if self.token != token::Comma {
2660 self.recover_stmt();
2666 match self.expect_one_of(&[token::Comma],
2667 &[token::CloseDelim(token::Brace)]) {
2671 self.recover_stmt();
2677 let span = lo.to(self.span);
2678 self.expect(&token::CloseDelim(token::Brace))?;
2679 return Ok(self.mk_expr(span, ExprKind::Struct(pth, fields, base), attrs));
2682 fn parse_or_use_outer_attributes(&mut self,
2683 already_parsed_attrs: Option<ThinVec<Attribute>>)
2684 -> PResult<'a, ThinVec<Attribute>> {
2685 if let Some(attrs) = already_parsed_attrs {
2688 self.parse_outer_attributes().map(|a| a.into())
2692 /// Parse a block or unsafe block
2693 fn parse_block_expr(&mut self, opt_label: Option<Label>,
2694 lo: Span, blk_mode: BlockCheckMode,
2695 outer_attrs: ThinVec<Attribute>)
2696 -> PResult<'a, P<Expr>> {
2697 self.expect(&token::OpenDelim(token::Brace))?;
2699 let mut attrs = outer_attrs;
2700 attrs.extend(self.parse_inner_attributes()?);
2702 let blk = self.parse_block_tail(lo, blk_mode)?;
2703 return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs));
2706 /// parse a.b or a(13) or a[4] or just a
2707 fn parse_dot_or_call_expr(&mut self,
2708 already_parsed_attrs: Option<ThinVec<Attribute>>)
2709 -> PResult<'a, P<Expr>> {
2710 let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
2712 let b = self.parse_bottom_expr();
2713 let (span, b) = self.interpolated_or_expr_span(b)?;
2714 self.parse_dot_or_call_expr_with(b, span, attrs)
2717 fn parse_dot_or_call_expr_with(&mut self,
2720 mut attrs: ThinVec<Attribute>)
2721 -> PResult<'a, P<Expr>> {
2722 // Stitch the list of outer attributes onto the return value.
2723 // A little bit ugly, but the best way given the current code
2725 self.parse_dot_or_call_expr_with_(e0, lo)
2727 expr.map(|mut expr| {
2728 attrs.extend::<Vec<_>>(expr.attrs.into());
2731 ExprKind::If(..) | ExprKind::IfLet(..) => {
2732 if !expr.attrs.is_empty() {
2733 // Just point to the first attribute in there...
2734 let span = expr.attrs[0].span;
2737 "attributes are not yet allowed on `if` \
2748 // Assuming we have just parsed `.`, continue parsing into an expression.
2749 fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
2750 let segment = self.parse_path_segment(PathStyle::Expr, true)?;
2751 Ok(match self.token {
2752 token::OpenDelim(token::Paren) => {
2753 // Method call `expr.f()`
2754 let mut args = self.parse_unspanned_seq(
2755 &token::OpenDelim(token::Paren),
2756 &token::CloseDelim(token::Paren),
2757 SeqSep::trailing_allowed(token::Comma),
2758 |p| Ok(p.parse_expr()?)
2760 args.insert(0, self_arg);
2762 let span = lo.to(self.prev_span);
2763 self.mk_expr(span, ExprKind::MethodCall(segment, args), ThinVec::new())
2766 // Field access `expr.f`
2767 if let Some(args) = segment.args {
2768 self.span_err(args.span(),
2769 "field expressions may not have generic arguments");
2772 let span = lo.to(self.prev_span);
2773 self.mk_expr(span, ExprKind::Field(self_arg, segment.ident), ThinVec::new())
2778 fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
2783 while self.eat(&token::Question) {
2784 let hi = self.prev_span;
2785 e = self.mk_expr(lo.to(hi), ExprKind::Try(e), ThinVec::new());
2789 if self.eat(&token::Dot) {
2791 token::Ident(..) => {
2792 e = self.parse_dot_suffix(e, lo)?;
2794 token::Literal(token::Integer(name), _) => {
2795 let span = self.span;
2797 let field = ExprKind::Field(e, Ident::new(name, span));
2798 e = self.mk_expr(lo.to(span), field, ThinVec::new());
2800 token::Literal(token::Float(n), _suf) => {
2802 let fstr = n.as_str();
2803 let mut err = self.diagnostic()
2804 .struct_span_err(self.prev_span, &format!("unexpected token: `{}`", n));
2805 err.span_label(self.prev_span, "unexpected token");
2806 if fstr.chars().all(|x| "0123456789.".contains(x)) {
2807 let float = match fstr.parse::<f64>().ok() {
2811 let sugg = pprust::to_string(|s| {
2812 use print::pprust::PrintState;
2816 s.print_usize(float.trunc() as usize)?;
2819 s.s.word(fstr.splitn(2, ".").last().unwrap().to_string())
2821 err.span_suggestion_with_applicability(
2822 lo.to(self.prev_span),
2823 "try parenthesizing the first index",
2825 Applicability::MachineApplicable
2832 // FIXME Could factor this out into non_fatal_unexpected or something.
2833 let actual = self.this_token_to_string();
2834 self.span_err(self.span, &format!("unexpected token: `{}`", actual));
2839 if self.expr_is_complete(&e) { break; }
2842 token::OpenDelim(token::Paren) => {
2843 let es = self.parse_unspanned_seq(
2844 &token::OpenDelim(token::Paren),
2845 &token::CloseDelim(token::Paren),
2846 SeqSep::trailing_allowed(token::Comma),
2847 |p| Ok(p.parse_expr()?)
2849 hi = self.prev_span;
2851 let nd = self.mk_call(e, es);
2852 e = self.mk_expr(lo.to(hi), nd, ThinVec::new());
2856 // Could be either an index expression or a slicing expression.
2857 token::OpenDelim(token::Bracket) => {
2859 let ix = self.parse_expr()?;
2861 self.expect(&token::CloseDelim(token::Bracket))?;
2862 let index = self.mk_index(e, ix);
2863 e = self.mk_expr(lo.to(hi), index, ThinVec::new())
2871 crate fn process_potential_macro_variable(&mut self) {
2872 let (token, span) = match self.token {
2873 token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() &&
2874 self.look_ahead(1, |t| t.is_ident()) => {
2876 let name = match self.token {
2877 token::Ident(ident, _) => ident,
2880 let mut err = self.fatal(&format!("unknown macro variable `{}`", name));
2881 err.span_label(self.span, "unknown macro variable");
2885 token::Interpolated(ref nt) => {
2886 self.meta_var_span = Some(self.span);
2887 // Interpolated identifier and lifetime tokens are replaced with usual identifier
2888 // and lifetime tokens, so the former are never encountered during normal parsing.
2890 token::NtIdent(ident, is_raw) => (token::Ident(ident, is_raw), ident.span),
2891 token::NtLifetime(ident) => (token::Lifetime(ident), ident.span),
2901 /// parse a single token tree from the input.
2902 crate fn parse_token_tree(&mut self) -> TokenTree {
2904 token::OpenDelim(..) => {
2905 let frame = mem::replace(&mut self.token_cursor.frame,
2906 self.token_cursor.stack.pop().unwrap());
2907 self.span = frame.span.entire();
2909 TokenTree::Delimited(
2912 frame.tree_cursor.original_stream().into(),
2915 token::CloseDelim(_) | token::Eof => unreachable!(),
2917 let (token, span) = (mem::replace(&mut self.token, token::Whitespace), self.span);
2919 TokenTree::Token(span, token)
2924 // parse a stream of tokens into a list of TokenTree's,
2926 pub fn parse_all_token_trees(&mut self) -> PResult<'a, Vec<TokenTree>> {
2927 let mut tts = Vec::new();
2928 while self.token != token::Eof {
2929 tts.push(self.parse_token_tree());
2934 pub fn parse_tokens(&mut self) -> TokenStream {
2935 let mut result = Vec::new();
2938 token::Eof | token::CloseDelim(..) => break,
2939 _ => result.push(self.parse_token_tree().into()),
2942 TokenStream::new(result)
2945 /// Parse a prefix-unary-operator expr
2946 fn parse_prefix_expr(&mut self,
2947 already_parsed_attrs: Option<ThinVec<Attribute>>)
2948 -> PResult<'a, P<Expr>> {
2949 let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
2951 // Note: when adding new unary operators, don't forget to adjust Token::can_begin_expr()
2952 let (hi, ex) = match self.token {
2955 let e = self.parse_prefix_expr(None);
2956 let (span, e) = self.interpolated_or_expr_span(e)?;
2957 (lo.to(span), self.mk_unary(UnOp::Not, e))
2959 // Suggest `!` for bitwise negation when encountering a `~`
2962 let e = self.parse_prefix_expr(None);
2963 let (span, e) = self.interpolated_or_expr_span(e)?;
2964 let span_of_tilde = lo;
2965 let mut err = self.diagnostic()
2966 .struct_span_err(span_of_tilde, "`~` cannot be used as a unary operator");
2967 err.span_suggestion_short_with_applicability(
2969 "use `!` to perform bitwise negation",
2971 Applicability::MachineApplicable
2974 (lo.to(span), self.mk_unary(UnOp::Not, e))
2976 token::BinOp(token::Minus) => {
2978 let e = self.parse_prefix_expr(None);
2979 let (span, e) = self.interpolated_or_expr_span(e)?;
2980 (lo.to(span), self.mk_unary(UnOp::Neg, e))
2982 token::BinOp(token::Star) => {
2984 let e = self.parse_prefix_expr(None);
2985 let (span, e) = self.interpolated_or_expr_span(e)?;
2986 (lo.to(span), self.mk_unary(UnOp::Deref, e))
2988 token::BinOp(token::And) | token::AndAnd => {
2990 let m = self.parse_mutability();
2991 let e = self.parse_prefix_expr(None);
2992 let (span, e) = self.interpolated_or_expr_span(e)?;
2993 (lo.to(span), ExprKind::AddrOf(m, e))
2995 token::Ident(..) if self.token.is_keyword(keywords::In) => {
2997 let place = self.parse_expr_res(
2998 Restrictions::NO_STRUCT_LITERAL,
3001 let blk = self.parse_block()?;
3002 let span = blk.span;
3003 let blk_expr = self.mk_expr(span, ExprKind::Block(blk, None), ThinVec::new());
3004 (lo.to(span), ExprKind::ObsoleteInPlace(place, blk_expr))
3006 token::Ident(..) if self.token.is_keyword(keywords::Box) => {
3008 let e = self.parse_prefix_expr(None);
3009 let (span, e) = self.interpolated_or_expr_span(e)?;
3010 (lo.to(span), ExprKind::Box(e))
3012 token::Ident(..) if self.token.is_ident_named("not") => {
3013 // `not` is just an ordinary identifier in Rust-the-language,
3014 // but as `rustc`-the-compiler, we can issue clever diagnostics
3015 // for confused users who really want to say `!`
3016 let token_cannot_continue_expr = |t: &token::Token| match *t {
3017 // These tokens can start an expression after `!`, but
3018 // can't continue an expression after an ident
3019 token::Ident(ident, is_raw) => token::ident_can_begin_expr(ident, is_raw),
3020 token::Literal(..) | token::Pound => true,
3021 token::Interpolated(ref nt) => match nt.0 {
3022 token::NtIdent(..) | token::NtExpr(..) |
3023 token::NtBlock(..) | token::NtPath(..) => true,
3028 let cannot_continue_expr = self.look_ahead(1, token_cannot_continue_expr);
3029 if cannot_continue_expr {
3031 // Emit the error ...
3032 let mut err = self.diagnostic()
3033 .struct_span_err(self.span,
3034 &format!("unexpected {} after identifier",
3035 self.this_token_descr()));
3036 // span the `not` plus trailing whitespace to avoid
3037 // trailing whitespace after the `!` in our suggestion
3038 let to_replace = self.sess.source_map()
3039 .span_until_non_whitespace(lo.to(self.span));
3040 err.span_suggestion_short_with_applicability(
3042 "use `!` to perform logical negation",
3044 Applicability::MachineApplicable
3047 // —and recover! (just as if we were in the block
3048 // for the `token::Not` arm)
3049 let e = self.parse_prefix_expr(None);
3050 let (span, e) = self.interpolated_or_expr_span(e)?;
3051 (lo.to(span), self.mk_unary(UnOp::Not, e))
3053 return self.parse_dot_or_call_expr(Some(attrs));
3056 _ => { return self.parse_dot_or_call_expr(Some(attrs)); }
3058 return Ok(self.mk_expr(lo.to(hi), ex, attrs));
3061 /// Parse an associative expression
3063 /// This parses an expression accounting for associativity and precedence of the operators in
3066 fn parse_assoc_expr(&mut self,
3067 already_parsed_attrs: Option<ThinVec<Attribute>>)
3068 -> PResult<'a, P<Expr>> {
3069 self.parse_assoc_expr_with(0, already_parsed_attrs.into())
3072 /// Parse an associative expression with operators of at least `min_prec` precedence
3073 fn parse_assoc_expr_with(&mut self,
3076 -> PResult<'a, P<Expr>> {
3077 let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
3080 let attrs = match lhs {
3081 LhsExpr::AttributesParsed(attrs) => Some(attrs),
3084 if [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token) {
3085 return self.parse_prefix_range_expr(attrs);
3087 self.parse_prefix_expr(attrs)?
3091 if self.expr_is_complete(&lhs) {
3092 // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
3095 self.expected_tokens.push(TokenType::Operator);
3096 while let Some(op) = AssocOp::from_token(&self.token) {
3098 // Adjust the span for interpolated LHS to point to the `$lhs` token and not to what
3099 // it refers to. Interpolated identifiers are unwrapped early and never show up here
3100 // as `PrevTokenKind::Interpolated` so if LHS is a single identifier we always process
3101 // it as "interpolated", it doesn't change the answer for non-interpolated idents.
3102 let lhs_span = match (self.prev_token_kind, &lhs.node) {
3103 (PrevTokenKind::Interpolated, _) => self.prev_span,
3104 (PrevTokenKind::Ident, &ExprKind::Path(None, ref path))
3105 if path.segments.len() == 1 => self.prev_span,
3109 let cur_op_span = self.span;
3110 let restrictions = if op.is_assign_like() {
3111 self.restrictions & Restrictions::NO_STRUCT_LITERAL
3115 if op.precedence() < min_prec {
3118 // Check for deprecated `...` syntax
3119 if self.token == token::DotDotDot && op == AssocOp::DotDotEq {
3120 self.err_dotdotdot_syntax(self.span);
3124 if op.is_comparison() {
3125 self.check_no_chained_comparison(&lhs, &op);
3128 if op == AssocOp::As {
3129 lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?;
3131 } else if op == AssocOp::Colon {
3132 lhs = match self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type) {
3135 err.span_label(self.span,
3136 "expecting a type here because of type ascription");
3137 let cm = self.sess.source_map();
3138 let cur_pos = cm.lookup_char_pos(self.span.lo());
3139 let op_pos = cm.lookup_char_pos(cur_op_span.hi());
3140 if cur_pos.line != op_pos.line {
3141 err.span_suggestion_with_applicability(
3143 "try using a semicolon",
3145 Applicability::MaybeIncorrect // speculative
3152 } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
3153 // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
3154 // generalise it to the Fixity::None code.
3156 // We have 2 alternatives here: `x..y`/`x..=y` and `x..`/`x..=` The other
3157 // two variants are handled with `parse_prefix_range_expr` call above.
3158 let rhs = if self.is_at_start_of_range_notation_rhs() {
3159 Some(self.parse_assoc_expr_with(op.precedence() + 1,
3160 LhsExpr::NotYetParsed)?)
3164 let (lhs_span, rhs_span) = (lhs.span, if let Some(ref x) = rhs {
3169 let limits = if op == AssocOp::DotDot {
3170 RangeLimits::HalfOpen
3175 let r = self.mk_range(Some(lhs), rhs, limits)?;
3176 lhs = self.mk_expr(lhs_span.to(rhs_span), r, ThinVec::new());
3180 let rhs = match op.fixity() {
3181 Fixity::Right => self.with_res(
3182 restrictions - Restrictions::STMT_EXPR,
3184 this.parse_assoc_expr_with(op.precedence(),
3185 LhsExpr::NotYetParsed)
3187 Fixity::Left => self.with_res(
3188 restrictions - Restrictions::STMT_EXPR,
3190 this.parse_assoc_expr_with(op.precedence() + 1,
3191 LhsExpr::NotYetParsed)
3193 // We currently have no non-associative operators that are not handled above by
3194 // the special cases. The code is here only for future convenience.
3195 Fixity::None => self.with_res(
3196 restrictions - Restrictions::STMT_EXPR,
3198 this.parse_assoc_expr_with(op.precedence() + 1,
3199 LhsExpr::NotYetParsed)
3203 let span = lhs_span.to(rhs.span);
3205 AssocOp::Add | AssocOp::Subtract | AssocOp::Multiply | AssocOp::Divide |
3206 AssocOp::Modulus | AssocOp::LAnd | AssocOp::LOr | AssocOp::BitXor |
3207 AssocOp::BitAnd | AssocOp::BitOr | AssocOp::ShiftLeft | AssocOp::ShiftRight |
3208 AssocOp::Equal | AssocOp::Less | AssocOp::LessEqual | AssocOp::NotEqual |
3209 AssocOp::Greater | AssocOp::GreaterEqual => {
3210 let ast_op = op.to_ast_binop().unwrap();
3211 let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs);
3212 self.mk_expr(span, binary, ThinVec::new())
3215 self.mk_expr(span, ExprKind::Assign(lhs, rhs), ThinVec::new()),
3216 AssocOp::ObsoleteInPlace =>
3217 self.mk_expr(span, ExprKind::ObsoleteInPlace(lhs, rhs), ThinVec::new()),
3218 AssocOp::AssignOp(k) => {
3220 token::Plus => BinOpKind::Add,
3221 token::Minus => BinOpKind::Sub,
3222 token::Star => BinOpKind::Mul,
3223 token::Slash => BinOpKind::Div,
3224 token::Percent => BinOpKind::Rem,
3225 token::Caret => BinOpKind::BitXor,
3226 token::And => BinOpKind::BitAnd,
3227 token::Or => BinOpKind::BitOr,
3228 token::Shl => BinOpKind::Shl,
3229 token::Shr => BinOpKind::Shr,
3231 let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs);
3232 self.mk_expr(span, aopexpr, ThinVec::new())
3234 AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => {
3235 self.bug("AssocOp should have been handled by special case")
3239 if op.fixity() == Fixity::None { break }
3244 fn parse_assoc_op_cast(&mut self, lhs: P<Expr>, lhs_span: Span,
3245 expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind)
3246 -> PResult<'a, P<Expr>> {
3247 let mk_expr = |this: &mut Self, rhs: P<Ty>| {
3248 this.mk_expr(lhs_span.to(rhs.span), expr_kind(lhs, rhs), ThinVec::new())
3251 // Save the state of the parser before parsing type normally, in case there is a
3252 // LessThan comparison after this cast.
3253 let parser_snapshot_before_type = self.clone();
3254 match self.parse_ty_no_plus() {
3256 Ok(mk_expr(self, rhs))
3258 Err(mut type_err) => {
3259 // Rewind to before attempting to parse the type with generics, to recover
3260 // from situations like `x as usize < y` in which we first tried to parse
3261 // `usize < y` as a type with generic arguments.
3262 let parser_snapshot_after_type = self.clone();
3263 mem::replace(self, parser_snapshot_before_type);
3265 match self.parse_path(PathStyle::Expr) {
3267 let (op_noun, op_verb) = match self.token {
3268 token::Lt => ("comparison", "comparing"),
3269 token::BinOp(token::Shl) => ("shift", "shifting"),
3271 // We can end up here even without `<` being the next token, for
3272 // example because `parse_ty_no_plus` returns `Err` on keywords,
3273 // but `parse_path` returns `Ok` on them due to error recovery.
3274 // Return original error and parser state.
3275 mem::replace(self, parser_snapshot_after_type);
3276 return Err(type_err);
3280 // Successfully parsed the type path leaving a `<` yet to parse.
3283 // Report non-fatal diagnostics, keep `x as usize` as an expression
3284 // in AST and continue parsing.
3285 let msg = format!("`<` is interpreted as a start of generic \
3286 arguments for `{}`, not a {}", path, op_noun);
3287 let mut err = self.sess.span_diagnostic.struct_span_err(self.span, &msg);
3288 err.span_label(self.look_ahead_span(1).to(parser_snapshot_after_type.span),
3289 "interpreted as generic arguments");
3290 err.span_label(self.span, format!("not interpreted as {}", op_noun));
3292 let expr = mk_expr(self, P(Ty {
3294 node: TyKind::Path(None, path),
3295 id: ast::DUMMY_NODE_ID
3298 let expr_str = self.sess.source_map().span_to_snippet(expr.span)
3299 .unwrap_or_else(|_| pprust::expr_to_string(&expr));
3300 err.span_suggestion_with_applicability(
3302 &format!("try {} the cast value", op_verb),
3303 format!("({})", expr_str),
3304 Applicability::MachineApplicable
3310 Err(mut path_err) => {
3311 // Couldn't parse as a path, return original error and parser state.
3313 mem::replace(self, parser_snapshot_after_type);
3321 /// Produce an error if comparison operators are chained (RFC #558).
3322 /// We only need to check lhs, not rhs, because all comparison ops
3323 /// have same precedence and are left-associative
3324 fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: &AssocOp) {
3325 debug_assert!(outer_op.is_comparison(),
3326 "check_no_chained_comparison: {:?} is not comparison",
3329 ExprKind::Binary(op, _, _) if op.node.is_comparison() => {
3330 // respan to include both operators
3331 let op_span = op.span.to(self.span);
3332 let mut err = self.diagnostic().struct_span_err(op_span,
3333 "chained comparison operators require parentheses");
3334 if op.node == BinOpKind::Lt &&
3335 *outer_op == AssocOp::Less || // Include `<` to provide this recommendation
3336 *outer_op == AssocOp::Greater // even in a case like the following:
3337 { // Foo<Bar<Baz<Qux, ()>>>
3339 "use `::<...>` instead of `<...>` if you meant to specify type arguments");
3340 err.help("or use `(...)` if you meant to specify fn arguments");
3348 /// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr`
3349 fn parse_prefix_range_expr(&mut self,
3350 already_parsed_attrs: Option<ThinVec<Attribute>>)
3351 -> PResult<'a, P<Expr>> {
3352 // Check for deprecated `...` syntax
3353 if self.token == token::DotDotDot {
3354 self.err_dotdotdot_syntax(self.span);
3357 debug_assert!([token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token),
3358 "parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq",
3360 let tok = self.token.clone();
3361 let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
3363 let mut hi = self.span;
3365 let opt_end = if self.is_at_start_of_range_notation_rhs() {
3366 // RHS must be parsed with more associativity than the dots.
3367 let next_prec = AssocOp::from_token(&tok).unwrap().precedence() + 1;
3368 Some(self.parse_assoc_expr_with(next_prec,
3369 LhsExpr::NotYetParsed)
3377 let limits = if tok == token::DotDot {
3378 RangeLimits::HalfOpen
3383 let r = self.mk_range(None, opt_end, limits)?;
3384 Ok(self.mk_expr(lo.to(hi), r, attrs))
3387 fn is_at_start_of_range_notation_rhs(&self) -> bool {
3388 if self.token.can_begin_expr() {
3389 // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
3390 if self.token == token::OpenDelim(token::Brace) {
3391 return !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
3399 /// Parse an 'if' or 'if let' expression ('if' token already eaten)
3400 fn parse_if_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3401 if self.check_keyword(keywords::Let) {
3402 return self.parse_if_let_expr(attrs);
3404 let lo = self.prev_span;
3405 let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3407 // Verify that the parsed `if` condition makes sense as a condition. If it is a block, then
3408 // verify that the last statement is either an implicit return (no `;`) or an explicit
3409 // return. This won't catch blocks with an explicit `return`, but that would be caught by
3410 // the dead code lint.
3411 if self.eat_keyword(keywords::Else) || !cond.returns() {
3412 let sp = self.sess.source_map().next_point(lo);
3413 let mut err = self.diagnostic()
3414 .struct_span_err(sp, "missing condition for `if` statemement");
3415 err.span_label(sp, "expected if condition here");
3418 let not_block = self.token != token::OpenDelim(token::Brace);
3419 let thn = self.parse_block().map_err(|mut err| {
3421 err.span_label(lo, "this `if` statement has a condition, but no block");
3425 let mut els: Option<P<Expr>> = None;
3426 let mut hi = thn.span;
3427 if self.eat_keyword(keywords::Else) {
3428 let elexpr = self.parse_else_expr()?;
3432 Ok(self.mk_expr(lo.to(hi), ExprKind::If(cond, thn, els), attrs))
3435 /// Parse an 'if let' expression ('if' token already eaten)
3436 fn parse_if_let_expr(&mut self, attrs: ThinVec<Attribute>)
3437 -> PResult<'a, P<Expr>> {
3438 let lo = self.prev_span;
3439 self.expect_keyword(keywords::Let)?;
3440 let pats = self.parse_pats()?;
3441 self.expect(&token::Eq)?;
3442 let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3443 let thn = self.parse_block()?;
3444 let (hi, els) = if self.eat_keyword(keywords::Else) {
3445 let expr = self.parse_else_expr()?;
3446 (expr.span, Some(expr))
3450 Ok(self.mk_expr(lo.to(hi), ExprKind::IfLet(pats, expr, thn, els), attrs))
3453 // `move |args| expr`
3454 fn parse_lambda_expr(&mut self,
3455 attrs: ThinVec<Attribute>)
3456 -> PResult<'a, P<Expr>>
3459 let movability = if self.eat_keyword(keywords::Static) {
3464 let asyncness = if self.span.rust_2018() {
3465 self.parse_asyncness()
3469 let capture_clause = if self.eat_keyword(keywords::Move) {
3474 let decl = self.parse_fn_block_decl()?;
3475 let decl_hi = self.prev_span;
3476 let body = match decl.output {
3477 FunctionRetTy::Default(_) => {
3478 let restrictions = self.restrictions - Restrictions::STMT_EXPR;
3479 self.parse_expr_res(restrictions, None)?
3482 // If an explicit return type is given, require a
3483 // block to appear (RFC 968).
3484 let body_lo = self.span;
3485 self.parse_block_expr(None, body_lo, BlockCheckMode::Default, ThinVec::new())?
3491 ExprKind::Closure(capture_clause, asyncness, movability, decl, body, lo.to(decl_hi)),
3495 // `else` token already eaten
3496 fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
3497 if self.eat_keyword(keywords::If) {
3498 return self.parse_if_expr(ThinVec::new());
3500 let blk = self.parse_block()?;
3501 return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None), ThinVec::new()));
3505 /// Parse a 'for' .. 'in' expression ('for' token already eaten)
3506 fn parse_for_expr(&mut self, opt_label: Option<Label>,
3508 mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3509 // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
3511 let pat = self.parse_top_level_pat()?;
3512 if !self.eat_keyword(keywords::In) {
3513 let in_span = self.prev_span.between(self.span);
3514 let mut err = self.sess.span_diagnostic
3515 .struct_span_err(in_span, "missing `in` in `for` loop");
3516 err.span_suggestion_short_with_applicability(
3517 in_span, "try adding `in` here", " in ".into(),
3518 // has been misleading, at least in the past (closed Issue #48492)
3519 Applicability::MaybeIncorrect
3523 let in_span = self.prev_span;
3524 if self.eat_keyword(keywords::In) {
3525 // a common typo: `for _ in in bar {}`
3526 let mut err = self.sess.span_diagnostic.struct_span_err(
3528 "expected iterable, found keyword `in`",
3530 err.span_suggestion_short_with_applicability(
3531 in_span.until(self.prev_span),
3532 "remove the duplicated `in`",
3534 Applicability::MachineApplicable,
3536 err.note("if you meant to use emplacement syntax, it is obsolete (for now, anyway)");
3537 err.note("for more information on the status of emplacement syntax, see <\
3538 https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911>");
3541 let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3542 let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
3543 attrs.extend(iattrs);
3545 let hi = self.prev_span;
3546 Ok(self.mk_expr(span_lo.to(hi), ExprKind::ForLoop(pat, expr, loop_block, opt_label), attrs))
3549 /// Parse a 'while' or 'while let' expression ('while' token already eaten)
3550 fn parse_while_expr(&mut self, opt_label: Option<Label>,
3552 mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3553 if self.token.is_keyword(keywords::Let) {
3554 return self.parse_while_let_expr(opt_label, span_lo, attrs);
3556 let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3557 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
3558 attrs.extend(iattrs);
3559 let span = span_lo.to(body.span);
3560 return Ok(self.mk_expr(span, ExprKind::While(cond, body, opt_label), attrs));
3563 /// Parse a 'while let' expression ('while' token already eaten)
3564 fn parse_while_let_expr(&mut self, opt_label: Option<Label>,
3566 mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3567 self.expect_keyword(keywords::Let)?;
3568 let pats = self.parse_pats()?;
3569 self.expect(&token::Eq)?;
3570 let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3571 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
3572 attrs.extend(iattrs);
3573 let span = span_lo.to(body.span);
3574 return Ok(self.mk_expr(span, ExprKind::WhileLet(pats, expr, body, opt_label), attrs));
3577 // parse `loop {...}`, `loop` token already eaten
3578 fn parse_loop_expr(&mut self, opt_label: Option<Label>,
3580 mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3581 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
3582 attrs.extend(iattrs);
3583 let span = span_lo.to(body.span);
3584 Ok(self.mk_expr(span, ExprKind::Loop(body, opt_label), attrs))
3587 /// Parse an `async move {...}` expression
3588 pub fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>)
3589 -> PResult<'a, P<Expr>>
3591 let span_lo = self.span;
3592 self.expect_keyword(keywords::Async)?;
3593 let capture_clause = if self.eat_keyword(keywords::Move) {
3598 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
3599 attrs.extend(iattrs);
3601 span_lo.to(body.span),
3602 ExprKind::Async(capture_clause, ast::DUMMY_NODE_ID, body), attrs))
3605 /// Parse a `try {...}` expression (`try` token already eaten)
3606 fn parse_try_block(&mut self, span_lo: Span, mut attrs: ThinVec<Attribute>)
3607 -> PResult<'a, P<Expr>>
3609 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
3610 attrs.extend(iattrs);
3611 Ok(self.mk_expr(span_lo.to(body.span), ExprKind::TryBlock(body), attrs))
3614 // `match` token already eaten
3615 fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3616 let match_span = self.prev_span;
3617 let lo = self.prev_span;
3618 let discriminant = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL,
3620 if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) {
3621 if self.token == token::Token::Semi {
3622 e.span_suggestion_short_with_applicability(
3624 "try removing this `match`",
3626 Applicability::MaybeIncorrect // speculative
3631 attrs.extend(self.parse_inner_attributes()?);
3633 let mut arms: Vec<Arm> = Vec::new();
3634 while self.token != token::CloseDelim(token::Brace) {
3635 match self.parse_arm() {
3636 Ok(arm) => arms.push(arm),
3638 // Recover by skipping to the end of the block.
3640 self.recover_stmt();
3641 let span = lo.to(self.span);
3642 if self.token == token::CloseDelim(token::Brace) {
3645 return Ok(self.mk_expr(span, ExprKind::Match(discriminant, arms), attrs));
3651 return Ok(self.mk_expr(lo.to(hi), ExprKind::Match(discriminant, arms), attrs));
3654 crate fn parse_arm(&mut self) -> PResult<'a, Arm> {
3655 maybe_whole!(self, NtArm, |x| x);
3657 let attrs = self.parse_outer_attributes()?;
3658 // Allow a '|' before the pats (RFC 1925)
3659 self.eat(&token::BinOp(token::Or));
3660 let pats = self.parse_pats()?;
3661 let guard = if self.eat_keyword(keywords::If) {
3662 Some(Guard::If(self.parse_expr()?))
3666 let arrow_span = self.span;
3667 self.expect(&token::FatArrow)?;
3668 let arm_start_span = self.span;
3670 let expr = self.parse_expr_res(Restrictions::STMT_EXPR, None)
3671 .map_err(|mut err| {
3672 err.span_label(arrow_span, "while parsing the `match` arm starting here");
3676 let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
3677 && self.token != token::CloseDelim(token::Brace);
3680 let cm = self.sess.source_map();
3681 self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])
3682 .map_err(|mut err| {
3683 match (cm.span_to_lines(expr.span), cm.span_to_lines(arm_start_span)) {
3684 (Ok(ref expr_lines), Ok(ref arm_start_lines))
3685 if arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col
3686 && expr_lines.lines.len() == 2
3687 && self.token == token::FatArrow => {
3688 // We check whether there's any trailing code in the parse span,
3689 // if there isn't, we very likely have the following:
3692 // | -- - missing comma
3698 // | parsed until here as `"y" & X`
3699 err.span_suggestion_short_with_applicability(
3700 cm.next_point(arm_start_span),
3701 "missing a comma here to end this `match` arm",
3703 Applicability::MachineApplicable
3707 err.span_label(arrow_span,
3708 "while parsing the `match` arm starting here");
3714 self.eat(&token::Comma);
3725 /// Parse an expression
3727 pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
3728 self.parse_expr_res(Restrictions::empty(), None)
3731 /// Evaluate the closure with restrictions in place.
3733 /// After the closure is evaluated, restrictions are reset.
3734 fn with_res<F, T>(&mut self, r: Restrictions, f: F) -> T
3735 where F: FnOnce(&mut Self) -> T
3737 let old = self.restrictions;
3738 self.restrictions = r;
3740 self.restrictions = old;
3745 /// Parse an expression, subject to the given restrictions
3747 fn parse_expr_res(&mut self, r: Restrictions,
3748 already_parsed_attrs: Option<ThinVec<Attribute>>)
3749 -> PResult<'a, P<Expr>> {
3750 self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs))
3753 /// Parse the RHS of a local variable declaration (e.g., '= 14;')
3754 fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option<P<Expr>>> {
3755 if self.eat(&token::Eq) {
3756 Ok(Some(self.parse_expr()?))
3758 Ok(Some(self.parse_expr()?))
3764 /// Parse patterns, separated by '|' s
3765 fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> {
3766 let mut pats = Vec::new();
3768 pats.push(self.parse_top_level_pat()?);
3770 if self.token == token::OrOr {
3771 let mut err = self.struct_span_err(self.span,
3772 "unexpected token `||` after pattern");
3773 err.span_suggestion_with_applicability(
3775 "use a single `|` to specify multiple patterns",
3777 Applicability::MachineApplicable
3781 } else if self.eat(&token::BinOp(token::Or)) {
3789 // Parses a parenthesized list of patterns like
3790 // `()`, `(p)`, `(p,)`, `(p, q)`, or `(p, .., q)`. Returns:
3791 // - a vector of the patterns that were parsed
3792 // - an option indicating the index of the `..` element
3793 // - a boolean indicating whether a trailing comma was present.
3794 // Trailing commas are significant because (p) and (p,) are different patterns.
3795 fn parse_parenthesized_pat_list(&mut self) -> PResult<'a, (Vec<P<Pat>>, Option<usize>, bool)> {
3796 self.expect(&token::OpenDelim(token::Paren))?;
3797 let result = self.parse_pat_list()?;
3798 self.expect(&token::CloseDelim(token::Paren))?;
3802 fn parse_pat_list(&mut self) -> PResult<'a, (Vec<P<Pat>>, Option<usize>, bool)> {
3803 let mut fields = Vec::new();
3804 let mut ddpos = None;
3805 let mut trailing_comma = false;
3807 if self.eat(&token::DotDot) {
3808 if ddpos.is_none() {
3809 ddpos = Some(fields.len());
3811 // Emit a friendly error, ignore `..` and continue parsing
3812 self.span_err(self.prev_span,
3813 "`..` can only be used once per tuple or tuple struct pattern");
3815 } else if !self.check(&token::CloseDelim(token::Paren)) {
3816 fields.push(self.parse_pat(None)?);
3821 trailing_comma = self.eat(&token::Comma);
3822 if !trailing_comma {
3827 if ddpos == Some(fields.len()) && trailing_comma {
3828 // `..` needs to be followed by `)` or `, pat`, `..,)` is disallowed.
3829 self.span_err(self.prev_span, "trailing comma is not permitted after `..`");
3832 Ok((fields, ddpos, trailing_comma))
3835 fn parse_pat_vec_elements(
3837 ) -> PResult<'a, (Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>)> {
3838 let mut before = Vec::new();
3839 let mut slice = None;
3840 let mut after = Vec::new();
3841 let mut first = true;
3842 let mut before_slice = true;
3844 while self.token != token::CloseDelim(token::Bracket) {
3848 self.expect(&token::Comma)?;
3850 if self.token == token::CloseDelim(token::Bracket)
3851 && (before_slice || !after.is_empty()) {
3857 if self.eat(&token::DotDot) {
3859 if self.check(&token::Comma) ||
3860 self.check(&token::CloseDelim(token::Bracket)) {
3861 slice = Some(P(Pat {
3862 id: ast::DUMMY_NODE_ID,
3863 node: PatKind::Wild,
3864 span: self.prev_span,
3866 before_slice = false;
3872 let subpat = self.parse_pat(None)?;
3873 if before_slice && self.eat(&token::DotDot) {
3874 slice = Some(subpat);
3875 before_slice = false;
3876 } else if before_slice {
3877 before.push(subpat);
3883 Ok((before, slice, after))
3889 attrs: Vec<Attribute>
3890 ) -> PResult<'a, source_map::Spanned<ast::FieldPat>> {
3891 // Check if a colon exists one ahead. This means we're parsing a fieldname.
3893 let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
3894 // Parsing a pattern of the form "fieldname: pat"
3895 let fieldname = self.parse_field_name()?;
3897 let pat = self.parse_pat(None)?;
3899 (pat, fieldname, false)
3901 // Parsing a pattern of the form "(box) (ref) (mut) fieldname"
3902 let is_box = self.eat_keyword(keywords::Box);
3903 let boxed_span = self.span;
3904 let is_ref = self.eat_keyword(keywords::Ref);
3905 let is_mut = self.eat_keyword(keywords::Mut);
3906 let fieldname = self.parse_ident()?;
3907 hi = self.prev_span;
3909 let bind_type = match (is_ref, is_mut) {
3910 (true, true) => BindingMode::ByRef(Mutability::Mutable),
3911 (true, false) => BindingMode::ByRef(Mutability::Immutable),
3912 (false, true) => BindingMode::ByValue(Mutability::Mutable),
3913 (false, false) => BindingMode::ByValue(Mutability::Immutable),
3915 let fieldpat = P(Pat {
3916 id: ast::DUMMY_NODE_ID,
3917 node: PatKind::Ident(bind_type, fieldname, None),
3918 span: boxed_span.to(hi),
3921 let subpat = if is_box {
3923 id: ast::DUMMY_NODE_ID,
3924 node: PatKind::Box(fieldpat),
3930 (subpat, fieldname, true)
3933 Ok(source_map::Spanned {
3935 node: ast::FieldPat {
3939 attrs: attrs.into(),
3944 /// Parse the fields of a struct-like pattern
3945 fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<source_map::Spanned<ast::FieldPat>>, bool)> {
3946 let mut fields = Vec::new();
3947 let mut etc = false;
3948 let mut ate_comma = true;
3949 let mut delayed_err: Option<DiagnosticBuilder<'a>> = None;
3950 let mut etc_span = None;
3952 while self.token != token::CloseDelim(token::Brace) {
3953 let attrs = self.parse_outer_attributes()?;
3956 // check that a comma comes after every field
3958 let err = self.struct_span_err(self.prev_span, "expected `,`");
3959 if let Some(mut delayed) = delayed_err {
3966 if self.check(&token::DotDot) || self.token == token::DotDotDot {
3968 let mut etc_sp = self.span;
3970 if self.token == token::DotDotDot { // Issue #46718
3971 // Accept `...` as if it were `..` to avoid further errors
3972 let mut err = self.struct_span_err(self.span,
3973 "expected field pattern, found `...`");
3974 err.span_suggestion_with_applicability(
3976 "to omit remaining fields, use one fewer `.`",
3978 Applicability::MachineApplicable
3982 self.bump(); // `..` || `...`
3984 if self.token == token::CloseDelim(token::Brace) {
3985 etc_span = Some(etc_sp);
3988 let token_str = self.this_token_descr();
3989 let mut err = self.fatal(&format!("expected `}}`, found {}", token_str));
3991 err.span_label(self.span, "expected `}`");
3992 let mut comma_sp = None;
3993 if self.token == token::Comma { // Issue #49257
3994 etc_sp = etc_sp.to(self.sess.source_map().span_until_non_whitespace(self.span));
3995 err.span_label(etc_sp,
3996 "`..` must be at the end and cannot have a trailing comma");
3997 comma_sp = Some(self.span);
4002 etc_span = Some(etc_sp.until(self.span));
4003 if self.token == token::CloseDelim(token::Brace) {
4004 // If the struct looks otherwise well formed, recover and continue.
4005 if let Some(sp) = comma_sp {
4006 err.span_suggestion_short_with_applicability(
4008 "remove this comma",
4010 Applicability::MachineApplicable,
4015 } else if self.token.is_ident() && ate_comma {
4016 // Accept fields coming after `..,`.
4017 // This way we avoid "pattern missing fields" errors afterwards.
4018 // We delay this error until the end in order to have a span for a
4020 if let Some(mut delayed_err) = delayed_err {
4024 delayed_err = Some(err);
4027 if let Some(mut err) = delayed_err {
4034 fields.push(match self.parse_pat_field(lo, attrs) {
4037 if let Some(mut delayed_err) = delayed_err {
4043 ate_comma = self.eat(&token::Comma);
4046 if let Some(mut err) = delayed_err {
4047 if let Some(etc_span) = etc_span {
4048 err.multipart_suggestion(
4049 "move the `..` to the end of the field list",
4051 (etc_span, String::new()),
4052 (self.span, format!("{}.. }}", if ate_comma { "" } else { ", " })),
4058 return Ok((fields, etc));
4061 fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
4062 if self.token.is_path_start() {
4064 let (qself, path) = if self.eat_lt() {
4065 // Parse a qualified path
4066 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
4069 // Parse an unqualified path
4070 (None, self.parse_path(PathStyle::Expr)?)
4072 let hi = self.prev_span;
4073 Ok(self.mk_expr(lo.to(hi), ExprKind::Path(qself, path), ThinVec::new()))
4075 self.parse_literal_maybe_minus()
4079 // helper function to decide whether to parse as ident binding or to try to do
4080 // something more complex like range patterns
4081 fn parse_as_ident(&mut self) -> bool {
4082 self.look_ahead(1, |t| match *t {
4083 token::OpenDelim(token::Paren) | token::OpenDelim(token::Brace) |
4084 token::DotDotDot | token::DotDotEq | token::ModSep | token::Not => Some(false),
4085 // ensure slice patterns [a, b.., c] and [a, b, c..] don't go into the
4086 // range pattern branch
4087 token::DotDot => None,
4089 }).unwrap_or_else(|| self.look_ahead(2, |t| match *t {
4090 token::Comma | token::CloseDelim(token::Bracket) => true,
4095 /// A wrapper around `parse_pat` with some special error handling for the
4096 /// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast
4097 /// to subpatterns within such).
4098 fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
4099 let pat = self.parse_pat(None)?;
4100 if self.token == token::Comma {
4101 // An unexpected comma after a top-level pattern is a clue that the
4102 // user (perhaps more accustomed to some other language) forgot the
4103 // parentheses in what should have been a tuple pattern; return a
4104 // suggestion-enhanced error here rather than choking on the comma
4106 let comma_span = self.span;
4108 if let Err(mut err) = self.parse_pat_list() {
4109 // We didn't expect this to work anyway; we just wanted
4110 // to advance to the end of the comma-sequence so we know
4111 // the span to suggest parenthesizing
4114 let seq_span = pat.span.to(self.prev_span);
4115 let mut err = self.struct_span_err(comma_span,
4116 "unexpected `,` in pattern");
4117 if let Ok(seq_snippet) = self.sess.source_map().span_to_snippet(seq_span) {
4118 err.span_suggestion_with_applicability(
4120 "try adding parentheses",
4121 format!("({})", seq_snippet),
4122 Applicability::MachineApplicable
4130 /// Parse a pattern.
4131 pub fn parse_pat(&mut self, expected: Option<&'static str>) -> PResult<'a, P<Pat>> {
4132 self.parse_pat_with_range_pat(true, expected)
4135 /// Parse a pattern, with a setting whether modern range patterns e.g., `a..=b`, `a..b` are
4137 fn parse_pat_with_range_pat(
4139 allow_range_pat: bool,
4140 expected: Option<&'static str>,
4141 ) -> PResult<'a, P<Pat>> {
4142 maybe_whole!(self, NtPat, |x| x);
4147 token::BinOp(token::And) | token::AndAnd => {
4148 // Parse &pat / &mut pat
4150 let mutbl = self.parse_mutability();
4151 if let token::Lifetime(ident) = self.token {
4152 let mut err = self.fatal(&format!("unexpected lifetime `{}` in pattern",
4154 err.span_label(self.span, "unexpected lifetime");
4157 let subpat = self.parse_pat_with_range_pat(false, expected)?;
4158 pat = PatKind::Ref(subpat, mutbl);
4160 token::OpenDelim(token::Paren) => {
4161 // Parse (pat,pat,pat,...) as tuple pattern
4162 let (fields, ddpos, trailing_comma) = self.parse_parenthesized_pat_list()?;
4163 pat = if fields.len() == 1 && ddpos.is_none() && !trailing_comma {
4164 PatKind::Paren(fields.into_iter().nth(0).unwrap())
4166 PatKind::Tuple(fields, ddpos)
4169 token::OpenDelim(token::Bracket) => {
4170 // Parse [pat,pat,...] as slice pattern
4172 let (before, slice, after) = self.parse_pat_vec_elements()?;
4173 self.expect(&token::CloseDelim(token::Bracket))?;
4174 pat = PatKind::Slice(before, slice, after);
4176 // At this point, token != &, &&, (, [
4177 _ => if self.eat_keyword(keywords::Underscore) {
4179 pat = PatKind::Wild;
4180 } else if self.eat_keyword(keywords::Mut) {
4181 // Parse mut ident @ pat / mut ref ident @ pat
4182 let mutref_span = self.prev_span.to(self.span);
4183 let binding_mode = if self.eat_keyword(keywords::Ref) {
4185 .struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect")
4186 .span_suggestion_with_applicability(
4188 "try switching the order",
4190 Applicability::MachineApplicable
4192 BindingMode::ByRef(Mutability::Mutable)
4194 BindingMode::ByValue(Mutability::Mutable)
4196 pat = self.parse_pat_ident(binding_mode)?;
4197 } else if self.eat_keyword(keywords::Ref) {
4198 // Parse ref ident @ pat / ref mut ident @ pat
4199 let mutbl = self.parse_mutability();
4200 pat = self.parse_pat_ident(BindingMode::ByRef(mutbl))?;
4201 } else if self.eat_keyword(keywords::Box) {
4203 let subpat = self.parse_pat_with_range_pat(false, None)?;
4204 pat = PatKind::Box(subpat);
4205 } else if self.token.is_ident() && !self.token.is_reserved_ident() &&
4206 self.parse_as_ident() {
4207 // Parse ident @ pat
4208 // This can give false positives and parse nullary enums,
4209 // they are dealt with later in resolve
4210 let binding_mode = BindingMode::ByValue(Mutability::Immutable);
4211 pat = self.parse_pat_ident(binding_mode)?;
4212 } else if self.token.is_path_start() {
4213 // Parse pattern starting with a path
4214 let (qself, path) = if self.eat_lt() {
4215 // Parse a qualified path
4216 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
4219 // Parse an unqualified path
4220 (None, self.parse_path(PathStyle::Expr)?)
4223 token::Not if qself.is_none() => {
4224 // Parse macro invocation
4226 let (delim, tts) = self.expect_delimited_token_tree()?;
4227 let mac = respan(lo.to(self.prev_span), Mac_ { path, tts, delim });
4228 pat = PatKind::Mac(mac);
4230 token::DotDotDot | token::DotDotEq | token::DotDot => {
4231 let end_kind = match self.token {
4232 token::DotDot => RangeEnd::Excluded,
4233 token::DotDotDot => RangeEnd::Included(RangeSyntax::DotDotDot),
4234 token::DotDotEq => RangeEnd::Included(RangeSyntax::DotDotEq),
4235 _ => panic!("can only parse `..`/`...`/`..=` for ranges \
4238 let op_span = self.span;
4240 let span = lo.to(self.prev_span);
4241 let begin = self.mk_expr(span, ExprKind::Path(qself, path), ThinVec::new());
4243 let end = self.parse_pat_range_end()?;
4244 let op = Spanned { span: op_span, node: end_kind };
4245 pat = PatKind::Range(begin, end, op);
4247 token::OpenDelim(token::Brace) => {
4248 if qself.is_some() {
4249 let msg = "unexpected `{` after qualified path";
4250 let mut err = self.fatal(msg);
4251 err.span_label(self.span, msg);
4254 // Parse struct pattern
4256 let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
4258 self.recover_stmt();
4262 pat = PatKind::Struct(path, fields, etc);
4264 token::OpenDelim(token::Paren) => {
4265 if qself.is_some() {
4266 let msg = "unexpected `(` after qualified path";
4267 let mut err = self.fatal(msg);
4268 err.span_label(self.span, msg);
4271 // Parse tuple struct or enum pattern
4272 let (fields, ddpos, _) = self.parse_parenthesized_pat_list()?;
4273 pat = PatKind::TupleStruct(path, fields, ddpos)
4275 _ => pat = PatKind::Path(qself, path),
4278 // Try to parse everything else as literal with optional minus
4279 match self.parse_literal_maybe_minus() {
4281 let op_span = self.span;
4282 if self.check(&token::DotDot) || self.check(&token::DotDotEq) ||
4283 self.check(&token::DotDotDot) {
4284 let end_kind = if self.eat(&token::DotDotDot) {
4285 RangeEnd::Included(RangeSyntax::DotDotDot)
4286 } else if self.eat(&token::DotDotEq) {
4287 RangeEnd::Included(RangeSyntax::DotDotEq)
4288 } else if self.eat(&token::DotDot) {
4291 panic!("impossible case: we already matched \
4292 on a range-operator token")
4294 let end = self.parse_pat_range_end()?;
4295 let op = Spanned { span: op_span, node: end_kind };
4296 pat = PatKind::Range(begin, end, op);
4298 pat = PatKind::Lit(begin);
4302 self.cancel(&mut err);
4303 let expected = expected.unwrap_or("pattern");
4305 "expected {}, found {}",
4307 self.this_token_descr(),
4309 let mut err = self.fatal(&msg);
4310 err.span_label(self.span, format!("expected {}", expected));
4317 let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID };
4318 let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
4320 if !allow_range_pat {
4323 _, _, Spanned { node: RangeEnd::Included(RangeSyntax::DotDotDot), .. }
4325 PatKind::Range(..) => {
4326 let mut err = self.struct_span_err(
4328 "the range pattern here has ambiguous interpretation",
4330 err.span_suggestion_with_applicability(
4332 "add parentheses to clarify the precedence",
4333 format!("({})", pprust::pat_to_string(&pat)),
4334 // "ambiguous interpretation" implies that we have to be guessing
4335 Applicability::MaybeIncorrect
4346 /// Parse ident or ident @ pat
4347 /// used by the copy foo and ref foo patterns to give a good
4348 /// error message when parsing mistakes like ref foo(a,b)
4349 fn parse_pat_ident(&mut self,
4350 binding_mode: ast::BindingMode)
4351 -> PResult<'a, PatKind> {
4352 let ident = self.parse_ident()?;
4353 let sub = if self.eat(&token::At) {
4354 Some(self.parse_pat(Some("binding pattern"))?)
4359 // just to be friendly, if they write something like
4361 // we end up here with ( as the current token. This shortly
4362 // leads to a parse error. Note that if there is no explicit
4363 // binding mode then we do not end up here, because the lookahead
4364 // will direct us over to parse_enum_variant()
4365 if self.token == token::OpenDelim(token::Paren) {
4366 return Err(self.span_fatal(
4368 "expected identifier, found enum pattern"))
4371 Ok(PatKind::Ident(binding_mode, ident, sub))
4374 /// Parse a local variable declaration
4375 fn parse_local(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Local>> {
4376 let lo = self.prev_span;
4377 let pat = self.parse_top_level_pat()?;
4379 let (err, ty) = if self.eat(&token::Colon) {
4380 // Save the state of the parser before parsing type normally, in case there is a `:`
4381 // instead of an `=` typo.
4382 let parser_snapshot_before_type = self.clone();
4383 let colon_sp = self.prev_span;
4384 match self.parse_ty() {
4385 Ok(ty) => (None, Some(ty)),
4387 // Rewind to before attempting to parse the type and continue parsing
4388 let parser_snapshot_after_type = self.clone();
4389 mem::replace(self, parser_snapshot_before_type);
4391 let snippet = self.sess.source_map().span_to_snippet(pat.span).unwrap();
4392 err.span_label(pat.span, format!("while parsing the type for `{}`", snippet));
4393 (Some((parser_snapshot_after_type, colon_sp, err)), None)
4399 let init = match (self.parse_initializer(err.is_some()), err) {
4400 (Ok(init), None) => { // init parsed, ty parsed
4403 (Ok(init), Some((_, colon_sp, mut err))) => { // init parsed, ty error
4404 // Could parse the type as if it were the initializer, it is likely there was a
4405 // typo in the code: `:` instead of `=`. Add suggestion and emit the error.
4406 err.span_suggestion_short_with_applicability(
4408 "use `=` if you meant to assign",
4410 Applicability::MachineApplicable
4413 // As this was parsed successfully, continue as if the code has been fixed for the
4414 // rest of the file. It will still fail due to the emitted error, but we avoid
4418 (Err(mut init_err), Some((snapshot, _, ty_err))) => { // init error, ty error
4420 // Couldn't parse the type nor the initializer, only raise the type error and
4421 // return to the parser state before parsing the type as the initializer.
4422 // let x: <parse_error>;
4423 mem::replace(self, snapshot);
4426 (Err(err), None) => { // init error, ty parsed
4427 // Couldn't parse the initializer and we're not attempting to recover a failed
4428 // parse of the type, return the error.
4432 let hi = if self.token == token::Semi {
4441 id: ast::DUMMY_NODE_ID,
4447 /// Parse a structure field
4448 fn parse_name_and_ty(&mut self,
4451 attrs: Vec<Attribute>)
4452 -> PResult<'a, StructField> {
4453 let name = self.parse_ident()?;
4454 self.expect(&token::Colon)?;
4455 let ty = self.parse_ty()?;
4457 span: lo.to(self.prev_span),
4460 id: ast::DUMMY_NODE_ID,
4466 /// Emit an expected item after attributes error.
4467 fn expected_item_err(&self, attrs: &[Attribute]) {
4468 let message = match attrs.last() {
4469 Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment",
4470 _ => "expected item after attributes",
4473 self.span_err(self.prev_span, message);
4476 /// Parse a statement. This stops just before trailing semicolons on everything but items.
4477 /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
4478 pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
4479 Ok(self.parse_stmt_(true))
4482 // Eat tokens until we can be relatively sure we reached the end of the
4483 // statement. This is something of a best-effort heuristic.
4485 // We terminate when we find an unmatched `}` (without consuming it).
4486 fn recover_stmt(&mut self) {
4487 self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore)
4490 // If `break_on_semi` is `Break`, then we will stop consuming tokens after
4491 // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
4492 // approximate - it can mean we break too early due to macros, but that
4493 // should only lead to sub-optimal recovery, not inaccurate parsing).
4495 // If `break_on_block` is `Break`, then we will stop consuming tokens
4496 // after finding (and consuming) a brace-delimited block.
4497 fn recover_stmt_(&mut self, break_on_semi: SemiColonMode, break_on_block: BlockMode) {
4498 let mut brace_depth = 0;
4499 let mut bracket_depth = 0;
4500 let mut in_block = false;
4501 debug!("recover_stmt_ enter loop (semi={:?}, block={:?})",
4502 break_on_semi, break_on_block);
4504 debug!("recover_stmt_ loop {:?}", self.token);
4506 token::OpenDelim(token::DelimToken::Brace) => {
4509 if break_on_block == BlockMode::Break &&
4511 bracket_depth == 0 {
4515 token::OpenDelim(token::DelimToken::Bracket) => {
4519 token::CloseDelim(token::DelimToken::Brace) => {
4520 if brace_depth == 0 {
4521 debug!("recover_stmt_ return - close delim {:?}", self.token);
4526 if in_block && bracket_depth == 0 && brace_depth == 0 {
4527 debug!("recover_stmt_ return - block end {:?}", self.token);
4531 token::CloseDelim(token::DelimToken::Bracket) => {
4533 if bracket_depth < 0 {
4539 debug!("recover_stmt_ return - Eof");
4544 if break_on_semi == SemiColonMode::Break &&
4546 bracket_depth == 0 {
4547 debug!("recover_stmt_ return - Semi");
4558 fn parse_stmt_(&mut self, macro_legacy_warnings: bool) -> Option<Stmt> {
4559 self.parse_stmt_without_recovery(macro_legacy_warnings).unwrap_or_else(|mut e| {
4561 self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
4566 fn is_async_block(&mut self) -> bool {
4567 self.token.is_keyword(keywords::Async) &&
4570 self.look_ahead(1, |t| t.is_keyword(keywords::Move)) &&
4571 self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))
4573 self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace))
4578 fn is_do_catch_block(&mut self) -> bool {
4579 self.token.is_keyword(keywords::Do) &&
4580 self.look_ahead(1, |t| t.is_keyword(keywords::Catch)) &&
4581 self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) &&
4582 !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
4585 fn is_try_block(&mut self) -> bool {
4586 self.token.is_keyword(keywords::Try) &&
4587 self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) &&
4588 self.span.rust_2018() &&
4589 // prevent `while try {} {}`, `if try {} {} else {}`, etc.
4590 !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
4593 fn is_union_item(&self) -> bool {
4594 self.token.is_keyword(keywords::Union) &&
4595 self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
4598 fn is_crate_vis(&self) -> bool {
4599 self.token.is_keyword(keywords::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
4602 fn is_extern_non_path(&self) -> bool {
4603 self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep)
4606 fn is_existential_type_decl(&self) -> bool {
4607 self.token.is_keyword(keywords::Existential) &&
4608 self.look_ahead(1, |t| t.is_keyword(keywords::Type))
4611 fn is_auto_trait_item(&mut self) -> bool {
4613 (self.token.is_keyword(keywords::Auto)
4614 && self.look_ahead(1, |t| t.is_keyword(keywords::Trait)))
4615 || // unsafe auto trait
4616 (self.token.is_keyword(keywords::Unsafe) &&
4617 self.look_ahead(1, |t| t.is_keyword(keywords::Auto)) &&
4618 self.look_ahead(2, |t| t.is_keyword(keywords::Trait)))
4621 fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span)
4622 -> PResult<'a, Option<P<Item>>> {
4623 let token_lo = self.span;
4624 let (ident, def) = match self.token {
4625 token::Ident(ident, false) if ident.name == keywords::Macro.name() => {
4627 let ident = self.parse_ident()?;
4628 let tokens = if self.check(&token::OpenDelim(token::Brace)) {
4629 match self.parse_token_tree() {
4630 TokenTree::Delimited(_, _, tts) => tts.stream(),
4631 _ => unreachable!(),
4633 } else if self.check(&token::OpenDelim(token::Paren)) {
4634 let args = self.parse_token_tree();
4635 let body = if self.check(&token::OpenDelim(token::Brace)) {
4636 self.parse_token_tree()
4641 TokenStream::new(vec![
4643 TokenTree::Token(token_lo.to(self.prev_span), token::FatArrow).into(),
4651 (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
4653 token::Ident(ident, _) if ident.name == "macro_rules" &&
4654 self.look_ahead(1, |t| *t == token::Not) => {
4655 let prev_span = self.prev_span;
4656 self.complain_if_pub_macro(&vis.node, prev_span);
4660 let ident = self.parse_ident()?;
4661 let (delim, tokens) = self.expect_delimited_token_tree()?;
4662 if delim != MacDelimiter::Brace {
4663 if !self.eat(&token::Semi) {
4664 let msg = "macros that expand to items must either \
4665 be surrounded with braces or followed by a semicolon";
4666 self.span_err(self.prev_span, msg);
4670 (ident, ast::MacroDef { tokens: tokens, legacy: true })
4672 _ => return Ok(None),
4675 let span = lo.to(self.prev_span);
4676 Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
4679 fn parse_stmt_without_recovery(&mut self,
4680 macro_legacy_warnings: bool)
4681 -> PResult<'a, Option<Stmt>> {
4682 maybe_whole!(self, NtStmt, |x| Some(x));
4684 let attrs = self.parse_outer_attributes()?;
4687 Ok(Some(if self.eat_keyword(keywords::Let) {
4689 id: ast::DUMMY_NODE_ID,
4690 node: StmtKind::Local(self.parse_local(attrs.into())?),
4691 span: lo.to(self.prev_span),
4693 } else if let Some(macro_def) = self.eat_macro_def(
4695 &source_map::respan(lo, VisibilityKind::Inherited),
4699 id: ast::DUMMY_NODE_ID,
4700 node: StmtKind::Item(macro_def),
4701 span: lo.to(self.prev_span),
4703 // Starts like a simple path, being careful to avoid contextual keywords
4704 // such as a union items, item with `crate` visibility or auto trait items.
4705 // Our goal here is to parse an arbitrary path `a::b::c` but not something that starts
4706 // like a path (1 token), but it fact not a path.
4707 // `union::b::c` - path, `union U { ... }` - not a path.
4708 // `crate::b::c` - path, `crate struct S;` - not a path.
4709 // `extern::b::c` - path, `extern crate c;` - not a path.
4710 } else if self.token.is_path_start() &&
4711 !self.token.is_qpath_start() &&
4712 !self.is_union_item() &&
4713 !self.is_crate_vis() &&
4714 !self.is_extern_non_path() &&
4715 !self.is_existential_type_decl() &&
4716 !self.is_auto_trait_item() {
4717 let pth = self.parse_path(PathStyle::Expr)?;
4719 if !self.eat(&token::Not) {
4720 let expr = if self.check(&token::OpenDelim(token::Brace)) {
4721 self.parse_struct_expr(lo, pth, ThinVec::new())?
4723 let hi = self.prev_span;
4724 self.mk_expr(lo.to(hi), ExprKind::Path(None, pth), ThinVec::new())
4727 let expr = self.with_res(Restrictions::STMT_EXPR, |this| {
4728 let expr = this.parse_dot_or_call_expr_with(expr, lo, attrs.into())?;
4729 this.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(expr))
4732 return Ok(Some(Stmt {
4733 id: ast::DUMMY_NODE_ID,
4734 node: StmtKind::Expr(expr),
4735 span: lo.to(self.prev_span),
4739 // it's a macro invocation
4740 let id = match self.token {
4741 token::OpenDelim(_) => keywords::Invalid.ident(), // no special identifier
4742 _ => self.parse_ident()?,
4745 // check that we're pointing at delimiters (need to check
4746 // again after the `if`, because of `parse_ident`
4747 // consuming more tokens).
4749 token::OpenDelim(_) => {}
4751 // we only expect an ident if we didn't parse one
4753 let ident_str = if id.name == keywords::Invalid.name() {
4758 let tok_str = self.this_token_descr();
4759 let mut err = self.fatal(&format!("expected {}`(` or `{{`, found {}",
4762 err.span_label(self.span, format!("expected {}`(` or `{{`", ident_str));
4767 let (delim, tts) = self.expect_delimited_token_tree()?;
4768 let hi = self.prev_span;
4770 let style = if delim == MacDelimiter::Brace {
4771 MacStmtStyle::Braces
4773 MacStmtStyle::NoBraces
4776 if id.name == keywords::Invalid.name() {
4777 let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim });
4778 let node = if delim == MacDelimiter::Brace ||
4779 self.token == token::Semi || self.token == token::Eof {
4780 StmtKind::Mac(P((mac, style, attrs.into())))
4782 // We used to incorrectly stop parsing macro-expanded statements here.
4783 // If the next token will be an error anyway but could have parsed with the
4784 // earlier behavior, stop parsing here and emit a warning to avoid breakage.
4785 else if macro_legacy_warnings && self.token.can_begin_expr() && match self.token {
4786 // These can continue an expression, so we can't stop parsing and warn.
4787 token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) |
4788 token::BinOp(token::Minus) | token::BinOp(token::Star) |
4789 token::BinOp(token::And) | token::BinOp(token::Or) |
4790 token::AndAnd | token::OrOr |
4791 token::DotDot | token::DotDotDot | token::DotDotEq => false,
4794 self.warn_missing_semicolon();
4795 StmtKind::Mac(P((mac, style, attrs.into())))
4797 let e = self.mk_mac_expr(lo.to(hi), mac.node, ThinVec::new());
4798 let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
4799 let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
4803 id: ast::DUMMY_NODE_ID,
4808 // if it has a special ident, it's definitely an item
4810 // Require a semicolon or braces.
4811 if style != MacStmtStyle::Braces {
4812 if !self.eat(&token::Semi) {
4813 self.span_err(self.prev_span,
4814 "macros that expand to items must \
4815 either be surrounded with braces or \
4816 followed by a semicolon");
4819 let span = lo.to(hi);
4821 id: ast::DUMMY_NODE_ID,
4823 node: StmtKind::Item({
4825 span, id /*id is good here*/,
4826 ItemKind::Mac(respan(span, Mac_ { path: pth, tts, delim })),
4827 respan(lo, VisibilityKind::Inherited),
4833 // FIXME: Bad copy of attrs
4834 let old_directory_ownership =
4835 mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock);
4836 let item = self.parse_item_(attrs.clone(), false, true)?;
4837 self.directory.ownership = old_directory_ownership;
4841 id: ast::DUMMY_NODE_ID,
4842 span: lo.to(i.span),
4843 node: StmtKind::Item(i),
4846 let unused_attrs = |attrs: &[Attribute], s: &mut Self| {
4847 if !attrs.is_empty() {
4848 if s.prev_token_kind == PrevTokenKind::DocComment {
4849 s.span_fatal_err(s.prev_span, Error::UselessDocComment).emit();
4850 } else if attrs.iter().any(|a| a.style == AttrStyle::Outer) {
4851 s.span_err(s.span, "expected statement after outer attribute");
4856 // Do not attempt to parse an expression if we're done here.
4857 if self.token == token::Semi {
4858 unused_attrs(&attrs, self);
4863 if self.token == token::CloseDelim(token::Brace) {
4864 unused_attrs(&attrs, self);
4868 // Remainder are line-expr stmts.
4869 let e = self.parse_expr_res(
4870 Restrictions::STMT_EXPR, Some(attrs.into()))?;
4872 id: ast::DUMMY_NODE_ID,
4873 span: lo.to(e.span),
4874 node: StmtKind::Expr(e),
4881 /// Is this expression a successfully-parsed statement?
4882 fn expr_is_complete(&mut self, e: &Expr) -> bool {
4883 self.restrictions.contains(Restrictions::STMT_EXPR) &&
4884 !classify::expr_requires_semi_to_be_stmt(e)
4887 /// Parse a block. No inner attrs are allowed.
4888 pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
4889 maybe_whole!(self, NtBlock, |x| x);
4893 if !self.eat(&token::OpenDelim(token::Brace)) {
4895 let tok = self.this_token_descr();
4896 let mut e = self.span_fatal(sp, &format!("expected `{{`, found {}", tok));
4897 let do_not_suggest_help =
4898 self.token.is_keyword(keywords::In) || self.token == token::Colon;
4900 if self.token.is_ident_named("and") {
4901 e.span_suggestion_short_with_applicability(
4903 "use `&&` instead of `and` for the boolean operator",
4905 Applicability::MaybeIncorrect,
4908 if self.token.is_ident_named("or") {
4909 e.span_suggestion_short_with_applicability(
4911 "use `||` instead of `or` for the boolean operator",
4913 Applicability::MaybeIncorrect,
4917 // Check to see if the user has written something like
4922 // Which is valid in other languages, but not Rust.
4923 match self.parse_stmt_without_recovery(false) {
4925 if self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace))
4926 || do_not_suggest_help {
4927 // if the next token is an open brace (e.g., `if a b {`), the place-
4928 // inside-a-block suggestion would be more likely wrong than right
4929 e.span_label(sp, "expected `{`");
4932 let mut stmt_span = stmt.span;
4933 // expand the span to include the semicolon, if it exists
4934 if self.eat(&token::Semi) {
4935 stmt_span = stmt_span.with_hi(self.prev_span.hi());
4937 let sugg = pprust::to_string(|s| {
4938 use print::pprust::{PrintState, INDENT_UNIT};
4939 s.ibox(INDENT_UNIT)?;
4941 s.print_stmt(&stmt)?;
4942 s.bclose_maybe_open(stmt.span, INDENT_UNIT, false)
4944 e.span_suggestion_with_applicability(
4946 "try placing this code inside a block",
4948 // speculative, has been misleading in the past (closed Issue #46836)
4949 Applicability::MaybeIncorrect
4953 self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
4954 self.cancel(&mut e);
4958 e.span_label(sp, "expected `{`");
4962 self.parse_block_tail(lo, BlockCheckMode::Default)
4965 /// Parse a block. Inner attrs are allowed.
4966 fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
4967 maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
4970 self.expect(&token::OpenDelim(token::Brace))?;
4971 Ok((self.parse_inner_attributes()?,
4972 self.parse_block_tail(lo, BlockCheckMode::Default)?))
4975 /// Parse the rest of a block expression or function body
4976 /// Precondition: already parsed the '{'.
4977 fn parse_block_tail(&mut self, lo: Span, s: BlockCheckMode) -> PResult<'a, P<Block>> {
4978 let mut stmts = vec![];
4979 let mut recovered = false;
4981 while !self.eat(&token::CloseDelim(token::Brace)) {
4982 let stmt = match self.parse_full_stmt(false) {
4985 self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore);
4986 self.eat(&token::CloseDelim(token::Brace));
4992 if let Some(stmt) = stmt {
4994 } else if self.token == token::Eof {
4997 // Found only `;` or `}`.
5003 id: ast::DUMMY_NODE_ID,
5005 span: lo.to(self.prev_span),
5010 /// Parse a statement, including the trailing semicolon.
5011 crate fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
5012 // skip looking for a trailing semicolon when we have an interpolated statement
5013 maybe_whole!(self, NtStmt, |x| Some(x));
5015 let mut stmt = match self.parse_stmt_without_recovery(macro_legacy_warnings)? {
5017 None => return Ok(None),
5021 StmtKind::Expr(ref expr) if self.token != token::Eof => {
5022 // expression without semicolon
5023 if classify::expr_requires_semi_to_be_stmt(expr) {
5024 // Just check for errors and recover; do not eat semicolon yet.
5026 self.expect_one_of(&[], &[token::Semi, token::CloseDelim(token::Brace)])
5029 self.recover_stmt();
5033 StmtKind::Local(..) => {
5034 // We used to incorrectly allow a macro-expanded let statement to lack a semicolon.
5035 if macro_legacy_warnings && self.token != token::Semi {
5036 self.warn_missing_semicolon();
5038 self.expect_one_of(&[], &[token::Semi])?;
5044 if self.eat(&token::Semi) {
5045 stmt = stmt.add_trailing_semicolon();
5048 stmt.span = stmt.span.with_hi(self.prev_span.hi());
5052 fn warn_missing_semicolon(&self) {
5053 self.diagnostic().struct_span_warn(self.span, {
5054 &format!("expected `;`, found {}", self.this_token_descr())
5056 "This was erroneously allowed and will become a hard error in a future release"
5060 fn err_dotdotdot_syntax(&self, span: Span) {
5061 self.diagnostic().struct_span_err(span, {
5062 "unexpected token: `...`"
5063 }).span_suggestion_with_applicability(
5064 span, "use `..` for an exclusive range", "..".to_owned(),
5065 Applicability::MaybeIncorrect
5066 ).span_suggestion_with_applicability(
5067 span, "or `..=` for an inclusive range", "..=".to_owned(),
5068 Applicability::MaybeIncorrect
5072 // Parse bounds of a type parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
5073 // BOUND = TY_BOUND | LT_BOUND
5074 // LT_BOUND = LIFETIME (e.g., `'a`)
5075 // TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
5076 // TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`)
5077 fn parse_generic_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, GenericBounds> {
5078 let mut bounds = Vec::new();
5080 // This needs to be synchronized with `Token::can_begin_bound`.
5081 let is_bound_start = self.check_path() || self.check_lifetime() ||
5082 self.check(&token::Question) ||
5083 self.check_keyword(keywords::For) ||
5084 self.check(&token::OpenDelim(token::Paren));
5087 let has_parens = self.eat(&token::OpenDelim(token::Paren));
5088 let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None };
5089 if self.token.is_lifetime() {
5090 if let Some(question_span) = question {
5091 self.span_err(question_span,
5092 "`?` may only modify trait bounds, not lifetime bounds");
5094 bounds.push(GenericBound::Outlives(self.expect_lifetime()));
5096 self.expect(&token::CloseDelim(token::Paren))?;
5097 self.span_err(self.prev_span,
5098 "parenthesized lifetime bounds are not supported");
5101 let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
5102 let path = self.parse_path(PathStyle::Type)?;
5104 self.expect(&token::CloseDelim(token::Paren))?;
5106 let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span));
5107 let modifier = if question.is_some() {
5108 TraitBoundModifier::Maybe
5110 TraitBoundModifier::None
5112 bounds.push(GenericBound::Trait(poly_trait, modifier));
5118 if !allow_plus || !self.eat_plus() {
5126 fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> {
5127 self.parse_generic_bounds_common(true)
5130 // Parse bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
5131 // BOUND = LT_BOUND (e.g., `'a`)
5132 fn parse_lt_param_bounds(&mut self) -> GenericBounds {
5133 let mut lifetimes = Vec::new();
5134 while self.check_lifetime() {
5135 lifetimes.push(ast::GenericBound::Outlives(self.expect_lifetime()));
5137 if !self.eat_plus() {
5144 /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
5145 fn parse_ty_param(&mut self,
5146 preceding_attrs: Vec<Attribute>)
5147 -> PResult<'a, GenericParam> {
5148 let ident = self.parse_ident()?;
5150 // Parse optional colon and param bounds.
5151 let bounds = if self.eat(&token::Colon) {
5152 self.parse_generic_bounds()?
5157 let default = if self.eat(&token::Eq) {
5158 Some(self.parse_ty()?)
5165 id: ast::DUMMY_NODE_ID,
5166 attrs: preceding_attrs.into(),
5168 kind: GenericParamKind::Type {
5174 /// Parses the following grammar:
5175 /// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
5176 fn parse_trait_item_assoc_ty(&mut self)
5177 -> PResult<'a, (Ident, TraitItemKind, ast::Generics)> {
5178 let ident = self.parse_ident()?;
5179 let mut generics = self.parse_generics()?;
5181 // Parse optional colon and param bounds.
5182 let bounds = if self.eat(&token::Colon) {
5183 self.parse_generic_bounds()?
5187 generics.where_clause = self.parse_where_clause()?;
5189 let default = if self.eat(&token::Eq) {
5190 Some(self.parse_ty()?)
5194 self.expect(&token::Semi)?;
5196 Ok((ident, TraitItemKind::Type(bounds, default), generics))
5199 /// Parses (possibly empty) list of lifetime and type parameters, possibly including
5200 /// trailing comma and erroneous trailing attributes.
5201 crate fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
5202 let mut lifetimes = Vec::new();
5203 let mut params = Vec::new();
5204 let mut seen_ty_param: Option<Span> = None;
5205 let mut last_comma_span = None;
5206 let mut bad_lifetime_pos = vec![];
5207 let mut suggestions = vec![];
5209 let attrs = self.parse_outer_attributes()?;
5210 if self.check_lifetime() {
5211 let lifetime = self.expect_lifetime();
5212 // Parse lifetime parameter.
5213 let bounds = if self.eat(&token::Colon) {
5214 self.parse_lt_param_bounds()
5218 lifetimes.push(ast::GenericParam {
5219 ident: lifetime.ident,
5221 attrs: attrs.into(),
5223 kind: ast::GenericParamKind::Lifetime,
5225 if let Some(sp) = seen_ty_param {
5226 let param_span = self.prev_span;
5227 let ate_comma = self.eat(&token::Comma);
5228 let remove_sp = if ate_comma {
5229 param_span.until(self.span)
5231 last_comma_span.unwrap_or(param_span).to(param_span)
5233 bad_lifetime_pos.push(param_span);
5235 if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) {
5236 suggestions.push((remove_sp, String::new()));
5237 suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet)));
5240 last_comma_span = Some(self.prev_span);
5244 } else if self.check_ident() {
5245 // Parse type parameter.
5246 params.push(self.parse_ty_param(attrs)?);
5247 if seen_ty_param.is_none() {
5248 seen_ty_param = Some(self.prev_span);
5251 // Check for trailing attributes and stop parsing.
5252 if !attrs.is_empty() {
5253 let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" };
5254 self.span_err(attrs[0].span,
5255 &format!("trailing attribute after {} parameters", param_kind));
5260 if !self.eat(&token::Comma) {
5263 last_comma_span = Some(self.prev_span);
5265 if !bad_lifetime_pos.is_empty() {
5266 let mut err = self.struct_span_err(
5268 "lifetime parameters must be declared prior to type parameters",
5270 if !suggestions.is_empty() {
5271 err.multipart_suggestion_with_applicability(
5272 "move the lifetime parameter prior to the first type parameter",
5274 Applicability::MachineApplicable,
5279 lifetimes.extend(params); // ensure the correct order of lifetimes and type params
5283 /// Parse a set of optional generic type parameter declarations. Where
5284 /// clauses are not parsed here, and must be added later via
5285 /// `parse_where_clause()`.
5287 /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
5288 /// | ( < lifetimes , typaramseq ( , )? > )
5289 /// where typaramseq = ( typaram ) | ( typaram , typaramseq )
5290 fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
5291 maybe_whole!(self, NtGenerics, |x| x);
5293 let span_lo = self.span;
5295 let params = self.parse_generic_params()?;
5299 where_clause: WhereClause {
5300 id: ast::DUMMY_NODE_ID,
5301 predicates: Vec::new(),
5302 span: syntax_pos::DUMMY_SP,
5304 span: span_lo.to(self.prev_span),
5307 Ok(ast::Generics::default())
5311 /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
5312 /// possibly including trailing comma.
5313 fn parse_generic_args(&mut self)
5314 -> PResult<'a, (Vec<GenericArg>, Vec<TypeBinding>)> {
5315 let mut args = Vec::new();
5316 let mut bindings = Vec::new();
5317 let mut seen_type = false;
5318 let mut seen_binding = false;
5320 if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
5321 // Parse lifetime argument.
5322 args.push(GenericArg::Lifetime(self.expect_lifetime()));
5323 if seen_type || seen_binding {
5324 self.span_err(self.prev_span,
5325 "lifetime parameters must be declared prior to type parameters");
5327 } else if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) {
5328 // Parse associated type binding.
5330 let ident = self.parse_ident()?;
5332 let ty = self.parse_ty()?;
5333 bindings.push(TypeBinding {
5334 id: ast::DUMMY_NODE_ID,
5337 span: lo.to(self.prev_span),
5339 seen_binding = true;
5340 } else if self.check_type() {
5341 // Parse type argument.
5342 let ty_param = self.parse_ty()?;
5344 self.span_err(ty_param.span,
5345 "type parameters must be declared prior to associated type bindings");
5347 args.push(GenericArg::Type(ty_param));
5353 if !self.eat(&token::Comma) {
5357 Ok((args, bindings))
5360 /// Parses an optional `where` clause and places it in `generics`.
5362 /// ```ignore (only-for-syntax-highlight)
5363 /// where T : Trait<U, V> + 'b, 'a : 'b
5365 fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
5366 maybe_whole!(self, NtWhereClause, |x| x);
5368 let mut where_clause = WhereClause {
5369 id: ast::DUMMY_NODE_ID,
5370 predicates: Vec::new(),
5371 span: syntax_pos::DUMMY_SP,
5374 if !self.eat_keyword(keywords::Where) {
5375 return Ok(where_clause);
5377 let lo = self.prev_span;
5379 // We are considering adding generics to the `where` keyword as an alternative higher-rank
5380 // parameter syntax (as in `where<'a>` or `where<T>`. To avoid that being a breaking
5381 // change we parse those generics now, but report an error.
5382 if self.choose_generics_over_qpath() {
5383 let generics = self.parse_generics()?;
5384 self.span_err(generics.span,
5385 "generic parameters on `where` clauses are reserved for future use");
5390 if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
5391 let lifetime = self.expect_lifetime();
5392 // Bounds starting with a colon are mandatory, but possibly empty.
5393 self.expect(&token::Colon)?;
5394 let bounds = self.parse_lt_param_bounds();
5395 where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
5396 ast::WhereRegionPredicate {
5397 span: lo.to(self.prev_span),
5402 } else if self.check_type() {
5403 // Parse optional `for<'a, 'b>`.
5404 // This `for` is parsed greedily and applies to the whole predicate,
5405 // the bounded type can have its own `for` applying only to it.
5406 // Example 1: for<'a> Trait1<'a>: Trait2<'a /*ok*/>
5407 // Example 2: (for<'a> Trait1<'a>): Trait2<'a /*not ok*/>
5408 // Example 3: for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /*ok*/, 'b /*not ok*/>
5409 let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
5411 // Parse type with mandatory colon and (possibly empty) bounds,
5412 // or with mandatory equality sign and the second type.
5413 let ty = self.parse_ty()?;
5414 if self.eat(&token::Colon) {
5415 let bounds = self.parse_generic_bounds()?;
5416 where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
5417 ast::WhereBoundPredicate {
5418 span: lo.to(self.prev_span),
5419 bound_generic_params: lifetime_defs,
5424 // FIXME: Decide what should be used here, `=` or `==`.
5425 // FIXME: We are just dropping the binders in lifetime_defs on the floor here.
5426 } else if self.eat(&token::Eq) || self.eat(&token::EqEq) {
5427 let rhs_ty = self.parse_ty()?;
5428 where_clause.predicates.push(ast::WherePredicate::EqPredicate(
5429 ast::WhereEqPredicate {
5430 span: lo.to(self.prev_span),
5433 id: ast::DUMMY_NODE_ID,
5437 return self.unexpected();
5443 if !self.eat(&token::Comma) {
5448 where_clause.span = lo.to(self.prev_span);
5452 fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
5453 -> PResult<'a, (Vec<Arg> , bool)> {
5454 self.expect(&token::OpenDelim(token::Paren))?;
5457 let mut variadic = false;
5458 let args: Vec<Option<Arg>> =
5459 self.parse_seq_to_before_end(
5460 &token::CloseDelim(token::Paren),
5461 SeqSep::trailing_allowed(token::Comma),
5463 if p.token == token::DotDotDot {
5467 if p.token != token::CloseDelim(token::Paren) {
5470 "`...` must be last in argument list for variadic function");
5474 let span = p.prev_span;
5475 if p.token == token::CloseDelim(token::Paren) {
5476 // continue parsing to present any further errors
5479 "only foreign functions are allowed to be variadic"
5481 Ok(Some(dummy_arg(span)))
5483 // this function definition looks beyond recovery, stop parsing
5485 "only foreign functions are allowed to be variadic");
5490 match p.parse_arg_general(named_args, false) {
5491 Ok(arg) => Ok(Some(arg)),
5494 let lo = p.prev_span;
5495 // Skip every token until next possible arg or end.
5496 p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
5497 // Create a placeholder argument for proper arg count (#34264).
5498 let span = lo.to(p.prev_span);
5499 Ok(Some(dummy_arg(span)))
5506 self.eat(&token::CloseDelim(token::Paren));
5508 let args: Vec<_> = args.into_iter().filter_map(|x| x).collect();
5510 if variadic && args.is_empty() {
5512 "variadic function must be declared with at least one named argument");
5515 Ok((args, variadic))
5518 /// Parse the argument list and result type of a function declaration
5519 fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<'a, P<FnDecl>> {
5521 let (args, variadic) = self.parse_fn_args(true, allow_variadic)?;
5522 let ret_ty = self.parse_ret_ty(true)?;
5531 /// Returns the parsed optional self argument and whether a self shortcut was used.
5532 fn parse_self_arg(&mut self) -> PResult<'a, Option<Arg>> {
5533 let expect_ident = |this: &mut Self| match this.token {
5534 // Preserve hygienic context.
5535 token::Ident(ident, _) =>
5536 { let span = this.span; this.bump(); Ident::new(ident.name, span) }
5539 let isolated_self = |this: &mut Self, n| {
5540 this.look_ahead(n, |t| t.is_keyword(keywords::SelfLower)) &&
5541 this.look_ahead(n + 1, |t| t != &token::ModSep)
5544 // Parse optional self parameter of a method.
5545 // Only a limited set of initial token sequences is considered self parameters, anything
5546 // else is parsed as a normal function parameter list, so some lookahead is required.
5547 let eself_lo = self.span;
5548 let (eself, eself_ident, eself_hi) = match self.token {
5549 token::BinOp(token::And) => {
5555 (if isolated_self(self, 1) {
5557 SelfKind::Region(None, Mutability::Immutable)
5558 } else if self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) &&
5559 isolated_self(self, 2) {
5562 SelfKind::Region(None, Mutability::Mutable)
5563 } else if self.look_ahead(1, |t| t.is_lifetime()) &&
5564 isolated_self(self, 2) {
5566 let lt = self.expect_lifetime();
5567 SelfKind::Region(Some(lt), Mutability::Immutable)
5568 } else if self.look_ahead(1, |t| t.is_lifetime()) &&
5569 self.look_ahead(2, |t| t.is_keyword(keywords::Mut)) &&
5570 isolated_self(self, 3) {
5572 let lt = self.expect_lifetime();
5574 SelfKind::Region(Some(lt), Mutability::Mutable)
5577 }, expect_ident(self), self.prev_span)
5579 token::BinOp(token::Star) => {
5584 // Emit special error for `self` cases.
5585 (if isolated_self(self, 1) {
5587 self.span_err(self.span, "cannot pass `self` by raw pointer");
5588 SelfKind::Value(Mutability::Immutable)
5589 } else if self.look_ahead(1, |t| t.is_mutability()) &&
5590 isolated_self(self, 2) {
5593 self.span_err(self.span, "cannot pass `self` by raw pointer");
5594 SelfKind::Value(Mutability::Immutable)
5597 }, expect_ident(self), self.prev_span)
5599 token::Ident(..) => {
5600 if isolated_self(self, 0) {
5603 let eself_ident = expect_ident(self);
5604 let eself_hi = self.prev_span;
5605 (if self.eat(&token::Colon) {
5606 let ty = self.parse_ty()?;
5607 SelfKind::Explicit(ty, Mutability::Immutable)
5609 SelfKind::Value(Mutability::Immutable)
5610 }, eself_ident, eself_hi)
5611 } else if self.token.is_keyword(keywords::Mut) &&
5612 isolated_self(self, 1) {
5616 let eself_ident = expect_ident(self);
5617 let eself_hi = self.prev_span;
5618 (if self.eat(&token::Colon) {
5619 let ty = self.parse_ty()?;
5620 SelfKind::Explicit(ty, Mutability::Mutable)
5622 SelfKind::Value(Mutability::Mutable)
5623 }, eself_ident, eself_hi)
5628 _ => return Ok(None),
5631 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
5632 Ok(Some(Arg::from_self(eself, eself_ident)))
5635 /// Parse the parameter list and result type of a function that may have a `self` parameter.
5636 fn parse_fn_decl_with_self<F>(&mut self, parse_arg_fn: F) -> PResult<'a, P<FnDecl>>
5637 where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>,
5639 self.expect(&token::OpenDelim(token::Paren))?;
5641 // Parse optional self argument
5642 let self_arg = self.parse_self_arg()?;
5644 // Parse the rest of the function parameter list.
5645 let sep = SeqSep::trailing_allowed(token::Comma);
5646 let fn_inputs = if let Some(self_arg) = self_arg {
5647 if self.check(&token::CloseDelim(token::Paren)) {
5649 } else if self.eat(&token::Comma) {
5650 let mut fn_inputs = vec![self_arg];
5651 fn_inputs.append(&mut self.parse_seq_to_before_end(
5652 &token::CloseDelim(token::Paren), sep, parse_arg_fn)?
5656 return self.unexpected();
5659 self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)?
5662 // Parse closing paren and return type.
5663 self.expect(&token::CloseDelim(token::Paren))?;
5666 output: self.parse_ret_ty(true)?,
5671 // parse the |arg, arg| header on a lambda
5672 fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> {
5673 let inputs_captures = {
5674 if self.eat(&token::OrOr) {
5677 self.expect(&token::BinOp(token::Or))?;
5678 let args = self.parse_seq_to_before_tokens(
5679 &[&token::BinOp(token::Or), &token::OrOr],
5680 SeqSep::trailing_allowed(token::Comma),
5681 TokenExpectType::NoExpect,
5682 |p| p.parse_fn_block_arg()
5688 let output = self.parse_ret_ty(true)?;
5691 inputs: inputs_captures,
5697 /// Parse the name and optional generic types of a function header.
5698 fn parse_fn_header(&mut self) -> PResult<'a, (Ident, ast::Generics)> {
5699 let id = self.parse_ident()?;
5700 let generics = self.parse_generics()?;
5704 fn mk_item(&mut self, span: Span, ident: Ident, node: ItemKind, vis: Visibility,
5705 attrs: Vec<Attribute>) -> P<Item> {
5709 id: ast::DUMMY_NODE_ID,
5717 /// Parse an item-position function declaration.
5718 fn parse_item_fn(&mut self,
5721 constness: Spanned<Constness>,
5723 -> PResult<'a, ItemInfo> {
5724 let (ident, mut generics) = self.parse_fn_header()?;
5725 let decl = self.parse_fn_decl(false)?;
5726 generics.where_clause = self.parse_where_clause()?;
5727 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
5728 let header = FnHeader { unsafety, asyncness, constness, abi };
5729 Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
5732 /// true if we are looking at `const ID`, false for things like `const fn` etc
5733 fn is_const_item(&mut self) -> bool {
5734 self.token.is_keyword(keywords::Const) &&
5735 !self.look_ahead(1, |t| t.is_keyword(keywords::Fn)) &&
5736 !self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe))
5739 /// parses all the "front matter" for a `fn` declaration, up to
5740 /// and including the `fn` keyword:
5744 /// - `const unsafe fn`
5747 fn parse_fn_front_matter(&mut self)
5755 let is_const_fn = self.eat_keyword(keywords::Const);
5756 let const_span = self.prev_span;
5757 let unsafety = self.parse_unsafety();
5758 let asyncness = self.parse_asyncness();
5759 let (constness, unsafety, abi) = if is_const_fn {
5760 (respan(const_span, Constness::Const), unsafety, Abi::Rust)
5762 let abi = if self.eat_keyword(keywords::Extern) {
5763 self.parse_opt_abi()?.unwrap_or(Abi::C)
5767 (respan(self.prev_span, Constness::NotConst), unsafety, abi)
5769 self.expect_keyword(keywords::Fn)?;
5770 Ok((constness, unsafety, asyncness, abi))
5773 /// Parse an impl item.
5774 pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
5775 maybe_whole!(self, NtImplItem, |x| x);
5776 let attrs = self.parse_outer_attributes()?;
5777 let (mut item, tokens) = self.collect_tokens(|this| {
5778 this.parse_impl_item_(at_end, attrs)
5781 // See `parse_item` for why this clause is here.
5782 if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
5783 item.tokens = Some(tokens);
5788 fn parse_impl_item_(&mut self,
5790 mut attrs: Vec<Attribute>) -> PResult<'a, ImplItem> {
5792 let vis = self.parse_visibility(false)?;
5793 let defaultness = self.parse_defaultness();
5794 let (name, node, generics) = if let Some(type_) = self.eat_type() {
5795 let (name, alias, generics) = type_?;
5796 let kind = match alias {
5797 AliasKind::Weak(typ) => ast::ImplItemKind::Type(typ),
5798 AliasKind::Existential(bounds) => ast::ImplItemKind::Existential(bounds),
5800 (name, kind, generics)
5801 } else if self.is_const_item() {
5802 // This parses the grammar:
5803 // ImplItemConst = "const" Ident ":" Ty "=" Expr ";"
5804 self.expect_keyword(keywords::Const)?;
5805 let name = self.parse_ident()?;
5806 self.expect(&token::Colon)?;
5807 let typ = self.parse_ty()?;
5808 self.expect(&token::Eq)?;
5809 let expr = self.parse_expr()?;
5810 self.expect(&token::Semi)?;
5811 (name, ast::ImplItemKind::Const(typ, expr), ast::Generics::default())
5813 let (name, inner_attrs, generics, node) = self.parse_impl_method(&vis, at_end)?;
5814 attrs.extend(inner_attrs);
5815 (name, node, generics)
5819 id: ast::DUMMY_NODE_ID,
5820 span: lo.to(self.prev_span),
5831 fn complain_if_pub_macro(&mut self, vis: &VisibilityKind, sp: Span) {
5833 VisibilityKind::Inherited => {}
5835 let is_macro_rules: bool = match self.token {
5836 token::Ident(sid, _) => sid.name == Symbol::intern("macro_rules"),
5839 let mut err = if is_macro_rules {
5840 let mut err = self.diagnostic()
5841 .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
5842 err.span_suggestion_with_applicability(
5844 "try exporting the macro",
5845 "#[macro_export]".to_owned(),
5846 Applicability::MaybeIncorrect // speculative
5850 let mut err = self.diagnostic()
5851 .struct_span_err(sp, "can't qualify macro invocation with `pub`");
5852 err.help("try adjusting the macro to put `pub` inside the invocation");
5860 fn missing_assoc_item_kind_err(&mut self, item_type: &str, prev_span: Span)
5861 -> DiagnosticBuilder<'a>
5863 let expected_kinds = if item_type == "extern" {
5864 "missing `fn`, `type`, or `static`"
5866 "missing `fn`, `type`, or `const`"
5869 // Given this code `path(`, it seems like this is not
5870 // setting the visibility of a macro invocation, but rather
5871 // a mistyped method declaration.
5872 // Create a diagnostic pointing out that `fn` is missing.
5874 // x | pub path(&self) {
5875 // | ^ missing `fn`, `type`, or `const`
5877 // ^^ `sp` below will point to this
5878 let sp = prev_span.between(self.prev_span);
5879 let mut err = self.diagnostic().struct_span_err(
5881 &format!("{} for {}-item declaration",
5882 expected_kinds, item_type));
5883 err.span_label(sp, expected_kinds);
5887 /// Parse a method or a macro invocation in a trait impl.
5888 fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
5889 -> PResult<'a, (Ident, Vec<Attribute>, ast::Generics,
5890 ast::ImplItemKind)> {
5891 // code copied from parse_macro_use_or_failure... abstraction!
5892 if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? {
5894 Ok((keywords::Invalid.ident(), vec![], ast::Generics::default(),
5895 ast::ImplItemKind::Macro(mac)))
5897 let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
5898 let ident = self.parse_ident()?;
5899 let mut generics = self.parse_generics()?;
5900 let decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?;
5901 generics.where_clause = self.parse_where_clause()?;
5903 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
5904 let header = ast::FnHeader { abi, unsafety, constness, asyncness };
5905 Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(
5906 ast::MethodSig { header, decl },
5912 /// Parse `trait Foo { ... }` or `trait Foo = Bar;`
5913 fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
5914 let ident = self.parse_ident()?;
5915 let mut tps = self.parse_generics()?;
5917 // Parse optional colon and supertrait bounds.
5918 let bounds = if self.eat(&token::Colon) {
5919 self.parse_generic_bounds()?
5924 if self.eat(&token::Eq) {
5925 // it's a trait alias
5926 let bounds = self.parse_generic_bounds()?;
5927 tps.where_clause = self.parse_where_clause()?;
5928 self.expect(&token::Semi)?;
5929 if unsafety != Unsafety::Normal {
5930 self.span_err(self.prev_span, "trait aliases cannot be unsafe");
5932 Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
5934 // it's a normal trait
5935 tps.where_clause = self.parse_where_clause()?;
5936 self.expect(&token::OpenDelim(token::Brace))?;
5937 let mut trait_items = vec![];
5938 while !self.eat(&token::CloseDelim(token::Brace)) {
5939 let mut at_end = false;
5940 match self.parse_trait_item(&mut at_end) {
5941 Ok(item) => trait_items.push(item),
5945 self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
5950 Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None))
5954 fn choose_generics_over_qpath(&self) -> bool {
5955 // There's an ambiguity between generic parameters and qualified paths in impls.
5956 // If we see `<` it may start both, so we have to inspect some following tokens.
5957 // The following combinations can only start generics,
5958 // but not qualified paths (with one exception):
5959 // `<` `>` - empty generic parameters
5960 // `<` `#` - generic parameters with attributes
5961 // `<` (LIFETIME|IDENT) `>` - single generic parameter
5962 // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
5963 // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
5964 // `<` (LIFETIME|IDENT) `=` - generic parameter with a default
5965 // The only truly ambiguous case is
5966 // `<` IDENT `>` `::` IDENT ...
5967 // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
5968 // because this is what almost always expected in practice, qualified paths in impls
5969 // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
5970 self.token == token::Lt &&
5971 (self.look_ahead(1, |t| t == &token::Pound || t == &token::Gt) ||
5972 self.look_ahead(1, |t| t.is_lifetime() || t.is_ident()) &&
5973 self.look_ahead(2, |t| t == &token::Gt || t == &token::Comma ||
5974 t == &token::Colon || t == &token::Eq))
5977 fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
5978 self.expect(&token::OpenDelim(token::Brace))?;
5979 let attrs = self.parse_inner_attributes()?;
5981 let mut impl_items = Vec::new();
5982 while !self.eat(&token::CloseDelim(token::Brace)) {
5983 let mut at_end = false;
5984 match self.parse_impl_item(&mut at_end) {
5985 Ok(impl_item) => impl_items.push(impl_item),
5989 self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
5994 Ok((impl_items, attrs))
5997 /// Parses an implementation item, `impl` keyword is already parsed.
5998 /// impl<'a, T> TYPE { /* impl items */ }
5999 /// impl<'a, T> TRAIT for TYPE { /* impl items */ }
6000 /// impl<'a, T> !TRAIT for TYPE { /* impl items */ }
6001 /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
6002 /// `impl` GENERICS `!`? TYPE `for`? (TYPE | `..`) (`where` PREDICATES)? `{` BODY `}`
6003 /// `impl` GENERICS `!`? TYPE (`where` PREDICATES)? `{` BODY `}`
6004 fn parse_item_impl(&mut self, unsafety: Unsafety, defaultness: Defaultness)
6005 -> PResult<'a, ItemInfo> {
6006 // First, parse generic parameters if necessary.
6007 let mut generics = if self.choose_generics_over_qpath() {
6008 self.parse_generics()?
6010 ast::Generics::default()
6013 // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
6014 let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) {
6016 ast::ImplPolarity::Negative
6018 ast::ImplPolarity::Positive
6021 // Parse both types and traits as a type, then reinterpret if necessary.
6022 let ty_first = self.parse_ty()?;
6024 // If `for` is missing we try to recover.
6025 let has_for = self.eat_keyword(keywords::For);
6026 let missing_for_span = self.prev_span.between(self.span);
6028 let ty_second = if self.token == token::DotDot {
6029 // We need to report this error after `cfg` expansion for compatibility reasons
6030 self.bump(); // `..`, do not add it to expected tokens
6031 Some(P(Ty { node: TyKind::Err, span: self.prev_span, id: ast::DUMMY_NODE_ID }))
6032 } else if has_for || self.token.can_begin_type() {
6033 Some(self.parse_ty()?)
6038 generics.where_clause = self.parse_where_clause()?;
6040 let (impl_items, attrs) = self.parse_impl_body()?;
6042 let item_kind = match ty_second {
6043 Some(ty_second) => {
6044 // impl Trait for Type
6046 self.span_err(missing_for_span, "missing `for` in a trait impl");
6049 let ty_first = ty_first.into_inner();
6050 let path = match ty_first.node {
6051 // This notably includes paths passed through `ty` macro fragments (#46438).
6052 TyKind::Path(None, path) => path,
6054 self.span_err(ty_first.span, "expected a trait, found type");
6055 ast::Path::from_ident(Ident::new(keywords::Invalid.name(), ty_first.span))
6058 let trait_ref = TraitRef { path, ref_id: ty_first.id };
6060 ItemKind::Impl(unsafety, polarity, defaultness,
6061 generics, Some(trait_ref), ty_second, impl_items)
6065 ItemKind::Impl(unsafety, polarity, defaultness,
6066 generics, None, ty_first, impl_items)
6070 Ok((keywords::Invalid.ident(), item_kind, Some(attrs)))
6073 fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
6074 if self.eat_keyword(keywords::For) {
6076 let params = self.parse_generic_params()?;
6078 // We rely on AST validation to rule out invalid cases: There must not be type
6079 // parameters, and the lifetime parameters must not have bounds.
6086 /// Parse struct Foo { ... }
6087 fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
6088 let class_name = self.parse_ident()?;
6090 let mut generics = self.parse_generics()?;
6092 // There is a special case worth noting here, as reported in issue #17904.
6093 // If we are parsing a tuple struct it is the case that the where clause
6094 // should follow the field list. Like so:
6096 // struct Foo<T>(T) where T: Copy;
6098 // If we are parsing a normal record-style struct it is the case
6099 // that the where clause comes before the body, and after the generics.
6100 // So if we look ahead and see a brace or a where-clause we begin
6101 // parsing a record style struct.
6103 // Otherwise if we look ahead and see a paren we parse a tuple-style
6106 let vdata = if self.token.is_keyword(keywords::Where) {
6107 generics.where_clause = self.parse_where_clause()?;
6108 if self.eat(&token::Semi) {
6109 // If we see a: `struct Foo<T> where T: Copy;` style decl.
6110 VariantData::Unit(ast::DUMMY_NODE_ID)
6112 // If we see: `struct Foo<T> where T: Copy { ... }`
6113 VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
6115 // No `where` so: `struct Foo<T>;`
6116 } else if self.eat(&token::Semi) {
6117 VariantData::Unit(ast::DUMMY_NODE_ID)
6118 // Record-style struct definition
6119 } else if self.token == token::OpenDelim(token::Brace) {
6120 VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
6121 // Tuple-style struct definition with optional where-clause.
6122 } else if self.token == token::OpenDelim(token::Paren) {
6123 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, ast::DUMMY_NODE_ID);
6124 generics.where_clause = self.parse_where_clause()?;
6125 self.expect(&token::Semi)?;
6128 let token_str = self.this_token_descr();
6129 let mut err = self.fatal(&format!(
6130 "expected `where`, `{{`, `(`, or `;` after struct name, found {}",
6133 err.span_label(self.span, "expected `where`, `{`, `(`, or `;` after struct name");
6137 Ok((class_name, ItemKind::Struct(vdata, generics), None))
6140 /// Parse union Foo { ... }
6141 fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
6142 let class_name = self.parse_ident()?;
6144 let mut generics = self.parse_generics()?;
6146 let vdata = if self.token.is_keyword(keywords::Where) {
6147 generics.where_clause = self.parse_where_clause()?;
6148 VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
6149 } else if self.token == token::OpenDelim(token::Brace) {
6150 VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
6152 let token_str = self.this_token_descr();
6153 let mut err = self.fatal(&format!(
6154 "expected `where` or `{{` after union name, found {}", token_str));
6155 err.span_label(self.span, "expected `where` or `{` after union name");
6159 Ok((class_name, ItemKind::Union(vdata, generics), None))
6162 fn consume_block(&mut self, delim: token::DelimToken) {
6163 let mut brace_depth = 0;
6165 if self.eat(&token::OpenDelim(delim)) {
6167 } else if self.eat(&token::CloseDelim(delim)) {
6168 if brace_depth == 0 {
6174 } else if self.token == token::Eof || self.eat(&token::CloseDelim(token::NoDelim)) {
6182 fn parse_record_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
6183 let mut fields = Vec::new();
6184 if self.eat(&token::OpenDelim(token::Brace)) {
6185 while self.token != token::CloseDelim(token::Brace) {
6186 let field = self.parse_struct_decl_field().map_err(|e| {
6187 self.recover_stmt();
6191 Ok(field) => fields.push(field),
6197 self.eat(&token::CloseDelim(token::Brace));
6199 let token_str = self.this_token_descr();
6200 let mut err = self.fatal(&format!(
6201 "expected `where`, or `{{` after struct name, found {}", token_str));
6202 err.span_label(self.span, "expected `where`, or `{` after struct name");
6209 fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
6210 // This is the case where we find `struct Foo<T>(T) where T: Copy;`
6211 // Unit like structs are handled in parse_item_struct function
6212 let fields = self.parse_unspanned_seq(
6213 &token::OpenDelim(token::Paren),
6214 &token::CloseDelim(token::Paren),
6215 SeqSep::trailing_allowed(token::Comma),
6217 let attrs = p.parse_outer_attributes()?;
6219 let vis = p.parse_visibility(true)?;
6220 let ty = p.parse_ty()?;
6222 span: lo.to(ty.span),
6225 id: ast::DUMMY_NODE_ID,
6234 /// Parse a structure field declaration
6235 fn parse_single_struct_field(&mut self,
6238 attrs: Vec<Attribute> )
6239 -> PResult<'a, StructField> {
6240 let mut seen_comma: bool = false;
6241 let a_var = self.parse_name_and_ty(lo, vis, attrs)?;
6242 if self.token == token::Comma {
6249 token::CloseDelim(token::Brace) => {}
6250 token::DocComment(_) => {
6251 let previous_span = self.prev_span;
6252 let mut err = self.span_fatal_err(self.span, Error::UselessDocComment);
6253 self.bump(); // consume the doc comment
6254 let comma_after_doc_seen = self.eat(&token::Comma);
6255 // `seen_comma` is always false, because we are inside doc block
6256 // condition is here to make code more readable
6257 if seen_comma == false && comma_after_doc_seen == true {
6260 if comma_after_doc_seen || self.token == token::CloseDelim(token::Brace) {
6263 if seen_comma == false {
6264 let sp = self.sess.source_map().next_point(previous_span);
6265 err.span_suggestion_with_applicability(
6267 "missing comma here",
6269 Applicability::MachineApplicable
6276 let sp = self.sess.source_map().next_point(self.prev_span);
6277 let mut err = self.struct_span_err(sp, &format!("expected `,`, or `}}`, found {}",
6278 self.this_token_descr()));
6279 if self.token.is_ident() {
6280 // This is likely another field; emit the diagnostic and keep going
6281 err.span_suggestion_with_applicability(
6283 "try adding a comma",
6285 Applicability::MachineApplicable,
6296 /// Parse an element of a struct definition
6297 fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
6298 let attrs = self.parse_outer_attributes()?;
6300 let vis = self.parse_visibility(false)?;
6301 self.parse_single_struct_field(lo, vis, attrs)
6304 /// Parse `pub`, `pub(crate)` and `pub(in path)` plus shortcuts `crate` for `pub(crate)`,
6305 /// `pub(self)` for `pub(in self)` and `pub(super)` for `pub(in super)`.
6306 /// If the following element can't be a tuple (i.e., it's a function definition,
6307 /// it's not a tuple struct field) and the contents within the parens
6308 /// isn't valid, emit a proper diagnostic.
6309 pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibility> {
6310 maybe_whole!(self, NtVis, |x| x);
6312 self.expected_tokens.push(TokenType::Keyword(keywords::Crate));
6313 if self.is_crate_vis() {
6314 self.bump(); // `crate`
6315 return Ok(respan(self.prev_span, VisibilityKind::Crate(CrateSugar::JustCrate)));
6318 if !self.eat_keyword(keywords::Pub) {
6319 // We need a span for our `Spanned<VisibilityKind>`, but there's inherently no
6320 // keyword to grab a span from for inherited visibility; an empty span at the
6321 // beginning of the current token would seem to be the "Schelling span".
6322 return Ok(respan(self.span.shrink_to_lo(), VisibilityKind::Inherited))
6324 let lo = self.prev_span;
6326 if self.check(&token::OpenDelim(token::Paren)) {
6327 // We don't `self.bump()` the `(` yet because this might be a struct definition where
6328 // `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`.
6329 // Because of this, we only `bump` the `(` if we're assured it is appropriate to do so
6330 // by the following tokens.
6331 if self.look_ahead(1, |t| t.is_keyword(keywords::Crate)) {
6334 self.bump(); // `crate`
6335 self.expect(&token::CloseDelim(token::Paren))?; // `)`
6337 lo.to(self.prev_span),
6338 VisibilityKind::Crate(CrateSugar::PubCrate),
6341 } else if self.look_ahead(1, |t| t.is_keyword(keywords::In)) {
6344 self.bump(); // `in`
6345 let path = self.parse_path(PathStyle::Mod)?; // `path`
6346 self.expect(&token::CloseDelim(token::Paren))?; // `)`
6347 let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
6349 id: ast::DUMMY_NODE_ID,
6352 } else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) &&
6353 self.look_ahead(1, |t| t.is_keyword(keywords::Super) ||
6354 t.is_keyword(keywords::SelfLower))
6356 // `pub(self)` or `pub(super)`
6358 let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
6359 self.expect(&token::CloseDelim(token::Paren))?; // `)`
6360 let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
6362 id: ast::DUMMY_NODE_ID,
6365 } else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct
6366 // `pub(something) fn ...` or `struct X { pub(something) y: Z }`
6368 let msg = "incorrect visibility restriction";
6369 let suggestion = r##"some possible visibility restrictions are:
6370 `pub(crate)`: visible only on the current crate
6371 `pub(super)`: visible only in the current module's parent
6372 `pub(in path::to::module)`: visible only on the specified path"##;
6373 let path = self.parse_path(PathStyle::Mod)?;
6374 let sp = self.prev_span;
6375 let help_msg = format!("make this visible only to module `{}` with `in`", path);
6376 self.expect(&token::CloseDelim(token::Paren))?; // `)`
6377 let mut err = struct_span_err!(self.sess.span_diagnostic, sp, E0704, "{}", msg);
6378 err.help(suggestion);
6379 err.span_suggestion_with_applicability(
6380 sp, &help_msg, format!("in {}", path), Applicability::MachineApplicable
6382 err.emit(); // emit diagnostic, but continue with public visibility
6386 Ok(respan(lo, VisibilityKind::Public))
6389 /// Parse defaultness: `default` or nothing.
6390 fn parse_defaultness(&mut self) -> Defaultness {
6391 // `pub` is included for better error messages
6392 if self.check_keyword(keywords::Default) &&
6393 self.look_ahead(1, |t| t.is_keyword(keywords::Impl) ||
6394 t.is_keyword(keywords::Const) ||
6395 t.is_keyword(keywords::Fn) ||
6396 t.is_keyword(keywords::Unsafe) ||
6397 t.is_keyword(keywords::Extern) ||
6398 t.is_keyword(keywords::Type) ||
6399 t.is_keyword(keywords::Pub)) {
6400 self.bump(); // `default`
6401 Defaultness::Default
6407 /// Given a termination token, parse all of the items in a module
6408 fn parse_mod_items(&mut self, term: &token::Token, inner_lo: Span) -> PResult<'a, Mod> {
6409 let mut items = vec![];
6410 while let Some(item) = self.parse_item()? {
6414 if !self.eat(term) {
6415 let token_str = self.this_token_descr();
6416 let mut err = self.fatal(&format!("expected item, found {}", token_str));
6417 if self.token == token::Semi {
6418 let msg = "consider removing this semicolon";
6419 err.span_suggestion_short_with_applicability(
6420 self.span, msg, String::new(), Applicability::MachineApplicable
6422 if !items.is_empty() { // Issue #51603
6423 let previous_item = &items[items.len()-1];
6424 let previous_item_kind_name = match previous_item.node {
6425 // say "braced struct" because tuple-structs and
6426 // braceless-empty-struct declarations do take a semicolon
6427 ItemKind::Struct(..) => Some("braced struct"),
6428 ItemKind::Enum(..) => Some("enum"),
6429 ItemKind::Trait(..) => Some("trait"),
6430 ItemKind::Union(..) => Some("union"),
6433 if let Some(name) = previous_item_kind_name {
6434 err.help(&format!("{} declarations are not followed by a semicolon",
6439 err.span_label(self.span, "expected item");
6444 let hi = if self.span.is_dummy() {
6451 inner: inner_lo.to(hi),
6457 fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
6458 let id = if m.is_none() { self.parse_ident_or_underscore() } else { self.parse_ident() }?;
6459 self.expect(&token::Colon)?;
6460 let ty = self.parse_ty()?;
6461 self.expect(&token::Eq)?;
6462 let e = self.parse_expr()?;
6463 self.expect(&token::Semi)?;
6464 let item = match m {
6465 Some(m) => ItemKind::Static(ty, m, e),
6466 None => ItemKind::Const(ty, e),
6468 Ok((id, item, None))
6471 /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
6472 fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> {
6473 let (in_cfg, outer_attrs) = {
6474 let mut strip_unconfigured = ::config::StripUnconfigured {
6476 features: None, // don't perform gated feature checking
6478 let outer_attrs = strip_unconfigured.process_cfg_attrs(outer_attrs.to_owned());
6479 (!self.cfg_mods || strip_unconfigured.in_cfg(&outer_attrs), outer_attrs)
6482 let id_span = self.span;
6483 let id = self.parse_ident()?;
6484 if self.eat(&token::Semi) {
6485 if in_cfg && self.recurse_into_file_modules {
6486 // This mod is in an external file. Let's go get it!
6487 let ModulePathSuccess { path, directory_ownership, warn } =
6488 self.submod_path(id, &outer_attrs, id_span)?;
6489 let (module, mut attrs) =
6490 self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?;
6491 // Record that we fetched the mod from an external file
6493 let attr = Attribute {
6494 id: attr::mk_attr_id(),
6495 style: ast::AttrStyle::Outer,
6496 path: ast::Path::from_ident(Ident::from_str("warn_directory_ownership")),
6497 tokens: TokenStream::empty(),
6498 is_sugared_doc: false,
6499 span: syntax_pos::DUMMY_SP,
6501 attr::mark_known(&attr);
6504 Ok((id, ItemKind::Mod(module), Some(attrs)))
6506 let placeholder = ast::Mod {
6507 inner: syntax_pos::DUMMY_SP,
6511 Ok((id, ItemKind::Mod(placeholder), None))
6514 let old_directory = self.directory.clone();
6515 self.push_directory(id, &outer_attrs);
6517 self.expect(&token::OpenDelim(token::Brace))?;
6518 let mod_inner_lo = self.span;
6519 let attrs = self.parse_inner_attributes()?;
6520 let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
6522 self.directory = old_directory;
6523 Ok((id, ItemKind::Mod(module), Some(attrs)))
6527 fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
6528 if let Some(path) = attr::first_attr_value_str_by_name(attrs, "path") {
6529 self.directory.path.to_mut().push(&path.as_str());
6530 self.directory.ownership = DirectoryOwnership::Owned { relative: None };
6532 // We have to push on the current module name in the case of relative
6533 // paths in order to ensure that any additional module paths from inline
6534 // `mod x { ... }` come after the relative extension.
6536 // For example, a `mod z { ... }` inside `x/y.rs` should set the current
6537 // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
6538 if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership {
6539 if let Some(ident) = relative.take() { // remove the relative offset
6540 self.directory.path.to_mut().push(ident.as_str());
6543 self.directory.path.to_mut().push(&id.as_str());
6547 pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
6548 if let Some(s) = attr::first_attr_value_str_by_name(attrs, "path") {
6551 // On windows, the base path might have the form
6552 // `\\?\foo\bar` in which case it does not tolerate
6553 // mixed `/` and `\` separators, so canonicalize
6556 let s = s.replace("/", "\\");
6557 Some(dir_path.join(s))
6563 /// Returns either a path to a module, or .
6564 pub fn default_submod_path(
6566 relative: Option<ast::Ident>,
6568 source_map: &SourceMap) -> ModulePath
6570 // If we're in a foo.rs file instead of a mod.rs file,
6571 // we need to look for submodules in
6572 // `./foo/<id>.rs` and `./foo/<id>/mod.rs` rather than
6573 // `./<id>.rs` and `./<id>/mod.rs`.
6574 let relative_prefix_string;
6575 let relative_prefix = if let Some(ident) = relative {
6576 relative_prefix_string = format!("{}{}", ident.as_str(), path::MAIN_SEPARATOR);
6577 &relative_prefix_string
6582 let mod_name = id.to_string();
6583 let default_path_str = format!("{}{}.rs", relative_prefix, mod_name);
6584 let secondary_path_str = format!("{}{}{}mod.rs",
6585 relative_prefix, mod_name, path::MAIN_SEPARATOR);
6586 let default_path = dir_path.join(&default_path_str);
6587 let secondary_path = dir_path.join(&secondary_path_str);
6588 let default_exists = source_map.file_exists(&default_path);
6589 let secondary_exists = source_map.file_exists(&secondary_path);
6591 let result = match (default_exists, secondary_exists) {
6592 (true, false) => Ok(ModulePathSuccess {
6594 directory_ownership: DirectoryOwnership::Owned {
6599 (false, true) => Ok(ModulePathSuccess {
6600 path: secondary_path,
6601 directory_ownership: DirectoryOwnership::Owned {
6606 (false, false) => Err(Error::FileNotFoundForModule {
6607 mod_name: mod_name.clone(),
6608 default_path: default_path_str,
6609 secondary_path: secondary_path_str,
6610 dir_path: dir_path.display().to_string(),
6612 (true, true) => Err(Error::DuplicatePaths {
6613 mod_name: mod_name.clone(),
6614 default_path: default_path_str,
6615 secondary_path: secondary_path_str,
6621 path_exists: default_exists || secondary_exists,
6626 fn submod_path(&mut self,
6628 outer_attrs: &[Attribute],
6630 -> PResult<'a, ModulePathSuccess> {
6631 if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
6632 return Ok(ModulePathSuccess {
6633 directory_ownership: match path.file_name().and_then(|s| s.to_str()) {
6634 // All `#[path]` files are treated as though they are a `mod.rs` file.
6635 // This means that `mod foo;` declarations inside `#[path]`-included
6636 // files are siblings,
6638 // Note that this will produce weirdness when a file named `foo.rs` is
6639 // `#[path]` included and contains a `mod foo;` declaration.
6640 // If you encounter this, it's your own darn fault :P
6641 Some(_) => DirectoryOwnership::Owned { relative: None },
6642 _ => DirectoryOwnership::UnownedViaMod(true),
6649 let relative = match self.directory.ownership {
6650 DirectoryOwnership::Owned { relative } => relative,
6651 DirectoryOwnership::UnownedViaBlock |
6652 DirectoryOwnership::UnownedViaMod(_) => None,
6654 let paths = Parser::default_submod_path(
6655 id, relative, &self.directory.path, self.sess.source_map());
6657 match self.directory.ownership {
6658 DirectoryOwnership::Owned { .. } => {
6659 paths.result.map_err(|err| self.span_fatal_err(id_sp, err))
6661 DirectoryOwnership::UnownedViaBlock => {
6663 "Cannot declare a non-inline module inside a block \
6664 unless it has a path attribute";
6665 let mut err = self.diagnostic().struct_span_err(id_sp, msg);
6666 if paths.path_exists {
6667 let msg = format!("Maybe `use` the module `{}` instead of redeclaring it",
6669 err.span_note(id_sp, &msg);
6673 DirectoryOwnership::UnownedViaMod(warn) => {
6675 if let Ok(result) = paths.result {
6676 return Ok(ModulePathSuccess { warn: true, ..result });
6679 let mut err = self.diagnostic().struct_span_err(id_sp,
6680 "cannot declare a new module at this location");
6681 if !id_sp.is_dummy() {
6682 let src_path = self.sess.source_map().span_to_filename(id_sp);
6683 if let FileName::Real(src_path) = src_path {
6684 if let Some(stem) = src_path.file_stem() {
6685 let mut dest_path = src_path.clone();
6686 dest_path.set_file_name(stem);
6687 dest_path.push("mod.rs");
6688 err.span_note(id_sp,
6689 &format!("maybe move this module `{}` to its own \
6690 directory via `{}`", src_path.display(),
6691 dest_path.display()));
6695 if paths.path_exists {
6696 err.span_note(id_sp,
6697 &format!("... or maybe `use` the module `{}` instead \
6698 of possibly redeclaring it",
6706 /// Read a module from a source file.
6707 fn eval_src_mod(&mut self,
6709 directory_ownership: DirectoryOwnership,
6712 -> PResult<'a, (ast::Mod, Vec<Attribute> )> {
6713 let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
6714 if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
6715 let mut err = String::from("circular modules: ");
6716 let len = included_mod_stack.len();
6717 for p in &included_mod_stack[i.. len] {
6718 err.push_str(&p.to_string_lossy());
6719 err.push_str(" -> ");
6721 err.push_str(&path.to_string_lossy());
6722 return Err(self.span_fatal(id_sp, &err[..]));
6724 included_mod_stack.push(path.clone());
6725 drop(included_mod_stack);
6728 new_sub_parser_from_file(self.sess, &path, directory_ownership, Some(name), id_sp);
6729 p0.cfg_mods = self.cfg_mods;
6730 let mod_inner_lo = p0.span;
6731 let mod_attrs = p0.parse_inner_attributes()?;
6732 let mut m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?;
6734 self.sess.included_mod_stack.borrow_mut().pop();
6738 /// Parse a function declaration from a foreign module
6739 fn parse_item_foreign_fn(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
6740 -> PResult<'a, ForeignItem> {
6741 self.expect_keyword(keywords::Fn)?;
6743 let (ident, mut generics) = self.parse_fn_header()?;
6744 let decl = self.parse_fn_decl(true)?;
6745 generics.where_clause = self.parse_where_clause()?;
6747 self.expect(&token::Semi)?;
6748 Ok(ast::ForeignItem {
6751 node: ForeignItemKind::Fn(decl, generics),
6752 id: ast::DUMMY_NODE_ID,
6758 /// Parse a static item from a foreign module.
6759 /// Assumes that the `static` keyword is already parsed.
6760 fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
6761 -> PResult<'a, ForeignItem> {
6762 let mutbl = self.eat_keyword(keywords::Mut);
6763 let ident = self.parse_ident()?;
6764 self.expect(&token::Colon)?;
6765 let ty = self.parse_ty()?;
6767 self.expect(&token::Semi)?;
6771 node: ForeignItemKind::Static(ty, mutbl),
6772 id: ast::DUMMY_NODE_ID,
6778 /// Parse a type from a foreign module
6779 fn parse_item_foreign_type(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
6780 -> PResult<'a, ForeignItem> {
6781 self.expect_keyword(keywords::Type)?;
6783 let ident = self.parse_ident()?;
6785 self.expect(&token::Semi)?;
6786 Ok(ast::ForeignItem {
6789 node: ForeignItemKind::Ty,
6790 id: ast::DUMMY_NODE_ID,
6796 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
6797 let error_msg = "crate name using dashes are not valid in `extern crate` statements";
6798 let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
6800 let mut ident = if self.token.is_keyword(keywords::SelfLower) {
6801 self.parse_path_segment_ident()
6805 let mut idents = vec![];
6806 let mut replacement = vec![];
6807 let mut fixed_crate_name = false;
6808 // Accept `extern crate name-like-this` for better diagnostics
6809 let dash = token::Token::BinOp(token::BinOpToken::Minus);
6810 if self.token == dash { // Do not include `-` as part of the expected tokens list
6811 while self.eat(&dash) {
6812 fixed_crate_name = true;
6813 replacement.push((self.prev_span, "_".to_string()));
6814 idents.push(self.parse_ident()?);
6817 if fixed_crate_name {
6818 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
6819 let mut fixed_name = format!("{}", ident.name);
6820 for part in idents {
6821 fixed_name.push_str(&format!("_{}", part.name));
6823 ident = Ident::from_str(&fixed_name).with_span_pos(fixed_name_sp);
6825 let mut err = self.struct_span_err(fixed_name_sp, error_msg);
6826 err.span_label(fixed_name_sp, "dash-separated idents are not valid");
6827 err.multipart_suggestion(suggestion_msg, replacement);
6833 /// Parse extern crate links
6837 /// extern crate foo;
6838 /// extern crate bar as foo;
6839 fn parse_item_extern_crate(&mut self,
6841 visibility: Visibility,
6842 attrs: Vec<Attribute>)
6843 -> PResult<'a, P<Item>> {
6844 // Accept `extern crate name-like-this` for better diagnostics
6845 let orig_name = self.parse_crate_name_with_dashes()?;
6846 let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
6847 (rename, Some(orig_name.name))
6851 self.expect(&token::Semi)?;
6853 let span = lo.to(self.prev_span);
6854 Ok(self.mk_item(span, item_name, ItemKind::ExternCrate(orig_name), visibility, attrs))
6857 /// Parse `extern` for foreign ABIs
6860 /// `extern` is expected to have been
6861 /// consumed before calling this method
6867 fn parse_item_foreign_mod(&mut self,
6869 opt_abi: Option<Abi>,
6870 visibility: Visibility,
6871 mut attrs: Vec<Attribute>)
6872 -> PResult<'a, P<Item>> {
6873 self.expect(&token::OpenDelim(token::Brace))?;
6875 let abi = opt_abi.unwrap_or(Abi::C);
6877 attrs.extend(self.parse_inner_attributes()?);
6879 let mut foreign_items = vec![];
6880 while !self.eat(&token::CloseDelim(token::Brace)) {
6881 foreign_items.push(self.parse_foreign_item()?);
6884 let prev_span = self.prev_span;
6885 let m = ast::ForeignMod {
6887 items: foreign_items
6889 let invalid = keywords::Invalid.ident();
6890 Ok(self.mk_item(lo.to(prev_span), invalid, ItemKind::ForeignMod(m), visibility, attrs))
6893 /// Parse `type Foo = Bar;`
6895 /// `existential type Foo: Bar;`
6897 /// `return None` without modifying the parser state
6898 fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, ast::Generics)>> {
6899 // This parses the grammar:
6900 // Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
6901 if self.check_keyword(keywords::Type) ||
6902 self.check_keyword(keywords::Existential) &&
6903 self.look_ahead(1, |t| t.is_keyword(keywords::Type)) {
6904 let existential = self.eat_keyword(keywords::Existential);
6905 assert!(self.eat_keyword(keywords::Type));
6906 Some(self.parse_existential_or_alias(existential))
6912 /// Parse type alias or existential type
6913 fn parse_existential_or_alias(
6916 ) -> PResult<'a, (Ident, AliasKind, ast::Generics)> {
6917 let ident = self.parse_ident()?;
6918 let mut tps = self.parse_generics()?;
6919 tps.where_clause = self.parse_where_clause()?;
6920 let alias = if existential {
6921 self.expect(&token::Colon)?;
6922 let bounds = self.parse_generic_bounds()?;
6923 AliasKind::Existential(bounds)
6925 self.expect(&token::Eq)?;
6926 let ty = self.parse_ty()?;
6929 self.expect(&token::Semi)?;
6930 Ok((ident, alias, tps))
6933 /// Parse the part of an "enum" decl following the '{'
6934 fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> {
6935 let mut variants = Vec::new();
6936 let mut all_nullary = true;
6937 let mut any_disr = None;
6938 while self.token != token::CloseDelim(token::Brace) {
6939 let variant_attrs = self.parse_outer_attributes()?;
6940 let vlo = self.span;
6943 let mut disr_expr = None;
6944 let ident = self.parse_ident()?;
6945 if self.check(&token::OpenDelim(token::Brace)) {
6946 // Parse a struct variant.
6947 all_nullary = false;
6948 struct_def = VariantData::Struct(self.parse_record_struct_body()?,
6949 ast::DUMMY_NODE_ID);
6950 } else if self.check(&token::OpenDelim(token::Paren)) {
6951 all_nullary = false;
6952 struct_def = VariantData::Tuple(self.parse_tuple_struct_body()?,
6953 ast::DUMMY_NODE_ID);
6954 } else if self.eat(&token::Eq) {
6955 disr_expr = Some(AnonConst {
6956 id: ast::DUMMY_NODE_ID,
6957 value: self.parse_expr()?,
6959 any_disr = disr_expr.as_ref().map(|c| c.value.span);
6960 struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
6962 struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
6965 let vr = ast::Variant_ {
6967 attrs: variant_attrs,
6971 variants.push(respan(vlo.to(self.prev_span), vr));
6973 if !self.eat(&token::Comma) { break; }
6975 self.expect(&token::CloseDelim(token::Brace))?;
6977 Some(disr_span) if !all_nullary =>
6978 self.span_err(disr_span,
6979 "discriminator values can only be used with a field-less enum"),
6983 Ok(ast::EnumDef { variants })
6986 /// Parse an "enum" declaration
6987 fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
6988 let id = self.parse_ident()?;
6989 let mut generics = self.parse_generics()?;
6990 generics.where_clause = self.parse_where_clause()?;
6991 self.expect(&token::OpenDelim(token::Brace))?;
6993 let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
6994 self.recover_stmt();
6995 self.eat(&token::CloseDelim(token::Brace));
6998 Ok((id, ItemKind::Enum(enum_definition, generics), None))
7001 /// Parses a string as an ABI spec on an extern type or module. Consumes
7002 /// the `extern` keyword, if one is found.
7003 fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
7005 token::Literal(token::Str_(s), suf) | token::Literal(token::StrRaw(s, _), suf) => {
7007 self.expect_no_suffix(sp, "ABI spec", suf);
7009 match abi::lookup(&s.as_str()) {
7010 Some(abi) => Ok(Some(abi)),
7012 let prev_span = self.prev_span;
7013 let mut err = struct_span_err!(
7014 self.sess.span_diagnostic,
7017 "invalid ABI: found `{}`",
7019 err.span_label(prev_span, "invalid ABI");
7020 err.help(&format!("valid ABIs: {}", abi::all_names().join(", ")));
7031 fn is_static_global(&mut self) -> bool {
7032 if self.check_keyword(keywords::Static) {
7033 // Check if this could be a closure
7034 !self.look_ahead(1, |token| {
7035 if token.is_keyword(keywords::Move) {
7039 token::BinOp(token::Or) | token::OrOr => true,
7050 attrs: Vec<Attribute>,
7051 macros_allowed: bool,
7052 attributes_allowed: bool,
7053 ) -> PResult<'a, Option<P<Item>>> {
7054 let (ret, tokens) = self.collect_tokens(|this| {
7055 this.parse_item_implementation(attrs, macros_allowed, attributes_allowed)
7058 // Once we've parsed an item and recorded the tokens we got while
7059 // parsing we may want to store `tokens` into the item we're about to
7060 // return. Note, though, that we specifically didn't capture tokens
7061 // related to outer attributes. The `tokens` field here may later be
7062 // used with procedural macros to convert this item back into a token
7063 // stream, but during expansion we may be removing attributes as we go
7066 // If we've got inner attributes then the `tokens` we've got above holds
7067 // these inner attributes. If an inner attribute is expanded we won't
7068 // actually remove it from the token stream, so we'll just keep yielding
7069 // it (bad!). To work around this case for now we just avoid recording
7070 // `tokens` if we detect any inner attributes. This should help keep
7071 // expansion correct, but we should fix this bug one day!
7074 if !i.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
7075 i.tokens = Some(tokens);
7082 /// Parse one of the items allowed by the flags.
7083 fn parse_item_implementation(
7085 attrs: Vec<Attribute>,
7086 macros_allowed: bool,
7087 attributes_allowed: bool,
7088 ) -> PResult<'a, Option<P<Item>>> {
7089 maybe_whole!(self, NtItem, |item| {
7090 let mut item = item.into_inner();
7091 let mut attrs = attrs;
7092 mem::swap(&mut item.attrs, &mut attrs);
7093 item.attrs.extend(attrs);
7099 let visibility = self.parse_visibility(false)?;
7101 if self.eat_keyword(keywords::Use) {
7103 let item_ = ItemKind::Use(P(self.parse_use_tree()?));
7104 self.expect(&token::Semi)?;
7106 let span = lo.to(self.prev_span);
7107 let item = self.mk_item(span, keywords::Invalid.ident(), item_, visibility, attrs);
7108 return Ok(Some(item));
7111 if self.check_keyword(keywords::Extern) && self.is_extern_non_path() {
7112 self.bump(); // `extern`
7113 if self.eat_keyword(keywords::Crate) {
7114 return Ok(Some(self.parse_item_extern_crate(lo, visibility, attrs)?));
7117 let opt_abi = self.parse_opt_abi()?;
7119 if self.eat_keyword(keywords::Fn) {
7120 // EXTERN FUNCTION ITEM
7121 let fn_span = self.prev_span;
7122 let abi = opt_abi.unwrap_or(Abi::C);
7123 let (ident, item_, extra_attrs) =
7124 self.parse_item_fn(Unsafety::Normal,
7126 respan(fn_span, Constness::NotConst),
7128 let prev_span = self.prev_span;
7129 let item = self.mk_item(lo.to(prev_span),
7133 maybe_append(attrs, extra_attrs));
7134 return Ok(Some(item));
7135 } else if self.check(&token::OpenDelim(token::Brace)) {
7136 return Ok(Some(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs)?));
7142 if self.is_static_global() {
7145 let m = if self.eat_keyword(keywords::Mut) {
7148 Mutability::Immutable
7150 let (ident, item_, extra_attrs) = self.parse_item_const(Some(m))?;
7151 let prev_span = self.prev_span;
7152 let item = self.mk_item(lo.to(prev_span),
7156 maybe_append(attrs, extra_attrs));
7157 return Ok(Some(item));
7159 if self.eat_keyword(keywords::Const) {
7160 let const_span = self.prev_span;
7161 if self.check_keyword(keywords::Fn)
7162 || (self.check_keyword(keywords::Unsafe)
7163 && self.look_ahead(1, |t| t.is_keyword(keywords::Fn))) {
7164 // CONST FUNCTION ITEM
7165 let unsafety = self.parse_unsafety();
7167 let (ident, item_, extra_attrs) =
7168 self.parse_item_fn(unsafety,
7170 respan(const_span, Constness::Const),
7172 let prev_span = self.prev_span;
7173 let item = self.mk_item(lo.to(prev_span),
7177 maybe_append(attrs, extra_attrs));
7178 return Ok(Some(item));
7182 if self.eat_keyword(keywords::Mut) {
7183 let prev_span = self.prev_span;
7184 self.diagnostic().struct_span_err(prev_span, "const globals cannot be mutable")
7185 .help("did you mean to declare a static?")
7188 let (ident, item_, extra_attrs) = self.parse_item_const(None)?;
7189 let prev_span = self.prev_span;
7190 let item = self.mk_item(lo.to(prev_span),
7194 maybe_append(attrs, extra_attrs));
7195 return Ok(Some(item));
7198 // `unsafe async fn` or `async fn`
7200 self.check_keyword(keywords::Unsafe) &&
7201 self.look_ahead(1, |t| t.is_keyword(keywords::Async))
7203 self.check_keyword(keywords::Async) &&
7204 self.look_ahead(1, |t| t.is_keyword(keywords::Fn))
7207 // ASYNC FUNCTION ITEM
7208 let unsafety = self.parse_unsafety();
7209 self.expect_keyword(keywords::Async)?;
7210 self.expect_keyword(keywords::Fn)?;
7211 let fn_span = self.prev_span;
7212 let (ident, item_, extra_attrs) =
7213 self.parse_item_fn(unsafety,
7215 closure_id: ast::DUMMY_NODE_ID,
7216 return_impl_trait_id: ast::DUMMY_NODE_ID,
7218 respan(fn_span, Constness::NotConst),
7220 let prev_span = self.prev_span;
7221 let item = self.mk_item(lo.to(prev_span),
7225 maybe_append(attrs, extra_attrs));
7226 return Ok(Some(item));
7228 if self.check_keyword(keywords::Unsafe) &&
7229 (self.look_ahead(1, |t| t.is_keyword(keywords::Trait)) ||
7230 self.look_ahead(1, |t| t.is_keyword(keywords::Auto)))
7232 // UNSAFE TRAIT ITEM
7233 self.bump(); // `unsafe`
7234 let is_auto = if self.eat_keyword(keywords::Trait) {
7237 self.expect_keyword(keywords::Auto)?;
7238 self.expect_keyword(keywords::Trait)?;
7241 let (ident, item_, extra_attrs) =
7242 self.parse_item_trait(is_auto, Unsafety::Unsafe)?;
7243 let prev_span = self.prev_span;
7244 let item = self.mk_item(lo.to(prev_span),
7248 maybe_append(attrs, extra_attrs));
7249 return Ok(Some(item));
7251 if self.check_keyword(keywords::Impl) ||
7252 self.check_keyword(keywords::Unsafe) &&
7253 self.look_ahead(1, |t| t.is_keyword(keywords::Impl)) ||
7254 self.check_keyword(keywords::Default) &&
7255 self.look_ahead(1, |t| t.is_keyword(keywords::Impl)) ||
7256 self.check_keyword(keywords::Default) &&
7257 self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) {
7259 let defaultness = self.parse_defaultness();
7260 let unsafety = self.parse_unsafety();
7261 self.expect_keyword(keywords::Impl)?;
7262 let (ident, item, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?;
7263 let span = lo.to(self.prev_span);
7264 return Ok(Some(self.mk_item(span, ident, item, visibility,
7265 maybe_append(attrs, extra_attrs))));
7267 if self.check_keyword(keywords::Fn) {
7270 let fn_span = self.prev_span;
7271 let (ident, item_, extra_attrs) =
7272 self.parse_item_fn(Unsafety::Normal,
7274 respan(fn_span, Constness::NotConst),
7276 let prev_span = self.prev_span;
7277 let item = self.mk_item(lo.to(prev_span),
7281 maybe_append(attrs, extra_attrs));
7282 return Ok(Some(item));
7284 if self.check_keyword(keywords::Unsafe)
7285 && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
7286 // UNSAFE FUNCTION ITEM
7287 self.bump(); // `unsafe`
7288 // `{` is also expected after `unsafe`, in case of error, include it in the diagnostic
7289 self.check(&token::OpenDelim(token::Brace));
7290 let abi = if self.eat_keyword(keywords::Extern) {
7291 self.parse_opt_abi()?.unwrap_or(Abi::C)
7295 self.expect_keyword(keywords::Fn)?;
7296 let fn_span = self.prev_span;
7297 let (ident, item_, extra_attrs) =
7298 self.parse_item_fn(Unsafety::Unsafe,
7300 respan(fn_span, Constness::NotConst),
7302 let prev_span = self.prev_span;
7303 let item = self.mk_item(lo.to(prev_span),
7307 maybe_append(attrs, extra_attrs));
7308 return Ok(Some(item));
7310 if self.eat_keyword(keywords::Mod) {
7312 let (ident, item_, extra_attrs) =
7313 self.parse_item_mod(&attrs[..])?;
7314 let prev_span = self.prev_span;
7315 let item = self.mk_item(lo.to(prev_span),
7319 maybe_append(attrs, extra_attrs));
7320 return Ok(Some(item));
7322 if let Some(type_) = self.eat_type() {
7323 let (ident, alias, generics) = type_?;
7325 let item_ = match alias {
7326 AliasKind::Weak(ty) => ItemKind::Ty(ty, generics),
7327 AliasKind::Existential(bounds) => ItemKind::Existential(bounds, generics),
7329 let prev_span = self.prev_span;
7330 let item = self.mk_item(lo.to(prev_span),
7335 return Ok(Some(item));
7337 if self.eat_keyword(keywords::Enum) {
7339 let (ident, item_, extra_attrs) = self.parse_item_enum()?;
7340 let prev_span = self.prev_span;
7341 let item = self.mk_item(lo.to(prev_span),
7345 maybe_append(attrs, extra_attrs));
7346 return Ok(Some(item));
7348 if self.check_keyword(keywords::Trait)
7349 || (self.check_keyword(keywords::Auto)
7350 && self.look_ahead(1, |t| t.is_keyword(keywords::Trait)))
7352 let is_auto = if self.eat_keyword(keywords::Trait) {
7355 self.expect_keyword(keywords::Auto)?;
7356 self.expect_keyword(keywords::Trait)?;
7360 let (ident, item_, extra_attrs) =
7361 self.parse_item_trait(is_auto, Unsafety::Normal)?;
7362 let prev_span = self.prev_span;
7363 let item = self.mk_item(lo.to(prev_span),
7367 maybe_append(attrs, extra_attrs));
7368 return Ok(Some(item));
7370 if self.eat_keyword(keywords::Struct) {
7372 let (ident, item_, extra_attrs) = self.parse_item_struct()?;
7373 let prev_span = self.prev_span;
7374 let item = self.mk_item(lo.to(prev_span),
7378 maybe_append(attrs, extra_attrs));
7379 return Ok(Some(item));
7381 if self.is_union_item() {
7384 let (ident, item_, extra_attrs) = self.parse_item_union()?;
7385 let prev_span = self.prev_span;
7386 let item = self.mk_item(lo.to(prev_span),
7390 maybe_append(attrs, extra_attrs));
7391 return Ok(Some(item));
7393 if let Some(macro_def) = self.eat_macro_def(&attrs, &visibility, lo)? {
7394 return Ok(Some(macro_def));
7397 // Verify whether we have encountered a struct or method definition where the user forgot to
7398 // add the `struct` or `fn` keyword after writing `pub`: `pub S {}`
7399 if visibility.node.is_pub() &&
7400 self.check_ident() &&
7401 self.look_ahead(1, |t| *t != token::Not)
7403 // Space between `pub` keyword and the identifier
7406 // ^^^ `sp` points here
7407 let sp = self.prev_span.between(self.span);
7408 let full_sp = self.prev_span.to(self.span);
7409 let ident_sp = self.span;
7410 if self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) {
7411 // possible public struct definition where `struct` was forgotten
7412 let ident = self.parse_ident().unwrap();
7413 let msg = format!("add `struct` here to parse `{}` as a public struct",
7415 let mut err = self.diagnostic()
7416 .struct_span_err(sp, "missing `struct` for struct definition");
7417 err.span_suggestion_short_with_applicability(
7418 sp, &msg, " struct ".into(), Applicability::MaybeIncorrect // speculative
7421 } else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
7422 let ident = self.parse_ident().unwrap();
7424 let kw_name = if let Ok(Some(_)) = self.parse_self_arg() {
7429 self.consume_block(token::Paren);
7430 let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
7431 self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
7433 ("fn", kw_name, false)
7434 } else if self.check(&token::OpenDelim(token::Brace)) {
7436 ("fn", kw_name, false)
7437 } else if self.check(&token::Colon) {
7441 ("fn` or `struct", "function or struct", true)
7443 self.consume_block(token::Brace);
7445 let msg = format!("missing `{}` for {} definition", kw, kw_name);
7446 let mut err = self.diagnostic().struct_span_err(sp, &msg);
7448 let suggestion = format!("add `{}` here to parse `{}` as a public {}",
7452 err.span_suggestion_short_with_applicability(
7453 sp, &suggestion, format!(" {} ", kw), Applicability::MachineApplicable
7456 if let Ok(snippet) = self.sess.source_map().span_to_snippet(ident_sp) {
7457 err.span_suggestion_with_applicability(
7459 "if you meant to call a macro, try",
7460 format!("{}!", snippet),
7461 // this is the `ambiguous` conditional branch
7462 Applicability::MaybeIncorrect
7465 err.help("if you meant to call a macro, remove the `pub` \
7466 and add a trailing `!` after the identifier");
7470 } else if self.look_ahead(1, |t| *t == token::Lt) {
7471 let ident = self.parse_ident().unwrap();
7472 self.eat_to_tokens(&[&token::Gt]);
7474 let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
7475 if let Ok(Some(_)) = self.parse_self_arg() {
7476 ("fn", "method", false)
7478 ("fn", "function", false)
7480 } else if self.check(&token::OpenDelim(token::Brace)) {
7481 ("struct", "struct", false)
7483 ("fn` or `struct", "function or struct", true)
7485 let msg = format!("missing `{}` for {} definition", kw, kw_name);
7486 let mut err = self.diagnostic().struct_span_err(sp, &msg);
7488 err.span_suggestion_short_with_applicability(
7490 &format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name),
7491 format!(" {} ", kw),
7492 Applicability::MachineApplicable,
7498 self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
7501 /// Parse a foreign item.
7502 crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> {
7503 maybe_whole!(self, NtForeignItem, |ni| ni);
7505 let attrs = self.parse_outer_attributes()?;
7507 let visibility = self.parse_visibility(false)?;
7509 // FOREIGN STATIC ITEM
7510 // Treat `const` as `static` for error recovery, but don't add it to expected tokens.
7511 if self.check_keyword(keywords::Static) || self.token.is_keyword(keywords::Const) {
7512 if self.token.is_keyword(keywords::Const) {
7514 .struct_span_err(self.span, "extern items cannot be `const`")
7515 .span_suggestion_with_applicability(
7517 "try using a static value",
7518 "static".to_owned(),
7519 Applicability::MachineApplicable
7522 self.bump(); // `static` or `const`
7523 return Ok(self.parse_item_foreign_static(visibility, lo, attrs)?);
7525 // FOREIGN FUNCTION ITEM
7526 if self.check_keyword(keywords::Fn) {
7527 return Ok(self.parse_item_foreign_fn(visibility, lo, attrs)?);
7529 // FOREIGN TYPE ITEM
7530 if self.check_keyword(keywords::Type) {
7531 return Ok(self.parse_item_foreign_type(visibility, lo, attrs)?);
7534 match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? {
7538 ident: keywords::Invalid.ident(),
7539 span: lo.to(self.prev_span),
7540 id: ast::DUMMY_NODE_ID,
7543 node: ForeignItemKind::Macro(mac),
7548 if !attrs.is_empty() {
7549 self.expected_item_err(&attrs);
7557 /// This is the fall-through for parsing items.
7558 fn parse_macro_use_or_failure(
7560 attrs: Vec<Attribute> ,
7561 macros_allowed: bool,
7562 attributes_allowed: bool,
7564 visibility: Visibility
7565 ) -> PResult<'a, Option<P<Item>>> {
7566 if macros_allowed && self.token.is_path_start() {
7567 // MACRO INVOCATION ITEM
7569 let prev_span = self.prev_span;
7570 self.complain_if_pub_macro(&visibility.node, prev_span);
7572 let mac_lo = self.span;
7575 let pth = self.parse_path(PathStyle::Mod)?;
7576 self.expect(&token::Not)?;
7578 // a 'special' identifier (like what `macro_rules!` uses)
7579 // is optional. We should eventually unify invoc syntax
7581 let id = if self.token.is_ident() {
7584 keywords::Invalid.ident() // no special identifier
7586 // eat a matched-delimiter token tree:
7587 let (delim, tts) = self.expect_delimited_token_tree()?;
7588 if delim != MacDelimiter::Brace {
7589 if !self.eat(&token::Semi) {
7590 self.span_err(self.prev_span,
7591 "macros that expand to items must either \
7592 be surrounded with braces or followed by \
7597 let hi = self.prev_span;
7598 let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim });
7599 let item = self.mk_item(lo.to(hi), id, ItemKind::Mac(mac), visibility, attrs);
7600 return Ok(Some(item));
7603 // FAILURE TO PARSE ITEM
7604 match visibility.node {
7605 VisibilityKind::Inherited => {}
7607 return Err(self.span_fatal(self.prev_span, "unmatched visibility `pub`"));
7611 if !attributes_allowed && !attrs.is_empty() {
7612 self.expected_item_err(&attrs);
7617 /// Parse a macro invocation inside a `trait`, `impl` or `extern` block
7618 fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
7619 at_end: &mut bool) -> PResult<'a, Option<Mac>>
7621 if self.token.is_path_start() && !self.is_extern_non_path() {
7622 let prev_span = self.prev_span;
7624 let pth = self.parse_path(PathStyle::Mod)?;
7626 if pth.segments.len() == 1 {
7627 if !self.eat(&token::Not) {
7628 return Err(self.missing_assoc_item_kind_err(item_kind, prev_span));
7631 self.expect(&token::Not)?;
7634 if let Some(vis) = vis {
7635 self.complain_if_pub_macro(&vis.node, prev_span);
7640 // eat a matched-delimiter token tree:
7641 let (delim, tts) = self.expect_delimited_token_tree()?;
7642 if delim != MacDelimiter::Brace {
7643 self.expect(&token::Semi)?
7646 Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim })))
7652 fn collect_tokens<F, R>(&mut self, f: F) -> PResult<'a, (R, TokenStream)>
7653 where F: FnOnce(&mut Self) -> PResult<'a, R>
7655 // Record all tokens we parse when parsing this item.
7656 let mut tokens = Vec::new();
7657 let prev_collecting = match self.token_cursor.frame.last_token {
7658 LastToken::Collecting(ref mut list) => {
7659 Some(mem::replace(list, Vec::new()))
7661 LastToken::Was(ref mut last) => {
7662 tokens.extend(last.take());
7666 self.token_cursor.frame.last_token = LastToken::Collecting(tokens);
7667 let prev = self.token_cursor.stack.len();
7669 let last_token = if self.token_cursor.stack.len() == prev {
7670 &mut self.token_cursor.frame.last_token
7672 &mut self.token_cursor.stack[prev].last_token
7675 // Pull our the toekns that we've collected from the call to `f` above
7676 let mut collected_tokens = match *last_token {
7677 LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()),
7678 LastToken::Was(_) => panic!("our vector went away?"),
7681 // If we're not at EOF our current token wasn't actually consumed by
7682 // `f`, but it'll still be in our list that we pulled out. In that case
7684 let extra_token = if self.token != token::Eof {
7685 collected_tokens.pop()
7690 // If we were previously collecting tokens, then this was a recursive
7691 // call. In that case we need to record all the tokens we collected in
7692 // our parent list as well. To do that we push a clone of our stream
7693 // onto the previous list.
7694 let stream = collected_tokens.into_iter().collect::<TokenStream>();
7695 match prev_collecting {
7697 list.push(stream.clone());
7698 list.extend(extra_token);
7699 *last_token = LastToken::Collecting(list);
7702 *last_token = LastToken::Was(extra_token);
7709 pub fn parse_item(&mut self) -> PResult<'a, Option<P<Item>>> {
7710 let attrs = self.parse_outer_attributes()?;
7711 self.parse_item_(attrs, true, false)
7715 fn is_import_coupler(&mut self) -> bool {
7716 self.check(&token::ModSep) &&
7717 self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace) ||
7718 *t == token::BinOp(token::Star))
7723 /// USE_TREE = [`::`] `*` |
7724 /// [`::`] `{` USE_TREE_LIST `}` |
7726 /// PATH `::` `{` USE_TREE_LIST `}` |
7727 /// PATH [`as` IDENT]
7728 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
7731 let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() };
7732 let kind = if self.check(&token::OpenDelim(token::Brace)) ||
7733 self.check(&token::BinOp(token::Star)) ||
7734 self.is_import_coupler() {
7735 // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
7736 let mod_sep_ctxt = self.span.ctxt();
7737 if self.eat(&token::ModSep) {
7738 prefix.segments.push(
7739 PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))
7743 if self.eat(&token::BinOp(token::Star)) {
7746 UseTreeKind::Nested(self.parse_use_tree_list()?)
7749 // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
7750 prefix = self.parse_path(PathStyle::Mod)?;
7752 if self.eat(&token::ModSep) {
7753 if self.eat(&token::BinOp(token::Star)) {
7756 UseTreeKind::Nested(self.parse_use_tree_list()?)
7759 UseTreeKind::Simple(self.parse_rename()?, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID)
7763 Ok(UseTree { prefix, kind, span: lo.to(self.prev_span) })
7766 /// Parse UseTreeKind::Nested(list)
7768 /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`]
7769 fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> {
7770 self.parse_unspanned_seq(&token::OpenDelim(token::Brace),
7771 &token::CloseDelim(token::Brace),
7772 SeqSep::trailing_allowed(token::Comma), |this| {
7773 Ok((this.parse_use_tree()?, ast::DUMMY_NODE_ID))
7777 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
7778 if self.eat_keyword(keywords::As) {
7779 self.parse_ident_or_underscore().map(Some)
7785 /// Parses a source module as a crate. This is the main
7786 /// entry point for the parser.
7787 pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> {
7790 attrs: self.parse_inner_attributes()?,
7791 module: self.parse_mod_items(&token::Eof, lo)?,
7792 span: lo.to(self.span),
7796 pub fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
7797 let ret = match self.token {
7798 token::Literal(token::Str_(s), suf) => (s, ast::StrStyle::Cooked, suf),
7799 token::Literal(token::StrRaw(s, n), suf) => (s, ast::StrStyle::Raw(n), suf),
7806 pub fn parse_str(&mut self) -> PResult<'a, (Symbol, StrStyle)> {
7807 match self.parse_optional_str() {
7808 Some((s, style, suf)) => {
7809 let sp = self.prev_span;
7810 self.expect_no_suffix(sp, "string literal", suf);
7814 let msg = "expected string literal";
7815 let mut err = self.fatal(msg);
7816 err.span_label(self.span, msg);