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.
12 use ast
::{AngleBracketedParameterData, ParenthesizedParameterData, AttrStyle, BareFnTy}
;
13 use ast
::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}
;
15 use ast
::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind}
;
17 use ast
::{BlockCheckMode, CaptureBy}
;
18 use ast
::{Constness, Crate}
;
21 use ast
::{Expr, ExprKind, RangeLimits}
;
22 use ast
::{Field, FnDecl}
;
23 use ast
::{ForeignItem, ForeignItemKind, FunctionRetTy}
;
24 use ast
::{Ident, ImplItem, IsAuto, Item, ItemKind}
;
25 use ast
::{Lifetime, LifetimeDef, Lit, LitKind, UintTy}
;
27 use ast
::MacStmtStyle
;
29 use ast
::{MutTy, Mutability}
;
30 use ast
::{Pat, PatKind, PathSegment}
;
31 use ast
::{PolyTraitRef, QSelf}
;
32 use ast
::{Stmt, StmtKind}
;
33 use ast
::{VariantData, StructField}
;
36 use ast
::{TraitItem, TraitRef, TraitObjectSyntax}
;
37 use ast
::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds}
;
38 use ast
::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}
;
39 use ast
::{Visibility, WhereClause, CrateSugar}
;
40 use ast
::{BinOpKind, UnOp}
;
41 use ast
::{RangeEnd, RangeSyntax}
;
43 use codemap
::{self, CodeMap, Spanned, respan}
;
44 use syntax_pos
::{self, Span, BytePos}
;
45 use errors
::{self, DiagnosticBuilder}
;
46 use parse
::{self, classify, token}
;
47 use parse
::common
::SeqSep
;
48 use parse
::lexer
::TokenAndSpan
;
49 use parse
::lexer
::comments
::{doc_comment_style, strip_doc_comment_decoration}
;
50 use parse
::obsolete
::ObsoleteSyntax
;
51 use parse
::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership}
;
52 use util
::parser
::{AssocOp, Fixity}
;
56 use tokenstream
::{self, Delimited, ThinTokenStream, TokenTree, TokenStream}
;
57 use symbol
::{Symbol, keywords}
;
61 use std
::collections
::HashSet
;
63 use std
::path
::{self, Path, PathBuf}
;
67 pub struct Restrictions
: u8 {
68 const STMT_EXPR
= 1 << 0;
69 const NO_STRUCT_LITERAL
= 1 << 1;
73 type ItemInfo
= (Ident
, ItemKind
, Option
<Vec
<Attribute
> >);
75 /// How to parse a path.
76 #[derive(Copy, Clone, PartialEq)]
78 /// In some contexts, notably in expressions, paths with generic arguments are ambiguous
79 /// with something else. For example, in expressions `segment < ....` can be interpreted
80 /// as a comparison and `segment ( ....` can be interpreted as a function call.
81 /// In all such contexts the non-path interpretation is preferred by default for practical
82 /// reasons, but the path interpretation can be forced by the disambiguator `::`, e.g.
83 /// `x<y>` - comparisons, `x::<y>` - unambiguously a path.
85 /// In other contexts, notably in types, no ambiguity exists and paths can be written
86 /// without the disambiguator, e.g. `x<y>` - unambiguously a path.
87 /// Paths with disambiguators are still accepted, `x::<Y>` - unambiguously a path too.
89 /// A path with generic arguments disallowed, e.g. `foo::bar::Baz`, used in imports,
90 /// visibilities or attributes.
91 /// Technically, this variant is unnecessary and e.g. `Expr` can be used instead
92 /// (paths in "mod" contexts have to be checked later for absence of generic arguments
93 /// anyway, due to macros), but it is used to avoid weird suggestions about expected
94 /// tokens when something goes wrong.
98 #[derive(Clone, Copy, Debug, PartialEq)]
99 pub enum SemiColonMode
{
104 #[derive(Clone, Copy, Debug, PartialEq)]
110 /// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
111 /// dropped into the token stream, which happens while parsing the result of
112 /// macro expansion). Placement of these is not as complex as I feared it would
113 /// be. The important thing is to make sure that lookahead doesn't balk at
114 /// `token::Interpolated` tokens.
115 macro_rules
! maybe_whole_expr
{
117 if let token
::Interpolated(nt
) = $p
.token
.clone() {
119 token
::NtExpr(ref e
) => {
121 return Ok((*e
).clone());
123 token
::NtPath(ref path
) => {
126 let kind
= ExprKind
::Path(None
, (*path
).clone());
127 return Ok($p
.mk_expr(span
, kind
, ThinVec
::new()));
129 token
::NtBlock(ref block
) => {
132 let kind
= ExprKind
::Block((*block
).clone());
133 return Ok($p
.mk_expr(span
, kind
, ThinVec
::new()));
141 /// As maybe_whole_expr, but for things other than expressions
142 macro_rules
! maybe_whole
{
143 ($p
:expr
, $constructor
:ident
, |$x
:ident
| $e
:expr
) => {
144 if let token
::Interpolated(nt
) = $p
.token
.clone() {
145 if let token
::$
constructor($x
) = nt
.0.clone() {
153 fn maybe_append(mut lhs
: Vec
<Attribute
>, rhs
: Option
<Vec
<Attribute
>>)
155 if let Some(ref attrs
) = rhs
{
156 lhs
.extend(attrs
.iter().cloned())
161 #[derive(Debug, Clone, Copy, PartialEq)]
172 /* ident is handled by common.rs */
175 pub struct Parser
<'a
> {
176 pub sess
: &'a ParseSess
,
177 /// the current token:
178 pub token
: token
::Token
,
179 /// the span of the current token:
181 /// the span of the previous token:
182 pub meta_var_span
: Option
<Span
>,
184 /// the previous token kind
185 prev_token_kind
: PrevTokenKind
,
186 pub restrictions
: Restrictions
,
187 /// The set of seen errors about obsolete syntax. Used to suppress
188 /// extra detail when the same error is seen twice
189 pub obsolete_set
: HashSet
<ObsoleteSyntax
>,
190 /// Used to determine the path to externally loaded source files
191 pub directory
: Directory
,
192 /// Whether to parse sub-modules in other files.
193 pub recurse_into_file_modules
: bool
,
194 /// Name of the root module this parser originated from. If `None`, then the
195 /// name is not known. This does not change while the parser is descending
196 /// into modules, and sub-parsers have new values for this name.
197 pub root_module_name
: Option
<String
>,
198 pub expected_tokens
: Vec
<TokenType
>,
199 token_cursor
: TokenCursor
,
200 pub desugar_doc_comments
: bool
,
201 /// Whether we should configure out of line modules as we parse.
208 frame
: TokenCursorFrame
,
209 stack
: Vec
<TokenCursorFrame
>,
213 struct TokenCursorFrame
{
214 delim
: token
::DelimToken
,
217 tree_cursor
: tokenstream
::Cursor
,
219 last_token
: LastToken
,
222 /// This is used in `TokenCursorFrame` above to track tokens that are consumed
223 /// by the parser, and then that's transitively used to record the tokens that
224 /// each parse AST item is created with.
226 /// Right now this has two states, either collecting tokens or not collecting
227 /// tokens. If we're collecting tokens we just save everything off into a local
228 /// `Vec`. This should eventually though likely save tokens from the original
229 /// token stream and just use slicing of token streams to avoid creation of a
230 /// whole new vector.
232 /// The second state is where we're passively not recording tokens, but the last
233 /// token is still tracked for when we want to start recording tokens. This
234 /// "last token" means that when we start recording tokens we'll want to ensure
235 /// that this, the first token, is included in the output.
237 /// You can find some more example usage of this in the `collect_tokens` method
241 Collecting(Vec
<TokenTree
>),
242 Was(Option
<TokenTree
>),
245 impl TokenCursorFrame
{
246 fn new(sp
: Span
, delimited
: &Delimited
) -> Self {
248 delim
: delimited
.delim
,
250 open_delim
: delimited
.delim
== token
::NoDelim
,
251 tree_cursor
: delimited
.stream().into_trees(),
252 close_delim
: delimited
.delim
== token
::NoDelim
,
253 last_token
: LastToken
::Was(None
),
259 fn next(&mut self) -> TokenAndSpan
{
261 let tree
= if !self.frame
.open_delim
{
262 self.frame
.open_delim
= true;
263 Delimited { delim: self.frame.delim, tts: TokenStream::empty().into() }
264 .open_tt(self.frame
.span
)
265 } else if let Some(tree
) = self.frame
.tree_cursor
.next() {
267 } else if !self.frame
.close_delim
{
268 self.frame
.close_delim
= true;
269 Delimited { delim: self.frame.delim, tts: TokenStream::empty().into() }
270 .close_tt(self.frame
.span
)
271 } else if let Some(frame
) = self.stack
.pop() {
275 return TokenAndSpan { tok: token::Eof, sp: syntax_pos::DUMMY_SP }
278 match self.frame
.last_token
{
279 LastToken
::Collecting(ref mut v
) => v
.push(tree
.clone()),
280 LastToken
::Was(ref mut t
) => *t
= Some(tree
.clone()),
284 TokenTree
::Token(sp
, tok
) => return TokenAndSpan { tok: tok, sp: sp }
,
285 TokenTree
::Delimited(sp
, ref delimited
) => {
286 let frame
= TokenCursorFrame
::new(sp
, delimited
);
287 self.stack
.push(mem
::replace(&mut self.frame
, frame
));
293 fn next_desugared(&mut self) -> TokenAndSpan
{
294 let (sp
, name
) = match self.next() {
295 TokenAndSpan { sp, tok: token::DocComment(name) }
=> (sp
, name
),
299 let stripped
= strip_doc_comment_decoration(&name
.as_str());
301 // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
302 // required to wrap the text.
303 let mut num_of_hashes
= 0;
305 for ch
in stripped
.chars() {
308 '#' if count > 0 => count + 1,
311 num_of_hashes = cmp::max(num_of_hashes, count);
314 let body = TokenTree::Delimited(sp, Delimited {
315 delim: token::Bracket,
316 tts: [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc
"))),
317 TokenTree::Token(sp, token::Eq),
318 TokenTree::Token(sp, token::Literal(
319 token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))]
320 .iter().cloned().collect::<TokenStream>().into(),
323 self.stack.push(mem::replace(&mut self.frame, TokenCursorFrame::new(sp, &Delimited {
324 delim: token::NoDelim,
325 tts: if doc_comment_style(&name.as_str()) == AttrStyle::Inner {
326 [TokenTree::Token(sp, token::Pound), TokenTree::Token(sp, token::Not), body]
327 .iter().cloned().collect::<TokenStream>().into()
329 [TokenTree::Token(sp, token::Pound), body]
330 .iter().cloned().collect::<TokenStream>().into()
338 #[derive(PartialEq, Eq, Clone)]
341 Keyword(keywords::Keyword),
350 fn to_string(&self) -> String {
352 TokenType::Token(ref t) => format!("`{}`
", Parser::token_to_string(t)),
353 TokenType::Keyword(kw) => format!("`{}`
", kw.name()),
354 TokenType::Operator => "an operator
".to_string(),
355 TokenType::Lifetime => "lifetime
".to_string(),
356 TokenType::Ident => "identifier
".to_string(),
357 TokenType::Path => "path
".to_string(),
358 TokenType::Type => "type".to_string(),
363 // Returns true if `IDENT t` can start a type - `IDENT::a::b`, `IDENT<u8, u8>`,
364 // `IDENT<<u8 as Trait>::AssocTy>`, `IDENT(u8, u8) -> u8`.
365 fn can_continue_type_after_ident(t: &token::Token) -> bool {
366 t == &token::ModSep || t == &token::Lt ||
367 t == &token::BinOp(token::Shl) || t == &token::OpenDelim(token::Paren)
370 /// Information about the path to a module.
371 pub struct ModulePath {
373 pub path_exists: bool,
374 pub result: Result<ModulePathSuccess, Error>,
377 pub struct ModulePathSuccess {
379 pub directory_ownership: DirectoryOwnership,
383 pub struct ModulePathError {
385 pub help_msg: String,
389 FileNotFoundForModule {
391 default_path: String,
392 secondary_path: String,
397 default_path: String,
398 secondary_path: String,
401 InclusiveRangeWithNoEnd,
405 pub fn span_err(self, sp: Span, handler: &errors::Handler) -> DiagnosticBuilder {
407 Error::FileNotFoundForModule { ref mod_name,
411 let mut err = struct_span_err!(handler, sp, E0583,
412 "file not found
for module `{}`
", mod_name);
413 err.help(&format!("name the file either {} or {} inside the directory {:?}
",
419 Error::DuplicatePaths { ref mod_name, ref default_path, ref secondary_path } => {
420 let mut err = struct_span_err!(handler, sp, E0584,
421 "file
for module `{}` found at both {} and {}
",
425 err.help("delete or rename one of them to remove the ambiguity
");
428 Error::UselessDocComment => {
429 let mut err = struct_span_err!(handler, sp, E0585,
430 "found a documentation comment that doesn't document anything
");
431 err.help("doc comments must come before what they document
, maybe a comment was
\
432 intended with `
//`?");
435 Error
::InclusiveRangeWithNoEnd
=> {
436 let mut err
= struct_span_err
!(handler
, sp
, E0586
,
437 "inclusive range with no end");
438 err
.help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)");
448 AttributesParsed(ThinVec
<Attribute
>),
449 AlreadyParsed(P
<Expr
>),
452 impl From
<Option
<ThinVec
<Attribute
>>> for LhsExpr
{
453 fn from(o
: Option
<ThinVec
<Attribute
>>) -> Self {
454 if let Some(attrs
) = o
{
455 LhsExpr
::AttributesParsed(attrs
)
457 LhsExpr
::NotYetParsed
462 impl From
<P
<Expr
>> for LhsExpr
{
463 fn from(expr
: P
<Expr
>) -> Self {
464 LhsExpr
::AlreadyParsed(expr
)
468 /// Create a placeholder argument.
469 fn dummy_arg(span
: Span
) -> Arg
{
470 let spanned
= Spanned
{
472 node
: keywords
::Invalid
.ident()
475 id
: ast
::DUMMY_NODE_ID
,
476 node
: PatKind
::Ident(BindingMode
::ByValue(Mutability
::Immutable
), spanned
, None
),
482 id
: ast
::DUMMY_NODE_ID
484 Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID }
487 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
488 enum TokenExpectType
{
493 impl<'a
> Parser
<'a
> {
494 pub fn new(sess
: &'a ParseSess
,
496 directory
: Option
<Directory
>,
497 recurse_into_file_modules
: bool
,
498 desugar_doc_comments
: bool
)
500 let mut parser
= Parser
{
502 token
: token
::Underscore
,
503 span
: syntax_pos
::DUMMY_SP
,
504 prev_span
: syntax_pos
::DUMMY_SP
,
506 prev_token_kind
: PrevTokenKind
::Other
,
507 restrictions
: Restrictions
::empty(),
508 obsolete_set
: HashSet
::new(),
509 recurse_into_file_modules
,
510 directory
: Directory { path: PathBuf::new(), ownership: DirectoryOwnership::Owned }
,
511 root_module_name
: None
,
512 expected_tokens
: Vec
::new(),
513 token_cursor
: TokenCursor
{
514 frame
: TokenCursorFrame
::new(syntax_pos
::DUMMY_SP
, &Delimited
{
515 delim
: token
::NoDelim
,
520 desugar_doc_comments
,
524 let tok
= parser
.next_tok();
525 parser
.token
= tok
.tok
;
526 parser
.span
= tok
.sp
;
528 if let Some(directory
) = directory
{
529 parser
.directory
= directory
;
530 } else if parser
.span
!= syntax_pos
::DUMMY_SP
{
531 parser
.directory
.path
= sess
.codemap().span_to_unmapped_path(parser
.span
);
532 parser
.directory
.path
.pop();
535 parser
.process_potential_macro_variable();
539 fn next_tok(&mut self) -> TokenAndSpan
{
540 let mut next
= if self.desugar_doc_comments
{
541 self.token_cursor
.next_desugared()
543 self.token_cursor
.next()
545 if next
.sp
== syntax_pos
::DUMMY_SP
{
546 next
.sp
= self.prev_span
;
551 /// Convert a token to a string using self's reader
552 pub fn token_to_string(token
: &token
::Token
) -> String
{
553 pprust
::token_to_string(token
)
556 /// Convert the current token to a string using self's reader
557 pub fn this_token_to_string(&self) -> String
{
558 Parser
::token_to_string(&self.token
)
561 pub fn this_token_descr(&self) -> String
{
562 let prefix
= match &self.token
{
563 t
if t
.is_special_ident() => "reserved identifier ",
564 t
if t
.is_used_keyword() => "keyword ",
565 t
if t
.is_unused_keyword() => "reserved keyword ",
568 format
!("{}`{}`", prefix
, self.this_token_to_string())
571 pub fn unexpected_last
<T
>(&self, t
: &token
::Token
) -> PResult
<'a
, T
> {
572 let token_str
= Parser
::token_to_string(t
);
573 Err(self.span_fatal(self.prev_span
, &format
!("unexpected token: `{}`", token_str
)))
576 pub fn unexpected
<T
>(&mut self) -> PResult
<'a
, T
> {
577 match self.expect_one_of(&[], &[]) {
579 Ok(_
) => unreachable
!(),
583 /// Expect and consume the token t. Signal an error if
584 /// the next token is not t.
585 pub fn expect(&mut self, t
: &token
::Token
) -> PResult
<'a
, ()> {
586 if self.expected_tokens
.is_empty() {
587 if self.token
== *t
{
591 let token_str
= Parser
::token_to_string(t
);
592 let this_token_str
= self.this_token_to_string();
593 Err(self.fatal(&format
!("expected `{}`, found `{}`",
598 self.expect_one_of(unsafe { slice::from_raw_parts(t, 1) }
, &[])
602 /// Expect next token to be edible or inedible token. If edible,
603 /// then consume it; if inedible, then return without consuming
604 /// anything. Signal a fatal error if next token is unexpected.
605 pub fn expect_one_of(&mut self,
606 edible
: &[token
::Token
],
607 inedible
: &[token
::Token
]) -> PResult
<'a
, ()>{
608 fn tokens_to_string(tokens
: &[TokenType
]) -> String
{
609 let mut i
= tokens
.iter();
610 // This might be a sign we need a connect method on Iterator.
612 .map_or("".to_string(), |t
| t
.to_string());
613 i
.enumerate().fold(b
, |mut b
, (i
, a
)| {
614 if tokens
.len() > 2 && i
== tokens
.len() - 2 {
616 } else if tokens
.len() == 2 && i
== tokens
.len() - 2 {
621 b
.push_str(&a
.to_string());
625 if edible
.contains(&self.token
) {
628 } else if inedible
.contains(&self.token
) {
629 // leave it in the input
632 let mut expected
= edible
.iter()
633 .map(|x
| TokenType
::Token(x
.clone()))
634 .chain(inedible
.iter().map(|x
| TokenType
::Token(x
.clone())))
635 .chain(self.expected_tokens
.iter().cloned())
636 .collect
::<Vec
<_
>>();
637 expected
.sort_by(|a
, b
| a
.to_string().cmp(&b
.to_string()));
639 let expect
= tokens_to_string(&expected
[..]);
640 let actual
= self.this_token_to_string();
641 let (msg_exp
, (label_sp
, label_exp
)) = if expected
.len() > 1 {
642 let short_expect
= if expected
.len() > 6 {
643 format
!("{} possible tokens", expected
.len())
647 (format
!("expected one of {}, found `{}`", expect
, actual
),
648 (self.prev_span
.next_point(), format
!("expected one of {} here", short_expect
)))
649 } else if expected
.is_empty() {
650 (format
!("unexpected token: `{}`", actual
),
651 (self.prev_span
, "unexpected token after this".to_string()))
653 (format
!("expected {}, found `{}`", expect
, actual
),
654 (self.prev_span
.next_point(), format
!("expected {} here", expect
)))
656 let mut err
= self.fatal(&msg_exp
);
657 let sp
= if self.token
== token
::Token
::Eof
{
658 // This is EOF, don't want to point at the following char, but rather the last token
663 if self.span
.contains(sp
) {
664 err
.span_label(self.span
, label_exp
);
666 err
.span_label(sp
, label_exp
);
667 err
.span_label(self.span
, "unexpected token");
673 /// returns the span of expr, if it was not interpolated or the span of the interpolated token
674 fn interpolated_or_expr_span(&self,
675 expr
: PResult
<'a
, P
<Expr
>>)
676 -> PResult
<'a
, (Span
, P
<Expr
>)> {
678 if self.prev_token_kind
== PrevTokenKind
::Interpolated
{
686 pub fn parse_ident(&mut self) -> PResult
<'a
, ast
::Ident
> {
689 if self.token
.is_reserved_ident() {
690 self.span_err(self.span
, &format
!("expected identifier, found {}",
691 self.this_token_descr()));
697 Err(if self.prev_token_kind
== PrevTokenKind
::DocComment
{
698 self.span_fatal_err(self.prev_span
, Error
::UselessDocComment
)
700 let mut err
= self.fatal(&format
!("expected identifier, found `{}`",
701 self.this_token_to_string()));
702 if self.token
== token
::Underscore
{
703 err
.note("`_` is a wildcard pattern, not an identifier");
711 /// Check if the next token is `tok`, and return `true` if so.
713 /// This method will automatically add `tok` to `expected_tokens` if `tok` is not
715 pub fn check(&mut self, tok
: &token
::Token
) -> bool
{
716 let is_present
= self.token
== *tok
;
717 if !is_present { self.expected_tokens.push(TokenType::Token(tok.clone())); }
721 /// Consume token 'tok' if it exists. Returns true if the given
722 /// token was present, false otherwise.
723 pub fn eat(&mut self, tok
: &token
::Token
) -> bool
{
724 let is_present
= self.check(tok
);
725 if is_present { self.bump() }
729 pub fn check_keyword(&mut self, kw
: keywords
::Keyword
) -> bool
{
730 self.expected_tokens
.push(TokenType
::Keyword(kw
));
731 self.token
.is_keyword(kw
)
734 /// If the next token is the given keyword, eat it and return
735 /// true. Otherwise, return false.
736 pub fn eat_keyword(&mut self, kw
: keywords
::Keyword
) -> bool
{
737 if self.check_keyword(kw
) {
745 pub fn eat_keyword_noexpect(&mut self, kw
: keywords
::Keyword
) -> bool
{
746 if self.token
.is_keyword(kw
) {
754 /// If the given word is not a keyword, signal an error.
755 /// If the next token is not the given word, signal an error.
756 /// Otherwise, eat it.
757 pub fn expect_keyword(&mut self, kw
: keywords
::Keyword
) -> PResult
<'a
, ()> {
758 if !self.eat_keyword(kw
) {
765 fn check_ident(&mut self) -> bool
{
766 if self.token
.is_ident() {
769 self.expected_tokens
.push(TokenType
::Ident
);
774 fn check_path(&mut self) -> bool
{
775 if self.token
.is_path_start() {
778 self.expected_tokens
.push(TokenType
::Path
);
783 fn check_type(&mut self) -> bool
{
784 if self.token
.can_begin_type() {
787 self.expected_tokens
.push(TokenType
::Type
);
792 /// Expect and consume an `&`. If `&&` is seen, replace it with a single
793 /// `&` and continue. If an `&` is not seen, signal an error.
794 fn expect_and(&mut self) -> PResult
<'a
, ()> {
795 self.expected_tokens
.push(TokenType
::Token(token
::BinOp(token
::And
)));
797 token
::BinOp(token
::And
) => {
802 let span
= self.span
.with_lo(self.span
.lo() + BytePos(1));
803 Ok(self.bump_with(token
::BinOp(token
::And
), span
))
805 _
=> self.unexpected()
809 /// Expect and consume an `|`. If `||` is seen, replace it with a single
810 /// `|` and continue. If an `|` is not seen, signal an error.
811 fn expect_or(&mut self) -> PResult
<'a
, ()> {
812 self.expected_tokens
.push(TokenType
::Token(token
::BinOp(token
::Or
)));
814 token
::BinOp(token
::Or
) => {
819 let span
= self.span
.with_lo(self.span
.lo() + BytePos(1));
820 Ok(self.bump_with(token
::BinOp(token
::Or
), span
))
822 _
=> self.unexpected()
826 pub fn expect_no_suffix(&self, sp
: Span
, kind
: &str, suffix
: Option
<ast
::Name
>) {
828 None
=> {/* everything ok */}
830 let text
= suf
.as_str();
832 self.span_bug(sp
, "found empty literal suffix in Some")
834 self.span_err(sp
, &format
!("{} with a suffix is invalid", kind
));
839 /// Attempt to consume a `<`. If `<<` is seen, replace it with a single
840 /// `<` and continue. If a `<` is not seen, return false.
842 /// This is meant to be used when parsing generics on a path to get the
844 fn eat_lt(&mut self) -> bool
{
845 self.expected_tokens
.push(TokenType
::Token(token
::Lt
));
851 token
::BinOp(token
::Shl
) => {
852 let span
= self.span
.with_lo(self.span
.lo() + BytePos(1));
853 self.bump_with(token
::Lt
, span
);
860 fn expect_lt(&mut self) -> PResult
<'a
, ()> {
868 /// Expect and consume a GT. if a >> is seen, replace it
869 /// with a single > and continue. If a GT is not seen,
871 pub fn expect_gt(&mut self) -> PResult
<'a
, ()> {
872 self.expected_tokens
.push(TokenType
::Token(token
::Gt
));
878 token
::BinOp(token
::Shr
) => {
879 let span
= self.span
.with_lo(self.span
.lo() + BytePos(1));
880 Ok(self.bump_with(token
::Gt
, span
))
882 token
::BinOpEq(token
::Shr
) => {
883 let span
= self.span
.with_lo(self.span
.lo() + BytePos(1));
884 Ok(self.bump_with(token
::Ge
, span
))
887 let span
= self.span
.with_lo(self.span
.lo() + BytePos(1));
888 Ok(self.bump_with(token
::Eq
, span
))
890 _
=> self.unexpected()
894 pub fn parse_seq_to_before_gt_or_return
<T
, F
>(&mut self,
895 sep
: Option
<token
::Token
>,
897 -> PResult
<'a
, (Vec
<T
>, bool
)>
898 where F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, Option
<T
>>,
900 let mut v
= Vec
::new();
901 // This loop works by alternating back and forth between parsing types
902 // and commas. For example, given a string `A, B,>`, the parser would
903 // first parse `A`, then a comma, then `B`, then a comma. After that it
904 // would encounter a `>` and stop. This lets the parser handle trailing
905 // commas in generic parameters, because it can stop either after
906 // parsing a type or after parsing a comma.
908 if self.check(&token
::Gt
)
909 || self.token
== token
::BinOp(token
::Shr
)
910 || self.token
== token
::Ge
911 || self.token
== token
::BinOpEq(token
::Shr
) {
917 Some(result
) => v
.push(result
),
918 None
=> return Ok((v
, true))
921 if let Some(t
) = sep
.as_ref() {
927 return Ok((v
, false));
930 /// Parse a sequence bracketed by '<' and '>', stopping
932 pub fn parse_seq_to_before_gt
<T
, F
>(&mut self,
933 sep
: Option
<token
::Token
>,
935 -> PResult
<'a
, Vec
<T
>> where
936 F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, T
>,
938 let (result
, returned
) = self.parse_seq_to_before_gt_or_return(sep
,
939 |p
| Ok(Some(f(p
)?
)))?
;
944 pub fn parse_seq_to_gt
<T
, F
>(&mut self,
945 sep
: Option
<token
::Token
>,
947 -> PResult
<'a
, Vec
<T
>> where
948 F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, T
>,
950 let v
= self.parse_seq_to_before_gt(sep
, f
)?
;
955 pub fn parse_seq_to_gt_or_return
<T
, F
>(&mut self,
956 sep
: Option
<token
::Token
>,
958 -> PResult
<'a
, (Vec
<T
>, bool
)> where
959 F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, Option
<T
>>,
961 let (v
, returned
) = self.parse_seq_to_before_gt_or_return(sep
, f
)?
;
965 return Ok((v
, returned
));
968 /// Eat and discard tokens until one of `kets` is encountered. Respects token trees,
969 /// passes through any errors encountered. Used for error recovery.
970 pub fn eat_to_tokens(&mut self, kets
: &[&token
::Token
]) {
971 let handler
= self.diagnostic();
973 if let Err(ref mut err
) = self.parse_seq_to_before_tokens(kets
,
975 TokenExpectType
::Expect
,
976 |p
| Ok(p
.parse_token_tree())) {
981 /// Parse a sequence, including the closing delimiter. The function
982 /// f must consume tokens until reaching the next separator or
984 pub fn parse_seq_to_end
<T
, F
>(&mut self,
988 -> PResult
<'a
, Vec
<T
>> where
989 F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, T
>,
991 let val
= self.parse_seq_to_before_end(ket
, sep
, f
)?
;
996 /// Parse a sequence, not including the closing delimiter. The function
997 /// f must consume tokens until reaching the next separator or
999 pub fn parse_seq_to_before_end
<T
, F
>(&mut self,
1003 -> PResult
<'a
, Vec
<T
>>
1004 where F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, T
>
1006 self.parse_seq_to_before_tokens(&[ket
], sep
, TokenExpectType
::Expect
, f
)
1009 fn parse_seq_to_before_tokens
<T
, F
>(&mut self,
1010 kets
: &[&token
::Token
],
1012 expect
: TokenExpectType
,
1014 -> PResult
<'a
, Vec
<T
>>
1015 where F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, T
>
1017 let mut first
: bool
= true;
1019 while !kets
.contains(&&self.token
) {
1021 token
::CloseDelim(..) | token
::Eof
=> break,
1024 if let Some(ref t
) = sep
.sep
{
1028 if let Err(mut e
) = self.expect(t
) {
1029 // Attempt to keep parsing if it was a similar separator
1030 if let Some(ref tokens
) = t
.similar_tokens() {
1031 if tokens
.contains(&self.token
) {
1036 // Attempt to keep parsing if it was an omitted separator
1050 if sep
.trailing_sep_allowed
&& kets
.iter().any(|k
| {
1052 TokenExpectType
::Expect
=> self.check(k
),
1053 TokenExpectType
::NoExpect
=> self.token
== **k
,
1066 /// Parse a sequence, including the closing delimiter. The function
1067 /// f must consume tokens until reaching the next separator or
1068 /// closing bracket.
1069 pub fn parse_unspanned_seq
<T
, F
>(&mut self,
1074 -> PResult
<'a
, Vec
<T
>> where
1075 F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, T
>,
1078 let result
= self.parse_seq_to_before_end(ket
, sep
, f
)?
;
1079 if self.token
== *ket
{
1085 // NB: Do not use this function unless you actually plan to place the
1086 // spanned list in the AST.
1087 pub fn parse_seq
<T
, F
>(&mut self,
1092 -> PResult
<'a
, Spanned
<Vec
<T
>>> where
1093 F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, T
>,
1097 let result
= self.parse_seq_to_before_end(ket
, sep
, f
)?
;
1100 Ok(respan(lo
.to(hi
), result
))
1103 /// Advance the parser by one token
1104 pub fn bump(&mut self) {
1105 if self.prev_token_kind
== PrevTokenKind
::Eof
{
1106 // Bumping after EOF is a bad sign, usually an infinite loop.
1107 self.bug("attempted to bump the parser past EOF (may be stuck in a loop)");
1110 self.prev_span
= self.meta_var_span
.take().unwrap_or(self.span
);
1112 // Record last token kind for possible error recovery.
1113 self.prev_token_kind
= match self.token
{
1114 token
::DocComment(..) => PrevTokenKind
::DocComment
,
1115 token
::Comma
=> PrevTokenKind
::Comma
,
1116 token
::BinOp(token
::Plus
) => PrevTokenKind
::Plus
,
1117 token
::Interpolated(..) => PrevTokenKind
::Interpolated
,
1118 token
::Eof
=> PrevTokenKind
::Eof
,
1119 token
::Ident(..) => PrevTokenKind
::Ident
,
1120 _
=> PrevTokenKind
::Other
,
1123 let next
= self.next_tok();
1124 self.span
= next
.sp
;
1125 self.token
= next
.tok
;
1126 self.expected_tokens
.clear();
1127 // check after each token
1128 self.process_potential_macro_variable();
1131 /// Advance the parser using provided token as a next one. Use this when
1132 /// consuming a part of a token. For example a single `<` from `<<`.
1133 pub fn bump_with(&mut self, next
: token
::Token
, span
: Span
) {
1134 self.prev_span
= self.span
.with_hi(span
.lo());
1135 // It would be incorrect to record the kind of the current token, but
1136 // fortunately for tokens currently using `bump_with`, the
1137 // prev_token_kind will be of no use anyway.
1138 self.prev_token_kind
= PrevTokenKind
::Other
;
1141 self.expected_tokens
.clear();
1144 pub fn look_ahead
<R
, F
>(&self, dist
: usize, f
: F
) -> R
where
1145 F
: FnOnce(&token
::Token
) -> R
,
1148 return f(&self.token
)
1151 f(&match self.token_cursor
.frame
.tree_cursor
.look_ahead(dist
- 1) {
1152 Some(tree
) => match tree
{
1153 TokenTree
::Token(_
, tok
) => tok
,
1154 TokenTree
::Delimited(_
, delimited
) => token
::OpenDelim(delimited
.delim
),
1156 None
=> token
::CloseDelim(self.token_cursor
.frame
.delim
),
1159 fn look_ahead_span(&self, dist
: usize) -> Span
{
1164 match self.token_cursor
.frame
.tree_cursor
.look_ahead(dist
- 1) {
1165 Some(TokenTree
::Token(span
, _
)) | Some(TokenTree
::Delimited(span
, _
)) => span
,
1166 None
=> self.look_ahead_span(dist
- 1),
1169 pub fn fatal(&self, m
: &str) -> DiagnosticBuilder
<'a
> {
1170 self.sess
.span_diagnostic
.struct_span_fatal(self.span
, m
)
1172 pub fn span_fatal(&self, sp
: Span
, m
: &str) -> DiagnosticBuilder
<'a
> {
1173 self.sess
.span_diagnostic
.struct_span_fatal(sp
, m
)
1175 pub fn span_fatal_err(&self, sp
: Span
, err
: Error
) -> DiagnosticBuilder
<'a
> {
1176 err
.span_err(sp
, self.diagnostic())
1178 pub fn span_fatal_help(&self, sp
: Span
, m
: &str, help
: &str) -> DiagnosticBuilder
<'a
> {
1179 let mut err
= self.sess
.span_diagnostic
.struct_span_fatal(sp
, m
);
1183 pub fn bug(&self, m
: &str) -> ! {
1184 self.sess
.span_diagnostic
.span_bug(self.span
, m
)
1186 pub fn warn(&self, m
: &str) {
1187 self.sess
.span_diagnostic
.span_warn(self.span
, m
)
1189 pub fn span_warn(&self, sp
: Span
, m
: &str) {
1190 self.sess
.span_diagnostic
.span_warn(sp
, m
)
1192 pub fn span_err(&self, sp
: Span
, m
: &str) {
1193 self.sess
.span_diagnostic
.span_err(sp
, m
)
1195 pub fn span_err_help(&self, sp
: Span
, m
: &str, h
: &str) {
1196 let mut err
= self.sess
.span_diagnostic
.mut_span_err(sp
, m
);
1200 pub fn span_bug(&self, sp
: Span
, m
: &str) -> ! {
1201 self.sess
.span_diagnostic
.span_bug(sp
, m
)
1203 pub fn abort_if_errors(&self) {
1204 self.sess
.span_diagnostic
.abort_if_errors();
1207 fn cancel(&self, err
: &mut DiagnosticBuilder
) {
1208 self.sess
.span_diagnostic
.cancel(err
)
1211 pub fn diagnostic(&self) -> &'a errors
::Handler
{
1212 &self.sess
.span_diagnostic
1215 /// Is the current token one of the keywords that signals a bare function
1217 pub fn token_is_bare_fn_keyword(&mut self) -> bool
{
1218 self.check_keyword(keywords
::Fn
) ||
1219 self.check_keyword(keywords
::Unsafe
) ||
1220 self.check_keyword(keywords
::Extern
)
1223 fn get_label(&mut self) -> ast
::Ident
{
1225 token
::Lifetime(ref ident
) => *ident
,
1226 _
=> self.bug("not a lifetime"),
1230 /// parse a TyKind::BareFn type:
1231 pub fn parse_ty_bare_fn(&mut self, lifetime_defs
: Vec
<LifetimeDef
>)
1232 -> PResult
<'a
, TyKind
> {
1235 [unsafe] [extern "ABI"] fn (S) -> T
1245 let unsafety
= self.parse_unsafety()?
;
1246 let abi
= if self.eat_keyword(keywords
::Extern
) {
1247 self.parse_opt_abi()?
.unwrap_or(Abi
::C
)
1252 self.expect_keyword(keywords
::Fn
)?
;
1253 let (inputs
, variadic
) = self.parse_fn_args(false, true)?
;
1254 let ret_ty
= self.parse_ret_ty()?
;
1255 let decl
= P(FnDecl
{
1260 Ok(TyKind
::BareFn(P(BareFnTy
{
1263 lifetimes
: lifetime_defs
,
1268 pub fn parse_unsafety(&mut self) -> PResult
<'a
, Unsafety
> {
1269 if self.eat_keyword(keywords
::Unsafe
) {
1270 return Ok(Unsafety
::Unsafe
);
1272 return Ok(Unsafety
::Normal
);
1276 /// Parse the items in a trait declaration
1277 pub fn parse_trait_item(&mut self, at_end
: &mut bool
) -> PResult
<'a
, TraitItem
> {
1278 maybe_whole
!(self, NtTraitItem
, |x
| x
);
1279 let attrs
= self.parse_outer_attributes()?
;
1280 let (mut item
, tokens
) = self.collect_tokens(|this
| {
1281 this
.parse_trait_item_(at_end
, attrs
)
1283 // See `parse_item` for why this clause is here.
1284 if !item
.attrs
.iter().any(|attr
| attr
.style
== AttrStyle
::Inner
) {
1285 item
.tokens
= Some(tokens
);
1290 fn parse_trait_item_(&mut self,
1292 mut attrs
: Vec
<Attribute
>) -> PResult
<'a
, TraitItem
> {
1295 let (name
, node
, generics
) = if self.eat_keyword(keywords
::Type
) {
1296 let TyParam {ident, bounds, default, ..}
= self.parse_ty_param(vec
![])?
;
1297 self.expect(&token
::Semi
)?
;
1298 (ident
, TraitItemKind
::Type(bounds
, default), ast
::Generics
::default())
1299 } else if self.is_const_item() {
1300 self.expect_keyword(keywords
::Const
)?
;
1301 let ident
= self.parse_ident()?
;
1302 self.expect(&token
::Colon
)?
;
1303 let ty
= self.parse_ty()?
;
1304 let default = if self.check(&token
::Eq
) {
1306 let expr
= self.parse_expr()?
;
1307 self.expect(&token
::Semi
)?
;
1310 self.expect(&token
::Semi
)?
;
1313 (ident
, TraitItemKind
::Const(ty
, default), ast
::Generics
::default())
1314 } else if self.token
.is_path_start() {
1315 // trait item macro.
1316 // code copied from parse_macro_use_or_failure... abstraction!
1317 let prev_span
= self.prev_span
;
1319 let pth
= self.parse_path(PathStyle
::Mod
)?
;
1321 if pth
.segments
.len() == 1 {
1322 if !self.eat(&token
::Not
) {
1323 return Err(self.missing_assoc_item_kind_err("trait", prev_span
));
1326 self.expect(&token
::Not
)?
;
1329 // eat a matched-delimiter token tree:
1330 let (delim
, tts
) = self.expect_delimited_token_tree()?
;
1331 if delim
!= token
::Brace
{
1332 self.expect(&token
::Semi
)?
1335 let mac
= respan(lo
.to(self.prev_span
), Mac_ { path: pth, tts: tts }
);
1336 (keywords
::Invalid
.ident(), ast
::TraitItemKind
::Macro(mac
), ast
::Generics
::default())
1338 let (constness
, unsafety
, abi
) = self.parse_fn_front_matter()?
;
1340 let ident
= self.parse_ident()?
;
1341 let mut generics
= self.parse_generics()?
;
1343 let d
= self.parse_fn_decl_with_self(|p
: &mut Parser
<'a
>|{
1344 // This is somewhat dubious; We don't want to allow
1345 // argument names to be left off if there is a
1347 p
.parse_arg_general(false)
1349 generics
.where_clause
= self.parse_where_clause()?
;
1351 let sig
= ast
::MethodSig
{
1358 let body
= match self.token
{
1362 debug
!("parse_trait_methods(): parsing required method");
1365 token
::OpenDelim(token
::Brace
) => {
1366 debug
!("parse_trait_methods(): parsing provided method");
1368 let (inner_attrs
, body
) = self.parse_inner_attrs_and_block()?
;
1369 attrs
.extend(inner_attrs
.iter().cloned());
1373 let token_str
= self.this_token_to_string();
1374 return Err(self.fatal(&format
!("expected `;` or `{{`, found `{}`", token_str
)));
1377 (ident
, ast
::TraitItemKind
::Method(sig
, body
), generics
)
1381 id
: ast
::DUMMY_NODE_ID
,
1386 span
: lo
.to(self.prev_span
),
1391 /// Parse optional return type [ -> TY ] in function decl
1392 pub fn parse_ret_ty(&mut self) -> PResult
<'a
, FunctionRetTy
> {
1393 if self.eat(&token
::RArrow
) {
1394 Ok(FunctionRetTy
::Ty(self.parse_ty_no_plus()?
))
1396 Ok(FunctionRetTy
::Default(self.span
.with_hi(self.span
.lo())))
1401 pub fn parse_ty(&mut self) -> PResult
<'a
, P
<Ty
>> {
1402 self.parse_ty_common(true)
1405 /// Parse a type in restricted contexts where `+` is not permitted.
1406 /// Example 1: `&'a TYPE`
1407 /// `+` is prohibited to maintain operator priority (P(+) < P(&)).
1408 /// Example 2: `value1 as TYPE + value2`
1409 /// `+` is prohibited to avoid interactions with expression grammar.
1410 fn parse_ty_no_plus(&mut self) -> PResult
<'a
, P
<Ty
>> {
1411 self.parse_ty_common(false)
1414 fn parse_ty_common(&mut self, allow_plus
: bool
) -> PResult
<'a
, P
<Ty
>> {
1415 maybe_whole
!(self, NtTy
, |x
| x
);
1418 let node
= if self.eat(&token
::OpenDelim(token
::Paren
)) {
1419 // `(TYPE)` is a parenthesized type.
1420 // `(TYPE,)` is a tuple with a single field of type TYPE.
1421 let mut ts
= vec
![];
1422 let mut last_comma
= false;
1423 while self.token
!= token
::CloseDelim(token
::Paren
) {
1424 ts
.push(self.parse_ty()?
);
1425 if self.eat(&token
::Comma
) {
1432 let trailing_plus
= self.prev_token_kind
== PrevTokenKind
::Plus
;
1433 self.expect(&token
::CloseDelim(token
::Paren
))?
;
1435 if ts
.len() == 1 && !last_comma
{
1436 let ty
= ts
.into_iter().nth(0).unwrap().unwrap();
1437 let maybe_bounds
= allow_plus
&& self.token
== token
::BinOp(token
::Plus
);
1439 // `(TY_BOUND_NOPAREN) + BOUND + ...`.
1440 TyKind
::Path(None
, ref path
) if maybe_bounds
=> {
1441 self.parse_remaining_bounds(Vec
::new(), path
.clone(), lo
, true)?
1443 TyKind
::TraitObject(ref bounds
, TraitObjectSyntax
::None
)
1444 if maybe_bounds
&& bounds
.len() == 1 && !trailing_plus
=> {
1445 let path
= match bounds
[0] {
1446 TraitTyParamBound(ref pt
, ..) => pt
.trait_ref
.path
.clone(),
1447 _
=> self.bug("unexpected lifetime bound"),
1449 self.parse_remaining_bounds(Vec
::new(), path
, lo
, true)?
1452 _
=> TyKind
::Paren(P(ty
))
1457 } else if self.eat(&token
::Not
) {
1460 } else if self.eat(&token
::BinOp(token
::Star
)) {
1462 TyKind
::Ptr(self.parse_ptr()?
)
1463 } else if self.eat(&token
::OpenDelim(token
::Bracket
)) {
1465 let t
= self.parse_ty()?
;
1466 // Parse optional `; EXPR` in `[TYPE; EXPR]`
1467 let t
= match self.maybe_parse_fixed_length_of_vec()?
{
1468 None
=> TyKind
::Slice(t
),
1469 Some(suffix
) => TyKind
::Array(t
, suffix
),
1471 self.expect(&token
::CloseDelim(token
::Bracket
))?
;
1473 } else if self.check(&token
::BinOp(token
::And
)) || self.check(&token
::AndAnd
) {
1476 self.parse_borrowed_pointee()?
1477 } else if self.eat_keyword_noexpect(keywords
::Typeof
) {
1479 // In order to not be ambiguous, the type must be surrounded by parens.
1480 self.expect(&token
::OpenDelim(token
::Paren
))?
;
1481 let e
= self.parse_expr()?
;
1482 self.expect(&token
::CloseDelim(token
::Paren
))?
;
1484 } else if self.eat(&token
::Underscore
) {
1485 // A type to be inferred `_`
1487 } else if self.token_is_bare_fn_keyword() {
1488 // Function pointer type
1489 self.parse_ty_bare_fn(Vec
::new())?
1490 } else if self.check_keyword(keywords
::For
) {
1491 // Function pointer type or bound list (trait object type) starting with a poly-trait.
1492 // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
1493 // `for<'lt> Trait1<'lt> + Trait2 + 'a`
1495 let lifetime_defs
= self.parse_late_bound_lifetime_defs()?
;
1496 if self.token_is_bare_fn_keyword() {
1497 self.parse_ty_bare_fn(lifetime_defs
)?
1499 let path
= self.parse_path(PathStyle
::Type
)?
;
1500 let parse_plus
= allow_plus
&& self.check(&token
::BinOp(token
::Plus
));
1501 self.parse_remaining_bounds(lifetime_defs
, path
, lo
, parse_plus
)?
1503 } else if self.eat_keyword(keywords
::Impl
) {
1504 // FIXME: figure out priority of `+` in `impl Trait1 + Trait2` (#34511).
1505 TyKind
::ImplTrait(self.parse_ty_param_bounds()?
)
1506 } else if self.check_keyword(keywords
::Dyn
) &&
1507 self.look_ahead(1, |t
| t
.can_begin_bound() && !can_continue_type_after_ident(t
)) {
1508 // FIXME: figure out priority of `+` in `dyn Trait1 + Trait2` (#34511).
1509 self.bump(); // `dyn`
1510 TyKind
::TraitObject(self.parse_ty_param_bounds()?
, TraitObjectSyntax
::Dyn
)
1511 } else if self.check(&token
::Question
) ||
1512 self.check_lifetime() && self.look_ahead(1, |t
| t
== &token
::BinOp(token
::Plus
)) {
1513 // Bound list (trait object type)
1514 TyKind
::TraitObject(self.parse_ty_param_bounds_common(allow_plus
)?
,
1515 TraitObjectSyntax
::None
)
1516 } else if self.eat_lt() {
1518 let (qself
, path
) = self.parse_qpath(PathStyle
::Type
)?
;
1519 TyKind
::Path(Some(qself
), path
)
1520 } else if self.token
.is_path_start() {
1522 let path
= self.parse_path(PathStyle
::Type
)?
;
1523 if self.eat(&token
::Not
) {
1524 // Macro invocation in type position
1525 let (_
, tts
) = self.expect_delimited_token_tree()?
;
1526 TyKind
::Mac(respan(lo
.to(self.span
), Mac_ { path: path, tts: tts }
))
1528 // Just a type path or bound list (trait object type) starting with a trait.
1530 // `Trait1 + Trait2 + 'a`
1531 if allow_plus
&& self.check(&token
::BinOp(token
::Plus
)) {
1532 self.parse_remaining_bounds(Vec
::new(), path
, lo
, true)?
1534 TyKind
::Path(None
, path
)
1538 let msg
= format
!("expected type, found {}", self.this_token_descr());
1539 return Err(self.fatal(&msg
));
1542 let span
= lo
.to(self.prev_span
);
1543 let ty
= Ty { node, span, id: ast::DUMMY_NODE_ID }
;
1545 // Try to recover from use of `+` with incorrect priority.
1546 self.maybe_recover_from_bad_type_plus(allow_plus
, &ty
)?
;
1551 fn parse_remaining_bounds(&mut self, lifetime_defs
: Vec
<LifetimeDef
>, path
: ast
::Path
,
1552 lo
: Span
, parse_plus
: bool
) -> PResult
<'a
, TyKind
> {
1553 let poly_trait_ref
= PolyTraitRef
::new(lifetime_defs
, path
, lo
.to(self.prev_span
));
1554 let mut bounds
= vec
![TraitTyParamBound(poly_trait_ref
, TraitBoundModifier
::None
)];
1557 bounds
.append(&mut self.parse_ty_param_bounds()?
);
1559 Ok(TyKind
::TraitObject(bounds
, TraitObjectSyntax
::None
))
1562 fn maybe_recover_from_bad_type_plus(&mut self, allow_plus
: bool
, ty
: &Ty
) -> PResult
<'a
, ()> {
1563 // Do not add `+` to expected tokens.
1564 if !allow_plus
|| self.token
!= token
::BinOp(token
::Plus
) {
1569 let bounds
= self.parse_ty_param_bounds()?
;
1570 let sum_span
= ty
.span
.to(self.prev_span
);
1572 let mut err
= struct_span_err
!(self.sess
.span_diagnostic
, sum_span
, E0178
,
1573 "expected a path on the left-hand side of `+`, not `{}`", pprust
::ty_to_string(ty
));
1576 TyKind
::Rptr(ref lifetime
, ref mut_ty
) => {
1577 let sum_with_parens
= pprust
::to_string(|s
| {
1578 use print
::pprust
::PrintState
;
1581 s
.print_opt_lifetime(lifetime
)?
;
1582 s
.print_mutability(mut_ty
.mutbl
)?
;
1584 s
.print_type(&mut_ty
.ty
)?
;
1585 s
.print_bounds(" +", &bounds
)?
;
1588 err
.span_suggestion(sum_span
, "try adding parentheses", sum_with_parens
);
1590 TyKind
::Ptr(..) | TyKind
::BareFn(..) => {
1591 err
.span_label(sum_span
, "perhaps you forgot parentheses?");
1594 err
.span_label(sum_span
, "expected a path");
1601 fn parse_borrowed_pointee(&mut self) -> PResult
<'a
, TyKind
> {
1602 let opt_lifetime
= if self.check_lifetime() { Some(self.expect_lifetime()) }
else { None }
;
1603 let mutbl
= self.parse_mutability();
1604 let ty
= self.parse_ty_no_plus()?
;
1605 return Ok(TyKind
::Rptr(opt_lifetime
, MutTy { ty: ty, mutbl: mutbl }
));
1608 pub fn parse_ptr(&mut self) -> PResult
<'a
, MutTy
> {
1609 let mutbl
= if self.eat_keyword(keywords
::Mut
) {
1611 } else if self.eat_keyword(keywords
::Const
) {
1612 Mutability
::Immutable
1614 let span
= self.prev_span
;
1616 "expected mut or const in raw pointer type (use \
1617 `*mut T` or `*const T` as appropriate)");
1618 Mutability
::Immutable
1620 let t
= self.parse_ty_no_plus()?
;
1621 Ok(MutTy { ty: t, mutbl: mutbl }
)
1624 fn is_named_argument(&mut self) -> bool
{
1625 let offset
= match self.token
{
1626 token
::Interpolated(ref nt
) => match nt
.0 {
1627 token
::NtPat(..) => return self.look_ahead(1, |t
| t
== &token
::Colon
),
1630 token
::BinOp(token
::And
) | token
::AndAnd
=> 1,
1631 _
if self.token
.is_keyword(keywords
::Mut
) => 1,
1635 self.look_ahead(offset
, |t
| t
.is_ident() || t
== &token
::Underscore
) &&
1636 self.look_ahead(offset
+ 1, |t
| t
== &token
::Colon
)
1639 /// This version of parse arg doesn't necessarily require
1640 /// identifier names.
1641 pub fn parse_arg_general(&mut self, require_name
: bool
) -> PResult
<'a
, Arg
> {
1642 maybe_whole
!(self, NtArg
, |x
| x
);
1644 let pat
= if require_name
|| self.is_named_argument() {
1645 debug
!("parse_arg_general parse_pat (require_name:{})",
1647 let pat
= self.parse_pat()?
;
1649 self.expect(&token
::Colon
)?
;
1652 debug
!("parse_arg_general ident_to_pat");
1653 let sp
= self.prev_span
;
1654 let spanned
= Spanned { span: sp, node: keywords::Invalid.ident() }
;
1656 id
: ast
::DUMMY_NODE_ID
,
1657 node
: PatKind
::Ident(BindingMode
::ByValue(Mutability
::Immutable
),
1663 let t
= self.parse_ty()?
;
1668 id
: ast
::DUMMY_NODE_ID
,
1672 /// Parse a single function argument
1673 pub fn parse_arg(&mut self) -> PResult
<'a
, Arg
> {
1674 self.parse_arg_general(true)
1677 /// Parse an argument in a lambda header e.g. |arg, arg|
1678 pub fn parse_fn_block_arg(&mut self) -> PResult
<'a
, Arg
> {
1679 let pat
= self.parse_pat()?
;
1680 let t
= if self.eat(&token
::Colon
) {
1684 id
: ast
::DUMMY_NODE_ID
,
1685 node
: TyKind
::Infer
,
1692 id
: ast
::DUMMY_NODE_ID
1696 pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult
<'a
, Option
<P
<ast
::Expr
>>> {
1697 if self.eat(&token
::Semi
) {
1698 Ok(Some(self.parse_expr()?
))
1704 /// Matches token_lit = LIT_INTEGER | ...
1705 pub fn parse_lit_token(&mut self) -> PResult
<'a
, LitKind
> {
1706 let out
= match self.token
{
1707 token
::Interpolated(ref nt
) => match nt
.0 {
1708 token
::NtExpr(ref v
) => match v
.node
{
1709 ExprKind
::Lit(ref lit
) => { lit.node.clone() }
1710 _
=> { return self.unexpected_last(&self.token); }
1712 _
=> { return self.unexpected_last(&self.token); }
1714 token
::Literal(lit
, suf
) => {
1715 let diag
= Some((self.span
, &self.sess
.span_diagnostic
));
1716 let (suffix_illegal
, result
) = parse
::lit_token(lit
, suf
, diag
);
1720 self.expect_no_suffix(sp
, &format
!("{} literal", lit
.short_name()), suf
)
1725 _
=> { return self.unexpected_last(&self.token); }
1732 /// Matches lit = true | false | token_lit
1733 pub fn parse_lit(&mut self) -> PResult
<'a
, Lit
> {
1735 let lit
= if self.eat_keyword(keywords
::True
) {
1737 } else if self.eat_keyword(keywords
::False
) {
1738 LitKind
::Bool(false)
1740 let lit
= self.parse_lit_token()?
;
1743 Ok(codemap
::Spanned { node: lit, span: lo.to(self.prev_span) }
)
1746 /// matches '-' lit | lit (cf. ast_validation::AstValidator::check_expr_within_pat)
1747 pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult
<'a
, P
<Expr
>> {
1748 maybe_whole_expr
!(self);
1750 let minus_lo
= self.span
;
1751 let minus_present
= self.eat(&token
::BinOp(token
::Minus
));
1753 let literal
= P(self.parse_lit()?
);
1754 let hi
= self.prev_span
;
1755 let expr
= self.mk_expr(lo
.to(hi
), ExprKind
::Lit(literal
), ThinVec
::new());
1758 let minus_hi
= self.prev_span
;
1759 let unary
= self.mk_unary(UnOp
::Neg
, expr
);
1760 Ok(self.mk_expr(minus_lo
.to(minus_hi
), unary
, ThinVec
::new()))
1766 pub fn parse_path_segment_ident(&mut self) -> PResult
<'a
, ast
::Ident
> {
1768 token
::Ident(sid
) if self.token
.is_path_segment_keyword() => {
1772 _
=> self.parse_ident(),
1776 /// Parses qualified path.
1777 /// Assumes that the leading `<` has been parsed already.
1779 /// `qualified_path = <type [as trait_ref]>::path`
1783 /// `<T as U>::F::a<S>` (without disambiguator)
1784 /// `<T as U>::F::a::<S>` (with disambiguator)
1785 fn parse_qpath(&mut self, style
: PathStyle
) -> PResult
<'a
, (QSelf
, ast
::Path
)> {
1786 let lo
= self.prev_span
;
1787 let ty
= self.parse_ty()?
;
1788 let mut path
= if self.eat_keyword(keywords
::As
) {
1789 self.parse_path(PathStyle
::Type
)?
1791 ast
::Path { segments: Vec::new(), span: syntax_pos::DUMMY_SP }
1793 self.expect(&token
::Gt
)?
;
1794 self.expect(&token
::ModSep
)?
;
1796 let qself
= QSelf { ty, position: path.segments.len() }
;
1797 self.parse_path_segments(&mut path
.segments
, style
, true)?
;
1799 Ok((qself
, ast
::Path { segments: path.segments, span: lo.to(self.prev_span) }
))
1802 /// Parses simple paths.
1804 /// `path = [::] segment+`
1805 /// `segment = ident | ident[::]<args> | ident[::](args) [-> type]`
1808 /// `a::b::C<D>` (without disambiguator)
1809 /// `a::b::C::<D>` (with disambiguator)
1810 /// `Fn(Args)` (without disambiguator)
1811 /// `Fn::(Args)` (with disambiguator)
1812 pub fn parse_path(&mut self, style
: PathStyle
) -> PResult
<'a
, ast
::Path
> {
1813 self.parse_path_common(style
, true)
1816 pub fn parse_path_common(&mut self, style
: PathStyle
, enable_warning
: bool
)
1817 -> PResult
<'a
, ast
::Path
> {
1818 maybe_whole
!(self, NtPath
, |path
| {
1819 if style
== PathStyle
::Mod
&&
1820 path
.segments
.iter().any(|segment
| segment
.parameters
.is_some()) {
1821 self.diagnostic().span_err(path
.span
, "unexpected generic arguments in path");
1826 let lo
= self.meta_var_span
.unwrap_or(self.span
);
1827 let mut segments
= Vec
::new();
1828 if self.eat(&token
::ModSep
) {
1829 segments
.push(PathSegment
::crate_root(lo
));
1831 self.parse_path_segments(&mut segments
, style
, enable_warning
)?
;
1833 Ok(ast
::Path { segments, span: lo.to(self.prev_span) }
)
1836 /// Like `parse_path`, but also supports parsing `Word` meta items into paths for back-compat.
1837 /// This is used when parsing derive macro paths in `#[derive]` attributes.
1838 pub fn parse_path_allowing_meta(&mut self, style
: PathStyle
) -> PResult
<'a
, ast
::Path
> {
1839 let meta_ident
= match self.token
{
1840 token
::Interpolated(ref nt
) => match nt
.0 {
1841 token
::NtMeta(ref meta
) => match meta
.node
{
1842 ast
::MetaItemKind
::Word
=> Some(ast
::Ident
::with_empty_ctxt(meta
.name
)),
1849 if let Some(ident
) = meta_ident
{
1851 return Ok(ast
::Path
::from_ident(self.prev_span
, ident
));
1853 self.parse_path(style
)
1856 fn parse_path_segments(&mut self,
1857 segments
: &mut Vec
<PathSegment
>,
1859 enable_warning
: bool
)
1860 -> PResult
<'a
, ()> {
1862 segments
.push(self.parse_path_segment(style
, enable_warning
)?
);
1864 if self.is_import_coupler() || !self.eat(&token
::ModSep
) {
1870 fn parse_path_segment(&mut self, style
: PathStyle
, enable_warning
: bool
)
1871 -> PResult
<'a
, PathSegment
> {
1872 let ident_span
= self.span
;
1873 let ident
= self.parse_path_segment_ident()?
;
1875 let is_args_start
= |token
: &token
::Token
| match *token
{
1876 token
::Lt
| token
::BinOp(token
::Shl
) | token
::OpenDelim(token
::Paren
) => true,
1879 let check_args_start
= |this
: &mut Self| {
1880 this
.expected_tokens
.extend_from_slice(
1881 &[TokenType
::Token(token
::Lt
), TokenType
::Token(token
::OpenDelim(token
::Paren
))]
1883 is_args_start(&this
.token
)
1886 Ok(if style
== PathStyle
::Type
&& check_args_start(self) ||
1887 style
!= PathStyle
::Mod
&& self.check(&token
::ModSep
)
1888 && self.look_ahead(1, |t
| is_args_start(t
)) {
1889 // Generic arguments are found - `<`, `(`, `::<` or `::(`.
1891 if self.eat(&token
::ModSep
) && style
== PathStyle
::Type
&& enable_warning
{
1892 self.diagnostic().struct_span_warn(self.prev_span
, "unnecessary path disambiguator")
1893 .span_label(self.prev_span
, "try removing `::`").emit();
1896 let parameters
= if self.eat_lt() {
1898 let (lifetimes
, types
, bindings
) = self.parse_generic_args()?
;
1900 let span
= lo
.to(self.prev_span
);
1901 AngleBracketedParameterData { lifetimes, types, bindings, span }
.into()
1905 let inputs
= self.parse_seq_to_before_tokens(
1906 &[&token
::CloseDelim(token
::Paren
)],
1907 SeqSep
::trailing_allowed(token
::Comma
),
1908 TokenExpectType
::Expect
,
1911 let output
= if self.eat(&token
::RArrow
) {
1912 Some(self.parse_ty_no_plus()?
)
1916 let span
= lo
.to(self.prev_span
);
1917 ParenthesizedParameterData { inputs, output, span }
.into()
1920 PathSegment { identifier: ident, span: ident_span, parameters }
1922 // Generic arguments are not found.
1923 PathSegment
::from_ident(ident
, ident_span
)
1927 fn check_lifetime(&mut self) -> bool
{
1928 self.expected_tokens
.push(TokenType
::Lifetime
);
1929 self.token
.is_lifetime()
1932 /// Parse single lifetime 'a or panic.
1933 fn expect_lifetime(&mut self) -> Lifetime
{
1935 token
::Lifetime(ident
) => {
1936 let ident_span
= self.span
;
1938 Lifetime { ident: ident, span: ident_span, id: ast::DUMMY_NODE_ID }
1940 _
=> self.span_bug(self.span
, "not a lifetime")
1944 /// Parse mutability (`mut` or nothing).
1945 fn parse_mutability(&mut self) -> Mutability
{
1946 if self.eat_keyword(keywords
::Mut
) {
1949 Mutability
::Immutable
1953 pub fn parse_field_name(&mut self) -> PResult
<'a
, Ident
> {
1954 if let token
::Literal(token
::Integer(name
), None
) = self.token
{
1956 Ok(Ident
::with_empty_ctxt(name
))
1962 /// Parse ident (COLON expr)?
1963 pub fn parse_field(&mut self) -> PResult
<'a
, Field
> {
1964 let attrs
= self.parse_outer_attributes()?
;
1968 // Check if a colon exists one ahead. This means we're parsing a fieldname.
1969 let (fieldname
, expr
, is_shorthand
) = if self.look_ahead(1, |t
| t
== &token
::Colon
) {
1970 let fieldname
= self.parse_field_name()?
;
1972 hi
= self.prev_span
;
1973 (fieldname
, self.parse_expr()?
, false)
1975 let fieldname
= self.parse_ident()?
;
1976 hi
= self.prev_span
;
1978 // Mimic `x: x` for the `x` field shorthand.
1979 let path
= ast
::Path
::from_ident(lo
.to(hi
), fieldname
);
1980 (fieldname
, self.mk_expr(lo
.to(hi
), ExprKind
::Path(None
, path
), ThinVec
::new()), true)
1983 ident
: respan(lo
.to(hi
), fieldname
),
1984 span
: lo
.to(expr
.span
),
1987 attrs
: attrs
.into(),
1991 pub fn mk_expr(&mut self, span
: Span
, node
: ExprKind
, attrs
: ThinVec
<Attribute
>) -> P
<Expr
> {
1993 id
: ast
::DUMMY_NODE_ID
,
1996 attrs
: attrs
.into(),
2000 pub fn mk_unary(&mut self, unop
: ast
::UnOp
, expr
: P
<Expr
>) -> ast
::ExprKind
{
2001 ExprKind
::Unary(unop
, expr
)
2004 pub fn mk_binary(&mut self, binop
: ast
::BinOp
, lhs
: P
<Expr
>, rhs
: P
<Expr
>) -> ast
::ExprKind
{
2005 ExprKind
::Binary(binop
, lhs
, rhs
)
2008 pub fn mk_call(&mut self, f
: P
<Expr
>, args
: Vec
<P
<Expr
>>) -> ast
::ExprKind
{
2009 ExprKind
::Call(f
, args
)
2012 pub fn mk_index(&mut self, expr
: P
<Expr
>, idx
: P
<Expr
>) -> ast
::ExprKind
{
2013 ExprKind
::Index(expr
, idx
)
2016 pub fn mk_range(&mut self,
2017 start
: Option
<P
<Expr
>>,
2018 end
: Option
<P
<Expr
>>,
2019 limits
: RangeLimits
)
2020 -> PResult
<'a
, ast
::ExprKind
> {
2021 if end
.is_none() && limits
== RangeLimits
::Closed
{
2022 Err(self.span_fatal_err(self.span
, Error
::InclusiveRangeWithNoEnd
))
2024 Ok(ExprKind
::Range(start
, end
, limits
))
2028 pub fn mk_tup_field(&mut self, expr
: P
<Expr
>, idx
: codemap
::Spanned
<usize>) -> ast
::ExprKind
{
2029 ExprKind
::TupField(expr
, idx
)
2032 pub fn mk_assign_op(&mut self, binop
: ast
::BinOp
,
2033 lhs
: P
<Expr
>, rhs
: P
<Expr
>) -> ast
::ExprKind
{
2034 ExprKind
::AssignOp(binop
, lhs
, rhs
)
2037 pub fn mk_mac_expr(&mut self, span
: Span
, m
: Mac_
, attrs
: ThinVec
<Attribute
>) -> P
<Expr
> {
2039 id
: ast
::DUMMY_NODE_ID
,
2040 node
: ExprKind
::Mac(codemap
::Spanned {node: m, span: span}
),
2046 pub fn mk_lit_u32(&mut self, i
: u32, attrs
: ThinVec
<Attribute
>) -> P
<Expr
> {
2047 let span
= &self.span
;
2048 let lv_lit
= P(codemap
::Spanned
{
2049 node
: LitKind
::Int(i
as u128
, ast
::LitIntType
::Unsigned(UintTy
::U32
)),
2054 id
: ast
::DUMMY_NODE_ID
,
2055 node
: ExprKind
::Lit(lv_lit
),
2061 fn expect_delimited_token_tree(&mut self) -> PResult
<'a
, (token
::DelimToken
, ThinTokenStream
)> {
2063 token
::OpenDelim(delim
) => match self.parse_token_tree() {
2064 TokenTree
::Delimited(_
, delimited
) => Ok((delim
, delimited
.stream().into())),
2065 _
=> unreachable
!(),
2067 _
=> Err(self.fatal("expected open delimiter")),
2071 /// At the bottom (top?) of the precedence hierarchy,
2072 /// parse things like parenthesized exprs,
2073 /// macros, return, etc.
2075 /// NB: This does not parse outer attributes,
2076 /// and is private because it only works
2077 /// correctly if called from parse_dot_or_call_expr().
2078 fn parse_bottom_expr(&mut self) -> PResult
<'a
, P
<Expr
>> {
2079 maybe_whole_expr
!(self);
2081 // Outer attributes are already parsed and will be
2082 // added to the return value after the fact.
2084 // Therefore, prevent sub-parser from parsing
2085 // attributes by giving them a empty "already parsed" list.
2086 let mut attrs
= ThinVec
::new();
2089 let mut hi
= self.span
;
2093 // Note: when adding new syntax here, don't forget to adjust Token::can_begin_expr().
2095 token
::OpenDelim(token
::Paren
) => {
2098 attrs
.extend(self.parse_inner_attributes()?
);
2100 // (e) is parenthesized e
2101 // (e,) is a tuple with only one field, e
2102 let mut es
= vec
![];
2103 let mut trailing_comma
= false;
2104 while self.token
!= token
::CloseDelim(token
::Paren
) {
2105 es
.push(self.parse_expr()?
);
2106 self.expect_one_of(&[], &[token
::Comma
, token
::CloseDelim(token
::Paren
)])?
;
2107 if self.check(&token
::Comma
) {
2108 trailing_comma
= true;
2112 trailing_comma
= false;
2118 hi
= self.prev_span
;
2119 let span
= lo
.to(hi
);
2120 return if es
.len() == 1 && !trailing_comma
{
2121 Ok(self.mk_expr(span
, ExprKind
::Paren(es
.into_iter().nth(0).unwrap()), attrs
))
2123 Ok(self.mk_expr(span
, ExprKind
::Tup(es
), attrs
))
2126 token
::OpenDelim(token
::Brace
) => {
2127 return self.parse_block_expr(lo
, BlockCheckMode
::Default
, attrs
);
2129 token
::BinOp(token
::Or
) | token
::OrOr
=> {
2131 return self.parse_lambda_expr(lo
, CaptureBy
::Ref
, attrs
);
2133 token
::OpenDelim(token
::Bracket
) => {
2136 attrs
.extend(self.parse_inner_attributes()?
);
2138 if self.check(&token
::CloseDelim(token
::Bracket
)) {
2141 ex
= ExprKind
::Array(Vec
::new());
2144 let first_expr
= self.parse_expr()?
;
2145 if self.check(&token
::Semi
) {
2146 // Repeating array syntax: [ 0; 512 ]
2148 let count
= self.parse_expr()?
;
2149 self.expect(&token
::CloseDelim(token
::Bracket
))?
;
2150 ex
= ExprKind
::Repeat(first_expr
, count
);
2151 } else if self.check(&token
::Comma
) {
2152 // Vector with two or more elements.
2154 let remaining_exprs
= self.parse_seq_to_end(
2155 &token
::CloseDelim(token
::Bracket
),
2156 SeqSep
::trailing_allowed(token
::Comma
),
2157 |p
| Ok(p
.parse_expr()?
)
2159 let mut exprs
= vec
![first_expr
];
2160 exprs
.extend(remaining_exprs
);
2161 ex
= ExprKind
::Array(exprs
);
2163 // Vector with one element.
2164 self.expect(&token
::CloseDelim(token
::Bracket
))?
;
2165 ex
= ExprKind
::Array(vec
![first_expr
]);
2168 hi
= self.prev_span
;
2172 let (qself
, path
) = self.parse_qpath(PathStyle
::Expr
)?
;
2174 return Ok(self.mk_expr(lo
.to(hi
), ExprKind
::Path(Some(qself
), path
), attrs
));
2176 if self.eat_keyword(keywords
::Move
) {
2177 let lo
= self.prev_span
;
2178 return self.parse_lambda_expr(lo
, CaptureBy
::Value
, attrs
);
2180 if self.eat_keyword(keywords
::If
) {
2181 return self.parse_if_expr(attrs
);
2183 if self.eat_keyword(keywords
::For
) {
2184 let lo
= self.prev_span
;
2185 return self.parse_for_expr(None
, lo
, attrs
);
2187 if self.eat_keyword(keywords
::While
) {
2188 let lo
= self.prev_span
;
2189 return self.parse_while_expr(None
, lo
, attrs
);
2191 if self.token
.is_lifetime() {
2192 let label
= Spanned
{ node
: self.get_label(),
2196 self.expect(&token
::Colon
)?
;
2197 if self.eat_keyword(keywords
::While
) {
2198 return self.parse_while_expr(Some(label
), lo
, attrs
)
2200 if self.eat_keyword(keywords
::For
) {
2201 return self.parse_for_expr(Some(label
), lo
, attrs
)
2203 if self.eat_keyword(keywords
::Loop
) {
2204 return self.parse_loop_expr(Some(label
), lo
, attrs
)
2206 return Err(self.fatal("expected `while`, `for`, or `loop` after a label"))
2208 if self.eat_keyword(keywords
::Loop
) {
2209 let lo
= self.prev_span
;
2210 return self.parse_loop_expr(None
, lo
, attrs
);
2212 if self.eat_keyword(keywords
::Continue
) {
2213 let ex
= if self.token
.is_lifetime() {
2214 let ex
= ExprKind
::Continue(Some(Spanned
{
2215 node
: self.get_label(),
2221 ExprKind
::Continue(None
)
2223 let hi
= self.prev_span
;
2224 return Ok(self.mk_expr(lo
.to(hi
), ex
, attrs
));
2226 if self.eat_keyword(keywords
::Match
) {
2227 return self.parse_match_expr(attrs
);
2229 if self.eat_keyword(keywords
::Unsafe
) {
2230 return self.parse_block_expr(
2232 BlockCheckMode
::Unsafe(ast
::UserProvided
),
2235 if self.is_catch_expr() {
2237 assert
!(self.eat_keyword(keywords
::Do
));
2238 assert
!(self.eat_keyword(keywords
::Catch
));
2239 return self.parse_catch_expr(lo
, attrs
);
2241 if self.eat_keyword(keywords
::Return
) {
2242 if self.token
.can_begin_expr() {
2243 let e
= self.parse_expr()?
;
2245 ex
= ExprKind
::Ret(Some(e
));
2247 ex
= ExprKind
::Ret(None
);
2249 } else if self.eat_keyword(keywords
::Break
) {
2250 let lt
= if self.token
.is_lifetime() {
2251 let spanned_lt
= Spanned
{
2252 node
: self.get_label(),
2260 let e
= if self.token
.can_begin_expr()
2261 && !(self.token
== token
::OpenDelim(token
::Brace
)
2262 && self.restrictions
.contains(
2263 Restrictions
::NO_STRUCT_LITERAL
)) {
2264 Some(self.parse_expr()?
)
2268 ex
= ExprKind
::Break(lt
, e
);
2269 hi
= self.prev_span
;
2270 } else if self.eat_keyword(keywords
::Yield
) {
2271 if self.token
.can_begin_expr() {
2272 let e
= self.parse_expr()?
;
2274 ex
= ExprKind
::Yield(Some(e
));
2276 ex
= ExprKind
::Yield(None
);
2278 } else if self.token
.is_keyword(keywords
::Let
) {
2279 // Catch this syntax error here, instead of in `parse_ident`, so
2280 // that we can explicitly mention that let is not to be used as an expression
2281 let mut db
= self.fatal("expected expression, found statement (`let`)");
2282 db
.note("variable declaration using `let` is a statement");
2284 } else if self.token
.is_path_start() {
2285 let pth
= self.parse_path(PathStyle
::Expr
)?
;
2287 // `!`, as an operator, is prefix, so we know this isn't that
2288 if self.eat(&token
::Not
) {
2289 // MACRO INVOCATION expression
2290 let (_
, tts
) = self.expect_delimited_token_tree()?
;
2291 let hi
= self.prev_span
;
2292 return Ok(self.mk_mac_expr(lo
.to(hi
), Mac_ { path: pth, tts: tts }
, attrs
));
2294 if self.check(&token
::OpenDelim(token
::Brace
)) {
2295 // This is a struct literal, unless we're prohibited
2296 // from parsing struct literals here.
2297 let prohibited
= self.restrictions
.contains(
2298 Restrictions
::NO_STRUCT_LITERAL
2301 return self.parse_struct_expr(lo
, pth
, attrs
);
2306 ex
= ExprKind
::Path(None
, pth
);
2308 match self.parse_lit() {
2311 ex
= ExprKind
::Lit(P(lit
));
2314 self.cancel(&mut err
);
2315 let msg
= format
!("expected expression, found {}",
2316 self.this_token_descr());
2317 return Err(self.fatal(&msg
));
2324 return Ok(self.mk_expr(lo
.to(hi
), ex
, attrs
));
2327 fn parse_struct_expr(&mut self, lo
: Span
, pth
: ast
::Path
, mut attrs
: ThinVec
<Attribute
>)
2328 -> PResult
<'a
, P
<Expr
>> {
2330 let mut fields
= Vec
::new();
2331 let mut base
= None
;
2333 attrs
.extend(self.parse_inner_attributes()?
);
2335 while self.token
!= token
::CloseDelim(token
::Brace
) {
2336 if self.eat(&token
::DotDot
) {
2337 let exp_span
= self.prev_span
;
2338 match self.parse_expr() {
2344 self.recover_stmt();
2347 if self.token
== token
::Comma
{
2348 let mut err
= self.sess
.span_diagnostic
.mut_span_err(
2349 exp_span
.to(self.prev_span
),
2350 "cannot use a comma after the base struct",
2352 err
.span_suggestion_short(self.span
, "remove this comma", "".to_owned());
2353 err
.note("the base struct must always be the last field");
2355 self.recover_stmt();
2360 match self.parse_field() {
2361 Ok(f
) => fields
.push(f
),
2364 self.recover_stmt();
2369 match self.expect_one_of(&[token
::Comma
],
2370 &[token
::CloseDelim(token
::Brace
)]) {
2374 self.recover_stmt();
2380 let span
= lo
.to(self.span
);
2381 self.expect(&token
::CloseDelim(token
::Brace
))?
;
2382 return Ok(self.mk_expr(span
, ExprKind
::Struct(pth
, fields
, base
), attrs
));
2385 fn parse_or_use_outer_attributes(&mut self,
2386 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>)
2387 -> PResult
<'a
, ThinVec
<Attribute
>> {
2388 if let Some(attrs
) = already_parsed_attrs
{
2391 self.parse_outer_attributes().map(|a
| a
.into())
2395 /// Parse a block or unsafe block
2396 pub fn parse_block_expr(&mut self, lo
: Span
, blk_mode
: BlockCheckMode
,
2397 outer_attrs
: ThinVec
<Attribute
>)
2398 -> PResult
<'a
, P
<Expr
>> {
2399 self.expect(&token
::OpenDelim(token
::Brace
))?
;
2401 let mut attrs
= outer_attrs
;
2402 attrs
.extend(self.parse_inner_attributes()?
);
2404 let blk
= self.parse_block_tail(lo
, blk_mode
)?
;
2405 return Ok(self.mk_expr(blk
.span
, ExprKind
::Block(blk
), attrs
));
2408 /// parse a.b or a(13) or a[4] or just a
2409 pub fn parse_dot_or_call_expr(&mut self,
2410 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>)
2411 -> PResult
<'a
, P
<Expr
>> {
2412 let attrs
= self.parse_or_use_outer_attributes(already_parsed_attrs
)?
;
2414 let b
= self.parse_bottom_expr();
2415 let (span
, b
) = self.interpolated_or_expr_span(b
)?
;
2416 self.parse_dot_or_call_expr_with(b
, span
, attrs
)
2419 pub fn parse_dot_or_call_expr_with(&mut self,
2422 mut attrs
: ThinVec
<Attribute
>)
2423 -> PResult
<'a
, P
<Expr
>> {
2424 // Stitch the list of outer attributes onto the return value.
2425 // A little bit ugly, but the best way given the current code
2427 self.parse_dot_or_call_expr_with_(e0
, lo
)
2429 expr
.map(|mut expr
| {
2430 attrs
.extend
::<Vec
<_
>>(expr
.attrs
.into());
2433 ExprKind
::If(..) | ExprKind
::IfLet(..) => {
2434 if !expr
.attrs
.is_empty() {
2435 // Just point to the first attribute in there...
2436 let span
= expr
.attrs
[0].span
;
2439 "attributes are not yet allowed on `if` \
2450 // Assuming we have just parsed `.`, continue parsing into an expression.
2451 fn parse_dot_suffix(&mut self, self_arg
: P
<Expr
>, lo
: Span
) -> PResult
<'a
, P
<Expr
>> {
2452 let segment
= self.parse_path_segment(PathStyle
::Expr
, true)?
;
2453 Ok(match self.token
{
2454 token
::OpenDelim(token
::Paren
) => {
2455 // Method call `expr.f()`
2456 let mut args
= self.parse_unspanned_seq(
2457 &token
::OpenDelim(token
::Paren
),
2458 &token
::CloseDelim(token
::Paren
),
2459 SeqSep
::trailing_allowed(token
::Comma
),
2460 |p
| Ok(p
.parse_expr()?
)
2462 args
.insert(0, self_arg
);
2464 let span
= lo
.to(self.prev_span
);
2465 self.mk_expr(span
, ExprKind
::MethodCall(segment
, args
), ThinVec
::new())
2468 // Field access `expr.f`
2469 if let Some(parameters
) = segment
.parameters
{
2470 self.span_err(parameters
.span(),
2471 "field expressions may not have generic arguments");
2474 let span
= lo
.to(self.prev_span
);
2475 let ident
= respan(segment
.span
, segment
.identifier
);
2476 self.mk_expr(span
, ExprKind
::Field(self_arg
, ident
), ThinVec
::new())
2481 fn parse_dot_or_call_expr_with_(&mut self, e0
: P
<Expr
>, lo
: Span
) -> PResult
<'a
, P
<Expr
>> {
2486 while self.eat(&token
::Question
) {
2487 let hi
= self.prev_span
;
2488 e
= self.mk_expr(lo
.to(hi
), ExprKind
::Try(e
), ThinVec
::new());
2492 if self.eat(&token
::Dot
) {
2494 token
::Ident(..) => {
2495 e
= self.parse_dot_suffix(e
, lo
)?
;
2497 token
::Literal(token
::Integer(n
), suf
) => {
2500 // A tuple index may not have a suffix
2501 self.expect_no_suffix(sp
, "tuple index", suf
);
2503 let dot_span
= self.prev_span
;
2507 let index
= n
.as_str().parse
::<usize>().ok();
2510 let id
= respan(dot_span
.to(hi
), n
);
2511 let field
= self.mk_tup_field(e
, id
);
2512 e
= self.mk_expr(lo
.to(hi
), field
, ThinVec
::new());
2515 let prev_span
= self.prev_span
;
2516 self.span_err(prev_span
, "invalid tuple or tuple struct index");
2520 token
::Literal(token
::Float(n
), _suf
) => {
2522 let fstr
= n
.as_str();
2523 let mut err
= self.diagnostic().struct_span_err(self.prev_span
,
2524 &format
!("unexpected token: `{}`", n
));
2525 err
.span_label(self.prev_span
, "unexpected token");
2526 if fstr
.chars().all(|x
| "0123456789.".contains(x
)) {
2527 let float
= match fstr
.parse
::<f64>().ok() {
2531 let sugg
= pprust
::to_string(|s
| {
2532 use print
::pprust
::PrintState
;
2536 s
.print_usize(float
.trunc() as usize)?
;
2539 s
.s
.word(fstr
.splitn(2, ".").last().unwrap())
2541 err
.span_suggestion(
2542 lo
.to(self.prev_span
),
2543 "try parenthesizing the first index",
2550 // FIXME Could factor this out into non_fatal_unexpected or something.
2551 let actual
= self.this_token_to_string();
2552 self.span_err(self.span
, &format
!("unexpected token: `{}`", actual
));
2557 if self.expr_is_complete(&e
) { break; }
2560 token
::OpenDelim(token
::Paren
) => {
2561 let es
= self.parse_unspanned_seq(
2562 &token
::OpenDelim(token
::Paren
),
2563 &token
::CloseDelim(token
::Paren
),
2564 SeqSep
::trailing_allowed(token
::Comma
),
2565 |p
| Ok(p
.parse_expr()?
)
2567 hi
= self.prev_span
;
2569 let nd
= self.mk_call(e
, es
);
2570 e
= self.mk_expr(lo
.to(hi
), nd
, ThinVec
::new());
2574 // Could be either an index expression or a slicing expression.
2575 token
::OpenDelim(token
::Bracket
) => {
2577 let ix
= self.parse_expr()?
;
2579 self.expect(&token
::CloseDelim(token
::Bracket
))?
;
2580 let index
= self.mk_index(e
, ix
);
2581 e
= self.mk_expr(lo
.to(hi
), index
, ThinVec
::new())
2589 pub fn process_potential_macro_variable(&mut self) {
2590 let ident
= match self.token
{
2591 token
::Dollar
if self.span
.ctxt() != syntax_pos
::hygiene
::SyntaxContext
::empty() &&
2592 self.look_ahead(1, |t
| t
.is_ident()) => {
2594 let name
= match self.token { token::Ident(ident) => ident, _ => unreachable!() }
;
2595 self.fatal(&format
!("unknown macro variable `{}`", name
)).emit();
2598 token
::Interpolated(ref nt
) => {
2599 self.meta_var_span
= Some(self.span
);
2601 token
::NtIdent(ident
) => ident
,
2607 self.token
= token
::Ident(ident
.node
);
2608 self.span
= ident
.span
;
2611 /// parse a single token tree from the input.
2612 pub fn parse_token_tree(&mut self) -> TokenTree
{
2614 token
::OpenDelim(..) => {
2615 let frame
= mem
::replace(&mut self.token_cursor
.frame
,
2616 self.token_cursor
.stack
.pop().unwrap());
2617 self.span
= frame
.span
;
2619 TokenTree
::Delimited(frame
.span
, Delimited
{
2621 tts
: frame
.tree_cursor
.original_stream().into(),
2624 token
::CloseDelim(_
) | token
::Eof
=> unreachable
!(),
2626 let (token
, span
) = (mem
::replace(&mut self.token
, token
::Underscore
), self.span
);
2628 TokenTree
::Token(span
, token
)
2633 // parse a stream of tokens into a list of TokenTree's,
2635 pub fn parse_all_token_trees(&mut self) -> PResult
<'a
, Vec
<TokenTree
>> {
2636 let mut tts
= Vec
::new();
2637 while self.token
!= token
::Eof
{
2638 tts
.push(self.parse_token_tree());
2643 pub fn parse_tokens(&mut self) -> TokenStream
{
2644 let mut result
= Vec
::new();
2647 token
::Eof
| token
::CloseDelim(..) => break,
2648 _
=> result
.push(self.parse_token_tree().into()),
2651 TokenStream
::concat(result
)
2654 /// Parse a prefix-unary-operator expr
2655 pub fn parse_prefix_expr(&mut self,
2656 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>)
2657 -> PResult
<'a
, P
<Expr
>> {
2658 let attrs
= self.parse_or_use_outer_attributes(already_parsed_attrs
)?
;
2660 // Note: when adding new unary operators, don't forget to adjust Token::can_begin_expr()
2661 let (hi
, ex
) = match self.token
{
2664 let e
= self.parse_prefix_expr(None
);
2665 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
2666 (lo
.to(span
), self.mk_unary(UnOp
::Not
, e
))
2668 // Suggest `!` for bitwise negation when encountering a `~`
2671 let e
= self.parse_prefix_expr(None
);
2672 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
2673 let span_of_tilde
= lo
;
2674 let mut err
= self.diagnostic().struct_span_err(span_of_tilde
,
2675 "`~` can not be used as a unary operator");
2676 err
.span_label(span_of_tilde
, "did you mean `!`?");
2677 err
.help("use `!` instead of `~` if you meant to perform bitwise negation");
2679 (lo
.to(span
), self.mk_unary(UnOp
::Not
, e
))
2681 token
::BinOp(token
::Minus
) => {
2683 let e
= self.parse_prefix_expr(None
);
2684 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
2685 (lo
.to(span
), self.mk_unary(UnOp
::Neg
, e
))
2687 token
::BinOp(token
::Star
) => {
2689 let e
= self.parse_prefix_expr(None
);
2690 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
2691 (lo
.to(span
), self.mk_unary(UnOp
::Deref
, e
))
2693 token
::BinOp(token
::And
) | token
::AndAnd
=> {
2695 let m
= self.parse_mutability();
2696 let e
= self.parse_prefix_expr(None
);
2697 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
2698 (lo
.to(span
), ExprKind
::AddrOf(m
, e
))
2700 token
::Ident(..) if self.token
.is_keyword(keywords
::In
) => {
2702 let place
= self.parse_expr_res(
2703 Restrictions
::NO_STRUCT_LITERAL
,
2706 let blk
= self.parse_block()?
;
2707 let span
= blk
.span
;
2708 let blk_expr
= self.mk_expr(span
, ExprKind
::Block(blk
), ThinVec
::new());
2709 (lo
.to(span
), ExprKind
::InPlace(place
, blk_expr
))
2711 token
::Ident(..) if self.token
.is_keyword(keywords
::Box
) => {
2713 let e
= self.parse_prefix_expr(None
);
2714 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
2715 (lo
.to(span
), ExprKind
::Box(e
))
2717 _
=> return self.parse_dot_or_call_expr(Some(attrs
))
2719 return Ok(self.mk_expr(lo
.to(hi
), ex
, attrs
));
2722 /// Parse an associative expression
2724 /// This parses an expression accounting for associativity and precedence of the operators in
2726 pub fn parse_assoc_expr(&mut self,
2727 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>)
2728 -> PResult
<'a
, P
<Expr
>> {
2729 self.parse_assoc_expr_with(0, already_parsed_attrs
.into())
2732 /// Parse an associative expression with operators of at least `min_prec` precedence
2733 pub fn parse_assoc_expr_with(&mut self,
2736 -> PResult
<'a
, P
<Expr
>> {
2737 let mut lhs
= if let LhsExpr
::AlreadyParsed(expr
) = lhs
{
2740 let attrs
= match lhs
{
2741 LhsExpr
::AttributesParsed(attrs
) => Some(attrs
),
2744 if [token
::DotDot
, token
::DotDotDot
, token
::DotDotEq
].contains(&self.token
) {
2745 return self.parse_prefix_range_expr(attrs
);
2747 self.parse_prefix_expr(attrs
)?
2751 if self.expr_is_complete(&lhs
) {
2752 // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
2755 self.expected_tokens
.push(TokenType
::Operator
);
2756 while let Some(op
) = AssocOp
::from_token(&self.token
) {
2758 // Adjust the span for interpolated LHS to point to the `$lhs` token and not to what
2759 // it refers to. Interpolated identifiers are unwrapped early and never show up here
2760 // as `PrevTokenKind::Interpolated` so if LHS is a single identifier we always process
2761 // it as "interpolated", it doesn't change the answer for non-interpolated idents.
2762 let lhs_span
= match (self.prev_token_kind
, &lhs
.node
) {
2763 (PrevTokenKind
::Interpolated
, _
) => self.prev_span
,
2764 (PrevTokenKind
::Ident
, &ExprKind
::Path(None
, ref path
))
2765 if path
.segments
.len() == 1 => self.prev_span
,
2769 let cur_op_span
= self.span
;
2770 let restrictions
= if op
.is_assign_like() {
2771 self.restrictions
& Restrictions
::NO_STRUCT_LITERAL
2775 if op
.precedence() < min_prec
{
2778 // Check for deprecated `...` syntax
2779 if self.token
== token
::DotDotDot
&& op
== AssocOp
::DotDotEq
{
2780 self.err_dotdotdot_syntax(self.span
);
2784 if op
.is_comparison() {
2785 self.check_no_chained_comparison(&lhs
, &op
);
2788 if op
== AssocOp
::As
{
2789 lhs
= self.parse_assoc_op_cast(lhs
, lhs_span
, ExprKind
::Cast
)?
;
2791 } else if op
== AssocOp
::Colon
{
2792 lhs
= match self.parse_assoc_op_cast(lhs
, lhs_span
, ExprKind
::Type
) {
2795 err
.span_label(self.span
,
2796 "expecting a type here because of type ascription");
2797 let cm
= self.sess
.codemap();
2798 let cur_pos
= cm
.lookup_char_pos(self.span
.lo());
2799 let op_pos
= cm
.lookup_char_pos(cur_op_span
.hi());
2800 if cur_pos
.line
!= op_pos
.line
{
2801 err
.span_suggestion_short(cur_op_span
,
2802 "did you mean to use `;` here?",
2809 } else if op
== AssocOp
::DotDot
|| op
== AssocOp
::DotDotEq
{
2810 // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
2811 // generalise it to the Fixity::None code.
2813 // We have 2 alternatives here: `x..y`/`x..=y` and `x..`/`x..=` The other
2814 // two variants are handled with `parse_prefix_range_expr` call above.
2815 let rhs
= if self.is_at_start_of_range_notation_rhs() {
2816 Some(self.parse_assoc_expr_with(op
.precedence() + 1,
2817 LhsExpr
::NotYetParsed
)?
)
2821 let (lhs_span
, rhs_span
) = (lhs
.span
, if let Some(ref x
) = rhs
{
2826 let limits
= if op
== AssocOp
::DotDot
{
2827 RangeLimits
::HalfOpen
2832 let r
= try
!(self.mk_range(Some(lhs
), rhs
, limits
));
2833 lhs
= self.mk_expr(lhs_span
.to(rhs_span
), r
, ThinVec
::new());
2837 let rhs
= match op
.fixity() {
2838 Fixity
::Right
=> self.with_res(
2839 restrictions
- Restrictions
::STMT_EXPR
,
2841 this
.parse_assoc_expr_with(op
.precedence(),
2842 LhsExpr
::NotYetParsed
)
2844 Fixity
::Left
=> self.with_res(
2845 restrictions
- Restrictions
::STMT_EXPR
,
2847 this
.parse_assoc_expr_with(op
.precedence() + 1,
2848 LhsExpr
::NotYetParsed
)
2850 // We currently have no non-associative operators that are not handled above by
2851 // the special cases. The code is here only for future convenience.
2852 Fixity
::None
=> self.with_res(
2853 restrictions
- Restrictions
::STMT_EXPR
,
2855 this
.parse_assoc_expr_with(op
.precedence() + 1,
2856 LhsExpr
::NotYetParsed
)
2860 let span
= lhs_span
.to(rhs
.span
);
2862 AssocOp
::Add
| AssocOp
::Subtract
| AssocOp
::Multiply
| AssocOp
::Divide
|
2863 AssocOp
::Modulus
| AssocOp
::LAnd
| AssocOp
::LOr
| AssocOp
::BitXor
|
2864 AssocOp
::BitAnd
| AssocOp
::BitOr
| AssocOp
::ShiftLeft
| AssocOp
::ShiftRight
|
2865 AssocOp
::Equal
| AssocOp
::Less
| AssocOp
::LessEqual
| AssocOp
::NotEqual
|
2866 AssocOp
::Greater
| AssocOp
::GreaterEqual
=> {
2867 let ast_op
= op
.to_ast_binop().unwrap();
2868 let binary
= self.mk_binary(codemap
::respan(cur_op_span
, ast_op
), lhs
, rhs
);
2869 self.mk_expr(span
, binary
, ThinVec
::new())
2872 self.mk_expr(span
, ExprKind
::Assign(lhs
, rhs
), ThinVec
::new()),
2874 self.mk_expr(span
, ExprKind
::InPlace(lhs
, rhs
), ThinVec
::new()),
2875 AssocOp
::AssignOp(k
) => {
2877 token
::Plus
=> BinOpKind
::Add
,
2878 token
::Minus
=> BinOpKind
::Sub
,
2879 token
::Star
=> BinOpKind
::Mul
,
2880 token
::Slash
=> BinOpKind
::Div
,
2881 token
::Percent
=> BinOpKind
::Rem
,
2882 token
::Caret
=> BinOpKind
::BitXor
,
2883 token
::And
=> BinOpKind
::BitAnd
,
2884 token
::Or
=> BinOpKind
::BitOr
,
2885 token
::Shl
=> BinOpKind
::Shl
,
2886 token
::Shr
=> BinOpKind
::Shr
,
2888 let aopexpr
= self.mk_assign_op(codemap
::respan(cur_op_span
, aop
), lhs
, rhs
);
2889 self.mk_expr(span
, aopexpr
, ThinVec
::new())
2891 AssocOp
::As
| AssocOp
::Colon
| AssocOp
::DotDot
| AssocOp
::DotDotEq
=> {
2892 self.bug("AssocOp should have been handled by special case")
2896 if op
.fixity() == Fixity
::None { break }
2901 fn parse_assoc_op_cast(&mut self, lhs
: P
<Expr
>, lhs_span
: Span
,
2902 expr_kind
: fn(P
<Expr
>, P
<Ty
>) -> ExprKind
)
2903 -> PResult
<'a
, P
<Expr
>> {
2904 let mk_expr
= |this
: &mut Self, rhs
: P
<Ty
>| {
2905 this
.mk_expr(lhs_span
.to(rhs
.span
), expr_kind(lhs
, rhs
), ThinVec
::new())
2908 // Save the state of the parser before parsing type normally, in case there is a
2909 // LessThan comparison after this cast.
2910 let parser_snapshot_before_type
= self.clone();
2911 match self.parse_ty_no_plus() {
2913 Ok(mk_expr(self, rhs
))
2915 Err(mut type_err
) => {
2916 // Rewind to before attempting to parse the type with generics, to recover
2917 // from situations like `x as usize < y` in which we first tried to parse
2918 // `usize < y` as a type with generic arguments.
2919 let parser_snapshot_after_type
= self.clone();
2920 mem
::replace(self, parser_snapshot_before_type
);
2922 match self.parse_path(PathStyle
::Expr
) {
2924 let (op_noun
, op_verb
) = match self.token
{
2925 token
::Lt
=> ("comparison", "comparing"),
2926 token
::BinOp(token
::Shl
) => ("shift", "shifting"),
2928 // We can end up here even without `<` being the next token, for
2929 // example because `parse_ty_no_plus` returns `Err` on keywords,
2930 // but `parse_path` returns `Ok` on them due to error recovery.
2931 // Return original error and parser state.
2932 mem
::replace(self, parser_snapshot_after_type
);
2933 return Err(type_err
);
2937 // Successfully parsed the type path leaving a `<` yet to parse.
2940 // Report non-fatal diagnostics, keep `x as usize` as an expression
2941 // in AST and continue parsing.
2942 let msg
= format
!("`<` is interpreted as a start of generic \
2943 arguments for `{}`, not a {}", path
, op_noun
);
2944 let mut err
= self.sess
.span_diagnostic
.struct_span_err(self.span
, &msg
);
2945 err
.span_label(self.look_ahead_span(1).to(parser_snapshot_after_type
.span
),
2946 "interpreted as generic arguments");
2947 err
.span_label(self.span
, format
!("not interpreted as {}", op_noun
));
2949 let expr
= mk_expr(self, P(Ty
{
2951 node
: TyKind
::Path(None
, path
),
2952 id
: ast
::DUMMY_NODE_ID
2955 let expr_str
= self.sess
.codemap().span_to_snippet(expr
.span
)
2956 .unwrap_or(pprust
::expr_to_string(&expr
));
2957 err
.span_suggestion(expr
.span
,
2958 &format
!("try {} the casted value", op_verb
),
2959 format
!("({})", expr_str
));
2964 Err(mut path_err
) => {
2965 // Couldn't parse as a path, return original error and parser state.
2967 mem
::replace(self, parser_snapshot_after_type
);
2975 /// Produce an error if comparison operators are chained (RFC #558).
2976 /// We only need to check lhs, not rhs, because all comparison ops
2977 /// have same precedence and are left-associative
2978 fn check_no_chained_comparison(&mut self, lhs
: &Expr
, outer_op
: &AssocOp
) {
2979 debug_assert
!(outer_op
.is_comparison(),
2980 "check_no_chained_comparison: {:?} is not comparison",
2983 ExprKind
::Binary(op
, _
, _
) if op
.node
.is_comparison() => {
2984 // respan to include both operators
2985 let op_span
= op
.span
.to(self.span
);
2986 let mut err
= self.diagnostic().struct_span_err(op_span
,
2987 "chained comparison operators require parentheses");
2988 if op
.node
== BinOpKind
::Lt
&&
2989 *outer_op
== AssocOp
::Less
|| // Include `<` to provide this recommendation
2990 *outer_op
== AssocOp
::Greater
// even in a case like the following:
2991 { // Foo<Bar<Baz<Qux, ()>>>
2993 "use `::<...>` instead of `<...>` if you meant to specify type arguments");
2994 err
.help("or use `(...)` if you meant to specify fn arguments");
3002 /// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr`
3003 fn parse_prefix_range_expr(&mut self,
3004 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>)
3005 -> PResult
<'a
, P
<Expr
>> {
3006 // Check for deprecated `...` syntax
3007 if self.token
== token
::DotDotDot
{
3008 self.err_dotdotdot_syntax(self.span
);
3011 debug_assert
!([token
::DotDot
, token
::DotDotDot
, token
::DotDotEq
].contains(&self.token
),
3012 "parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq",
3014 let tok
= self.token
.clone();
3015 let attrs
= self.parse_or_use_outer_attributes(already_parsed_attrs
)?
;
3017 let mut hi
= self.span
;
3019 let opt_end
= if self.is_at_start_of_range_notation_rhs() {
3020 // RHS must be parsed with more associativity than the dots.
3021 let next_prec
= AssocOp
::from_token(&tok
).unwrap().precedence() + 1;
3022 Some(self.parse_assoc_expr_with(next_prec
,
3023 LhsExpr
::NotYetParsed
)
3031 let limits
= if tok
== token
::DotDot
{
3032 RangeLimits
::HalfOpen
3037 let r
= try
!(self.mk_range(None
,
3040 Ok(self.mk_expr(lo
.to(hi
), r
, attrs
))
3043 fn is_at_start_of_range_notation_rhs(&self) -> bool
{
3044 if self.token
.can_begin_expr() {
3045 // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
3046 if self.token
== token
::OpenDelim(token
::Brace
) {
3047 return !self.restrictions
.contains(Restrictions
::NO_STRUCT_LITERAL
);
3055 /// Parse an 'if' or 'if let' expression ('if' token already eaten)
3056 pub fn parse_if_expr(&mut self, attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
3057 if self.check_keyword(keywords
::Let
) {
3058 return self.parse_if_let_expr(attrs
);
3060 let lo
= self.prev_span
;
3061 let cond
= self.parse_expr_res(Restrictions
::NO_STRUCT_LITERAL
, None
)?
;
3063 // Verify that the parsed `if` condition makes sense as a condition. If it is a block, then
3064 // verify that the last statement is either an implicit return (no `;`) or an explicit
3065 // return. This won't catch blocks with an explicit `return`, but that would be caught by
3066 // the dead code lint.
3067 if self.eat_keyword(keywords
::Else
) || !cond
.returns() {
3068 let sp
= lo
.next_point();
3069 let mut err
= self.diagnostic()
3070 .struct_span_err(sp
, "missing condition for `if` statemement");
3071 err
.span_label(sp
, "expected if condition here");
3074 let thn
= self.parse_block()?
;
3075 let mut els
: Option
<P
<Expr
>> = None
;
3076 let mut hi
= thn
.span
;
3077 if self.eat_keyword(keywords
::Else
) {
3078 let elexpr
= self.parse_else_expr()?
;
3082 Ok(self.mk_expr(lo
.to(hi
), ExprKind
::If(cond
, thn
, els
), attrs
))
3085 /// Parse an 'if let' expression ('if' token already eaten)
3086 pub fn parse_if_let_expr(&mut self, attrs
: ThinVec
<Attribute
>)
3087 -> PResult
<'a
, P
<Expr
>> {
3088 let lo
= self.prev_span
;
3089 self.expect_keyword(keywords
::Let
)?
;
3090 let pat
= self.parse_pat()?
;
3091 self.expect(&token
::Eq
)?
;
3092 let expr
= self.parse_expr_res(Restrictions
::NO_STRUCT_LITERAL
, None
)?
;
3093 let thn
= self.parse_block()?
;
3094 let (hi
, els
) = if self.eat_keyword(keywords
::Else
) {
3095 let expr
= self.parse_else_expr()?
;
3096 (expr
.span
, Some(expr
))
3100 Ok(self.mk_expr(lo
.to(hi
), ExprKind
::IfLet(pat
, expr
, thn
, els
), attrs
))
3103 // `move |args| expr`
3104 pub fn parse_lambda_expr(&mut self,
3106 capture_clause
: CaptureBy
,
3107 attrs
: ThinVec
<Attribute
>)
3108 -> PResult
<'a
, P
<Expr
>>
3110 let decl
= self.parse_fn_block_decl()?
;
3111 let decl_hi
= self.prev_span
;
3112 let body
= match decl
.output
{
3113 FunctionRetTy
::Default(_
) => {
3114 let restrictions
= self.restrictions
- Restrictions
::STMT_EXPR
;
3115 self.parse_expr_res(restrictions
, None
)?
3118 // If an explicit return type is given, require a
3119 // block to appear (RFC 968).
3120 let body_lo
= self.span
;
3121 self.parse_block_expr(body_lo
, BlockCheckMode
::Default
, ThinVec
::new())?
3127 ExprKind
::Closure(capture_clause
, decl
, body
, lo
.to(decl_hi
)),
3131 // `else` token already eaten
3132 pub fn parse_else_expr(&mut self) -> PResult
<'a
, P
<Expr
>> {
3133 if self.eat_keyword(keywords
::If
) {
3134 return self.parse_if_expr(ThinVec
::new());
3136 let blk
= self.parse_block()?
;
3137 return Ok(self.mk_expr(blk
.span
, ExprKind
::Block(blk
), ThinVec
::new()));
3141 /// Parse a 'for' .. 'in' expression ('for' token already eaten)
3142 pub fn parse_for_expr(&mut self, opt_ident
: Option
<ast
::SpannedIdent
>,
3144 mut attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
3145 // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
3147 let pat
= self.parse_pat()?
;
3148 if !self.eat_keyword(keywords
::In
) {
3149 let in_span
= self.prev_span
.between(self.span
);
3150 let mut err
= self.sess
.span_diagnostic
3151 .struct_span_err(in_span
, "missing `in` in `for` loop");
3152 err
.span_suggestion_short(in_span
, "try adding `in` here", " in ".into());
3155 let expr
= self.parse_expr_res(Restrictions
::NO_STRUCT_LITERAL
, None
)?
;
3156 let (iattrs
, loop_block
) = self.parse_inner_attrs_and_block()?
;
3157 attrs
.extend(iattrs
);
3159 let hi
= self.prev_span
;
3160 Ok(self.mk_expr(span_lo
.to(hi
), ExprKind
::ForLoop(pat
, expr
, loop_block
, opt_ident
), attrs
))
3163 /// Parse a 'while' or 'while let' expression ('while' token already eaten)
3164 pub fn parse_while_expr(&mut self, opt_ident
: Option
<ast
::SpannedIdent
>,
3166 mut attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
3167 if self.token
.is_keyword(keywords
::Let
) {
3168 return self.parse_while_let_expr(opt_ident
, span_lo
, attrs
);
3170 let cond
= self.parse_expr_res(Restrictions
::NO_STRUCT_LITERAL
, None
)?
;
3171 let (iattrs
, body
) = self.parse_inner_attrs_and_block()?
;
3172 attrs
.extend(iattrs
);
3173 let span
= span_lo
.to(body
.span
);
3174 return Ok(self.mk_expr(span
, ExprKind
::While(cond
, body
, opt_ident
), attrs
));
3177 /// Parse a 'while let' expression ('while' token already eaten)
3178 pub fn parse_while_let_expr(&mut self, opt_ident
: Option
<ast
::SpannedIdent
>,
3180 mut attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
3181 self.expect_keyword(keywords
::Let
)?
;
3182 let pat
= self.parse_pat()?
;
3183 self.expect(&token
::Eq
)?
;
3184 let expr
= self.parse_expr_res(Restrictions
::NO_STRUCT_LITERAL
, None
)?
;
3185 let (iattrs
, body
) = self.parse_inner_attrs_and_block()?
;
3186 attrs
.extend(iattrs
);
3187 let span
= span_lo
.to(body
.span
);
3188 return Ok(self.mk_expr(span
, ExprKind
::WhileLet(pat
, expr
, body
, opt_ident
), attrs
));
3191 // parse `loop {...}`, `loop` token already eaten
3192 pub fn parse_loop_expr(&mut self, opt_ident
: Option
<ast
::SpannedIdent
>,
3194 mut attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
3195 let (iattrs
, body
) = self.parse_inner_attrs_and_block()?
;
3196 attrs
.extend(iattrs
);
3197 let span
= span_lo
.to(body
.span
);
3198 Ok(self.mk_expr(span
, ExprKind
::Loop(body
, opt_ident
), attrs
))
3201 /// Parse a `do catch {...}` expression (`do catch` token already eaten)
3202 pub fn parse_catch_expr(&mut self, span_lo
: Span
, mut attrs
: ThinVec
<Attribute
>)
3203 -> PResult
<'a
, P
<Expr
>>
3205 let (iattrs
, body
) = self.parse_inner_attrs_and_block()?
;
3206 attrs
.extend(iattrs
);
3207 Ok(self.mk_expr(span_lo
.to(body
.span
), ExprKind
::Catch(body
), attrs
))
3210 // `match` token already eaten
3211 fn parse_match_expr(&mut self, mut attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
3212 let match_span
= self.prev_span
;
3213 let lo
= self.prev_span
;
3214 let discriminant
= self.parse_expr_res(Restrictions
::NO_STRUCT_LITERAL
,
3216 if let Err(mut e
) = self.expect(&token
::OpenDelim(token
::Brace
)) {
3217 if self.token
== token
::Token
::Semi
{
3218 e
.span_note(match_span
, "did you mean to remove this `match` keyword?");
3222 attrs
.extend(self.parse_inner_attributes()?
);
3224 let mut arms
: Vec
<Arm
> = Vec
::new();
3225 while self.token
!= token
::CloseDelim(token
::Brace
) {
3226 match self.parse_arm() {
3227 Ok(arm
) => arms
.push(arm
),
3229 // Recover by skipping to the end of the block.
3231 self.recover_stmt();
3232 let span
= lo
.to(self.span
);
3233 if self.token
== token
::CloseDelim(token
::Brace
) {
3236 return Ok(self.mk_expr(span
, ExprKind
::Match(discriminant
, arms
), attrs
));
3242 return Ok(self.mk_expr(lo
.to(hi
), ExprKind
::Match(discriminant
, arms
), attrs
));
3245 pub fn parse_arm(&mut self) -> PResult
<'a
, Arm
> {
3246 maybe_whole
!(self, NtArm
, |x
| x
);
3248 let attrs
= self.parse_outer_attributes()?
;
3249 // Allow a '|' before the pats (RFC 1925)
3250 let beginning_vert
= if self.eat(&token
::BinOp(token
::Or
)) {
3251 Some(self.prev_span
)
3255 let pats
= self.parse_pats()?
;
3256 let guard
= if self.eat_keyword(keywords
::If
) {
3257 Some(self.parse_expr()?
)
3261 self.expect(&token
::FatArrow
)?
;
3262 let expr
= self.parse_expr_res(Restrictions
::STMT_EXPR
, None
)?
;
3264 let require_comma
= classify
::expr_requires_semi_to_be_stmt(&expr
)
3265 && self.token
!= token
::CloseDelim(token
::Brace
);
3268 self.expect_one_of(&[token
::Comma
], &[token
::CloseDelim(token
::Brace
)])?
;
3270 self.eat(&token
::Comma
);
3282 /// Parse an expression
3283 pub fn parse_expr(&mut self) -> PResult
<'a
, P
<Expr
>> {
3284 self.parse_expr_res(Restrictions
::empty(), None
)
3287 /// Evaluate the closure with restrictions in place.
3289 /// After the closure is evaluated, restrictions are reset.
3290 pub fn with_res
<F
, T
>(&mut self, r
: Restrictions
, f
: F
) -> T
3291 where F
: FnOnce(&mut Self) -> T
3293 let old
= self.restrictions
;
3294 self.restrictions
= r
;
3296 self.restrictions
= old
;
3301 /// Parse an expression, subject to the given restrictions
3302 pub fn parse_expr_res(&mut self, r
: Restrictions
,
3303 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>)
3304 -> PResult
<'a
, P
<Expr
>> {
3305 self.with_res(r
, |this
| this
.parse_assoc_expr(already_parsed_attrs
))
3308 /// Parse the RHS of a local variable declaration (e.g. '= 14;')
3309 fn parse_initializer(&mut self, skip_eq
: bool
) -> PResult
<'a
, Option
<P
<Expr
>>> {
3310 if self.check(&token
::Eq
) {
3312 Ok(Some(self.parse_expr()?
))
3314 Ok(Some(self.parse_expr()?
))
3320 /// Parse patterns, separated by '|' s
3321 fn parse_pats(&mut self) -> PResult
<'a
, Vec
<P
<Pat
>>> {
3322 let mut pats
= Vec
::new();
3324 pats
.push(self.parse_pat()?
);
3325 if self.check(&token
::BinOp(token
::Or
)) { self.bump();}
3326 else { return Ok(pats); }
3330 fn parse_pat_tuple_elements(&mut self, unary_needs_comma
: bool
)
3331 -> PResult
<'a
, (Vec
<P
<Pat
>>, Option
<usize>)> {
3332 let mut fields
= vec
![];
3333 let mut ddpos
= None
;
3335 while !self.check(&token
::CloseDelim(token
::Paren
)) {
3336 if ddpos
.is_none() && self.eat(&token
::DotDot
) {
3337 ddpos
= Some(fields
.len());
3338 if self.eat(&token
::Comma
) {
3339 // `..` needs to be followed by `)` or `, pat`, `..,)` is disallowed.
3340 fields
.push(self.parse_pat()?
);
3342 } else if ddpos
.is_some() && self.eat(&token
::DotDot
) {
3343 // Emit a friendly error, ignore `..` and continue parsing
3344 self.span_err(self.prev_span
, "`..` can only be used once per \
3345 tuple or tuple struct pattern");
3347 fields
.push(self.parse_pat()?
);
3350 if !self.check(&token
::CloseDelim(token
::Paren
)) ||
3351 (unary_needs_comma
&& fields
.len() == 1 && ddpos
.is_none()) {
3352 self.expect(&token
::Comma
)?
;
3359 fn parse_pat_vec_elements(
3361 ) -> PResult
<'a
, (Vec
<P
<Pat
>>, Option
<P
<Pat
>>, Vec
<P
<Pat
>>)> {
3362 let mut before
= Vec
::new();
3363 let mut slice
= None
;
3364 let mut after
= Vec
::new();
3365 let mut first
= true;
3366 let mut before_slice
= true;
3368 while self.token
!= token
::CloseDelim(token
::Bracket
) {
3372 self.expect(&token
::Comma
)?
;
3374 if self.token
== token
::CloseDelim(token
::Bracket
)
3375 && (before_slice
|| !after
.is_empty()) {
3381 if self.eat(&token
::DotDot
) {
3383 if self.check(&token
::Comma
) ||
3384 self.check(&token
::CloseDelim(token
::Bracket
)) {
3385 slice
= Some(P(ast
::Pat
{
3386 id
: ast
::DUMMY_NODE_ID
,
3387 node
: PatKind
::Wild
,
3390 before_slice
= false;
3396 let subpat
= self.parse_pat()?
;
3397 if before_slice
&& self.eat(&token
::DotDot
) {
3398 slice
= Some(subpat
);
3399 before_slice
= false;
3400 } else if before_slice
{
3401 before
.push(subpat
);
3407 Ok((before
, slice
, after
))
3410 /// Parse the fields of a struct-like pattern
3411 fn parse_pat_fields(&mut self) -> PResult
<'a
, (Vec
<codemap
::Spanned
<ast
::FieldPat
>>, bool
)> {
3412 let mut fields
= Vec
::new();
3413 let mut etc
= false;
3414 let mut first
= true;
3415 while self.token
!= token
::CloseDelim(token
::Brace
) {
3419 self.expect(&token
::Comma
)?
;
3420 // accept trailing commas
3421 if self.check(&token
::CloseDelim(token
::Brace
)) { break }
3424 let attrs
= self.parse_outer_attributes()?
;
3428 if self.check(&token
::DotDot
) {
3430 if self.token
!= token
::CloseDelim(token
::Brace
) {
3431 let token_str
= self.this_token_to_string();
3432 return Err(self.fatal(&format
!("expected `{}`, found `{}`", "}",
3439 // Check if a colon exists one ahead. This means we're parsing a fieldname.
3440 let (subpat
, fieldname
, is_shorthand
) = if self.look_ahead(1, |t
| t
== &token
::Colon
) {
3441 // Parsing a pattern of the form "fieldname: pat"
3442 let fieldname
= self.parse_field_name()?
;
3444 let pat
= self.parse_pat()?
;
3446 (pat
, fieldname
, false)
3448 // Parsing a pattern of the form "(box) (ref) (mut) fieldname"
3449 let is_box
= self.eat_keyword(keywords
::Box
);
3450 let boxed_span
= self.span
;
3451 let is_ref
= self.eat_keyword(keywords
::Ref
);
3452 let is_mut
= self.eat_keyword(keywords
::Mut
);
3453 let fieldname
= self.parse_ident()?
;
3454 hi
= self.prev_span
;
3456 let bind_type
= match (is_ref
, is_mut
) {
3457 (true, true) => BindingMode
::ByRef(Mutability
::Mutable
),
3458 (true, false) => BindingMode
::ByRef(Mutability
::Immutable
),
3459 (false, true) => BindingMode
::ByValue(Mutability
::Mutable
),
3460 (false, false) => BindingMode
::ByValue(Mutability
::Immutable
),
3462 let fieldpath
= codemap
::Spanned{span:self.prev_span, node:fieldname}
;
3463 let fieldpat
= P(ast
::Pat
{
3464 id
: ast
::DUMMY_NODE_ID
,
3465 node
: PatKind
::Ident(bind_type
, fieldpath
, None
),
3466 span
: boxed_span
.to(hi
),
3469 let subpat
= if is_box
{
3471 id
: ast
::DUMMY_NODE_ID
,
3472 node
: PatKind
::Box(fieldpat
),
3478 (subpat
, fieldname
, true)
3481 fields
.push(codemap
::Spanned
{ span
: lo
.to(hi
),
3482 node
: ast
::FieldPat
{
3486 attrs
: attrs
.into(),
3490 return Ok((fields
, etc
));
3493 fn parse_pat_range_end(&mut self) -> PResult
<'a
, P
<Expr
>> {
3494 if self.token
.is_path_start() {
3496 let (qself
, path
) = if self.eat_lt() {
3497 // Parse a qualified path
3498 let (qself
, path
) = self.parse_qpath(PathStyle
::Expr
)?
;
3501 // Parse an unqualified path
3502 (None
, self.parse_path(PathStyle
::Expr
)?
)
3504 let hi
= self.prev_span
;
3505 Ok(self.mk_expr(lo
.to(hi
), ExprKind
::Path(qself
, path
), ThinVec
::new()))
3507 self.parse_pat_literal_maybe_minus()
3511 // helper function to decide whether to parse as ident binding or to try to do
3512 // something more complex like range patterns
3513 fn parse_as_ident(&mut self) -> bool
{
3514 self.look_ahead(1, |t
| match *t
{
3515 token
::OpenDelim(token
::Paren
) | token
::OpenDelim(token
::Brace
) |
3516 token
::DotDotDot
| token
::DotDotEq
| token
::ModSep
| token
::Not
=> Some(false),
3517 // ensure slice patterns [a, b.., c] and [a, b, c..] don't go into the
3518 // range pattern branch
3519 token
::DotDot
=> None
,
3521 }).unwrap_or_else(|| self.look_ahead(2, |t
| match *t
{
3522 token
::Comma
| token
::CloseDelim(token
::Bracket
) => true,
3527 /// Parse a pattern.
3528 pub fn parse_pat(&mut self) -> PResult
<'a
, P
<Pat
>> {
3529 maybe_whole
!(self, NtPat
, |x
| x
);
3534 token
::Underscore
=> {
3537 pat
= PatKind
::Wild
;
3539 token
::BinOp(token
::And
) | token
::AndAnd
=> {
3540 // Parse &pat / &mut pat
3542 let mutbl
= self.parse_mutability();
3543 if let token
::Lifetime(ident
) = self.token
{
3544 return Err(self.fatal(&format
!("unexpected lifetime `{}` in pattern", ident
)));
3546 let subpat
= self.parse_pat()?
;
3547 pat
= PatKind
::Ref(subpat
, mutbl
);
3549 token
::OpenDelim(token
::Paren
) => {
3550 // Parse (pat,pat,pat,...) as tuple pattern
3552 let (fields
, ddpos
) = self.parse_pat_tuple_elements(true)?
;
3553 self.expect(&token
::CloseDelim(token
::Paren
))?
;
3554 pat
= PatKind
::Tuple(fields
, ddpos
);
3556 token
::OpenDelim(token
::Bracket
) => {
3557 // Parse [pat,pat,...] as slice pattern
3559 let (before
, slice
, after
) = self.parse_pat_vec_elements()?
;
3560 self.expect(&token
::CloseDelim(token
::Bracket
))?
;
3561 pat
= PatKind
::Slice(before
, slice
, after
);
3563 // At this point, token != _, &, &&, (, [
3564 _
=> if self.eat_keyword(keywords
::Mut
) {
3565 // Parse mut ident @ pat / mut ref ident @ pat
3566 let mutref_span
= self.prev_span
.to(self.span
);
3567 let binding_mode
= if self.eat_keyword(keywords
::Ref
) {
3569 .struct_span_err(mutref_span
, "the order of `mut` and `ref` is incorrect")
3570 .span_suggestion(mutref_span
, "try switching the order", "ref mut".into())
3572 BindingMode
::ByRef(Mutability
::Mutable
)
3574 BindingMode
::ByValue(Mutability
::Mutable
)
3576 pat
= self.parse_pat_ident(binding_mode
)?
;
3577 } else if self.eat_keyword(keywords
::Ref
) {
3578 // Parse ref ident @ pat / ref mut ident @ pat
3579 let mutbl
= self.parse_mutability();
3580 pat
= self.parse_pat_ident(BindingMode
::ByRef(mutbl
))?
;
3581 } else if self.eat_keyword(keywords
::Box
) {
3583 let subpat
= self.parse_pat()?
;
3584 pat
= PatKind
::Box(subpat
);
3585 } else if self.token
.is_ident() && !self.token
.is_reserved_ident() &&
3586 self.parse_as_ident() {
3587 // Parse ident @ pat
3588 // This can give false positives and parse nullary enums,
3589 // they are dealt with later in resolve
3590 let binding_mode
= BindingMode
::ByValue(Mutability
::Immutable
);
3591 pat
= self.parse_pat_ident(binding_mode
)?
;
3592 } else if self.token
.is_path_start() {
3593 // Parse pattern starting with a path
3594 let (qself
, path
) = if self.eat_lt() {
3595 // Parse a qualified path
3596 let (qself
, path
) = self.parse_qpath(PathStyle
::Expr
)?
;
3599 // Parse an unqualified path
3600 (None
, self.parse_path(PathStyle
::Expr
)?
)
3603 token
::Not
if qself
.is_none() => {
3604 // Parse macro invocation
3606 let (_
, tts
) = self.expect_delimited_token_tree()?
;
3607 let mac
= respan(lo
.to(self.prev_span
), Mac_ { path: path, tts: tts }
);
3608 pat
= PatKind
::Mac(mac
);
3610 token
::DotDotDot
| token
::DotDotEq
| token
::DotDot
=> {
3611 let end_kind
= match self.token
{
3612 token
::DotDot
=> RangeEnd
::Excluded
,
3613 token
::DotDotDot
=> RangeEnd
::Included(RangeSyntax
::DotDotDot
),
3614 token
::DotDotEq
=> RangeEnd
::Included(RangeSyntax
::DotDotEq
),
3615 _
=> panic
!("can only parse `..`/`...`/`..=` for ranges \
3619 let span
= lo
.to(self.prev_span
);
3620 let begin
= self.mk_expr(span
, ExprKind
::Path(qself
, path
), ThinVec
::new());
3622 let end
= self.parse_pat_range_end()?
;
3623 pat
= PatKind
::Range(begin
, end
, end_kind
);
3625 token
::OpenDelim(token
::Brace
) => {
3626 if qself
.is_some() {
3627 return Err(self.fatal("unexpected `{` after qualified path"));
3629 // Parse struct pattern
3631 let (fields
, etc
) = self.parse_pat_fields().unwrap_or_else(|mut e
| {
3633 self.recover_stmt();
3637 pat
= PatKind
::Struct(path
, fields
, etc
);
3639 token
::OpenDelim(token
::Paren
) => {
3640 if qself
.is_some() {
3641 return Err(self.fatal("unexpected `(` after qualified path"));
3643 // Parse tuple struct or enum pattern
3645 let (fields
, ddpos
) = self.parse_pat_tuple_elements(false)?
;
3646 self.expect(&token
::CloseDelim(token
::Paren
))?
;
3647 pat
= PatKind
::TupleStruct(path
, fields
, ddpos
)
3649 _
=> pat
= PatKind
::Path(qself
, path
),
3652 // Try to parse everything else as literal with optional minus
3653 match self.parse_pat_literal_maybe_minus() {
3655 if self.eat(&token
::DotDotDot
) {
3656 let end
= self.parse_pat_range_end()?
;
3657 pat
= PatKind
::Range(begin
, end
,
3658 RangeEnd
::Included(RangeSyntax
::DotDotDot
));
3659 } else if self.eat(&token
::DotDotEq
) {
3660 let end
= self.parse_pat_range_end()?
;
3661 pat
= PatKind
::Range(begin
, end
,
3662 RangeEnd
::Included(RangeSyntax
::DotDotEq
));
3663 } else if self.eat(&token
::DotDot
) {
3664 let end
= self.parse_pat_range_end()?
;
3665 pat
= PatKind
::Range(begin
, end
, RangeEnd
::Excluded
);
3667 pat
= PatKind
::Lit(begin
);
3671 self.cancel(&mut err
);
3672 let msg
= format
!("expected pattern, found {}", self.this_token_descr());
3673 return Err(self.fatal(&msg
));
3680 id
: ast
::DUMMY_NODE_ID
,
3682 span
: lo
.to(self.prev_span
),
3686 /// Parse ident or ident @ pat
3687 /// used by the copy foo and ref foo patterns to give a good
3688 /// error message when parsing mistakes like ref foo(a,b)
3689 fn parse_pat_ident(&mut self,
3690 binding_mode
: ast
::BindingMode
)
3691 -> PResult
<'a
, PatKind
> {
3692 let ident_span
= self.span
;
3693 let ident
= self.parse_ident()?
;
3694 let name
= codemap
::Spanned{span: ident_span, node: ident}
;
3695 let sub
= if self.eat(&token
::At
) {
3696 Some(self.parse_pat()?
)
3701 // just to be friendly, if they write something like
3703 // we end up here with ( as the current token. This shortly
3704 // leads to a parse error. Note that if there is no explicit
3705 // binding mode then we do not end up here, because the lookahead
3706 // will direct us over to parse_enum_variant()
3707 if self.token
== token
::OpenDelim(token
::Paren
) {
3708 return Err(self.span_fatal(
3710 "expected identifier, found enum pattern"))
3713 Ok(PatKind
::Ident(binding_mode
, name
, sub
))
3716 /// Parse a local variable declaration
3717 fn parse_local(&mut self, attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Local
>> {
3718 let lo
= self.prev_span
;
3719 let pat
= self.parse_pat()?
;
3721 let (err
, ty
) = if self.eat(&token
::Colon
) {
3722 // Save the state of the parser before parsing type normally, in case there is a `:`
3723 // instead of an `=` typo.
3724 let parser_snapshot_before_type
= self.clone();
3725 let colon_sp
= self.prev_span
;
3726 match self.parse_ty() {
3727 Ok(ty
) => (None
, Some(ty
)),
3729 // Rewind to before attempting to parse the type and continue parsing
3730 let parser_snapshot_after_type
= self.clone();
3731 mem
::replace(self, parser_snapshot_before_type
);
3733 let snippet
= self.sess
.codemap().span_to_snippet(pat
.span
).unwrap();
3734 err
.span_label(pat
.span
, format
!("while parsing the type for `{}`", snippet
));
3735 (Some((parser_snapshot_after_type
, colon_sp
, err
)), None
)
3741 let init
= match (self.parse_initializer(err
.is_some()), err
) {
3742 (Ok(init
), None
) => { // init parsed, ty parsed
3745 (Ok(init
), Some((_
, colon_sp
, mut err
))) => { // init parsed, ty error
3746 // Could parse the type as if it were the initializer, it is likely there was a
3747 // typo in the code: `:` instead of `=`. Add suggestion and emit the error.
3748 err
.span_suggestion_short(colon_sp
,
3749 "use `=` if you meant to assign",
3752 // As this was parsed successfuly, continue as if the code has been fixed for the
3753 // rest of the file. It will still fail due to the emitted error, but we avoid
3757 (Err(mut init_err
), Some((snapshot
, _
, ty_err
))) => { // init error, ty error
3759 // Couldn't parse the type nor the initializer, only raise the type error and
3760 // return to the parser state before parsing the type as the initializer.
3761 // let x: <parse_error>;
3762 mem
::replace(self, snapshot
);
3765 (Err(err
), None
) => { // init error, ty parsed
3766 // Couldn't parse the initializer and we're not attempting to recover a failed
3767 // parse of the type, return the error.
3771 let hi
= if self.token
== token
::Semi
{
3780 id
: ast
::DUMMY_NODE_ID
,
3786 /// Parse a structure field
3787 fn parse_name_and_ty(&mut self,
3790 attrs
: Vec
<Attribute
>)
3791 -> PResult
<'a
, StructField
> {
3792 let name
= self.parse_ident()?
;
3793 self.expect(&token
::Colon
)?
;
3794 let ty
= self.parse_ty()?
;
3796 span
: lo
.to(self.prev_span
),
3799 id
: ast
::DUMMY_NODE_ID
,
3805 /// Emit an expected item after attributes error.
3806 fn expected_item_err(&self, attrs
: &[Attribute
]) {
3807 let message
= match attrs
.last() {
3808 Some(&Attribute { is_sugared_doc: true, .. }
) => "expected item after doc comment",
3809 _
=> "expected item after attributes",
3812 self.span_err(self.prev_span
, message
);
3815 /// Parse a statement. This stops just before trailing semicolons on everything but items.
3816 /// e.g. a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
3817 pub fn parse_stmt(&mut self) -> PResult
<'a
, Option
<Stmt
>> {
3818 Ok(self.parse_stmt_(true))
3821 // Eat tokens until we can be relatively sure we reached the end of the
3822 // statement. This is something of a best-effort heuristic.
3824 // We terminate when we find an unmatched `}` (without consuming it).
3825 fn recover_stmt(&mut self) {
3826 self.recover_stmt_(SemiColonMode
::Ignore
, BlockMode
::Ignore
)
3829 // If `break_on_semi` is `Break`, then we will stop consuming tokens after
3830 // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
3831 // approximate - it can mean we break too early due to macros, but that
3832 // shoud only lead to sub-optimal recovery, not inaccurate parsing).
3834 // If `break_on_block` is `Break`, then we will stop consuming tokens
3835 // after finding (and consuming) a brace-delimited block.
3836 fn recover_stmt_(&mut self, break_on_semi
: SemiColonMode
, break_on_block
: BlockMode
) {
3837 let mut brace_depth
= 0;
3838 let mut bracket_depth
= 0;
3839 let mut in_block
= false;
3840 debug
!("recover_stmt_ enter loop (semi={:?}, block={:?})",
3841 break_on_semi
, break_on_block
);
3843 debug
!("recover_stmt_ loop {:?}", self.token
);
3845 token
::OpenDelim(token
::DelimToken
::Brace
) => {
3848 if break_on_block
== BlockMode
::Break
&&
3850 bracket_depth
== 0 {
3854 token
::OpenDelim(token
::DelimToken
::Bracket
) => {
3858 token
::CloseDelim(token
::DelimToken
::Brace
) => {
3859 if brace_depth
== 0 {
3860 debug
!("recover_stmt_ return - close delim {:?}", self.token
);
3865 if in_block
&& bracket_depth
== 0 && brace_depth
== 0 {
3866 debug
!("recover_stmt_ return - block end {:?}", self.token
);
3870 token
::CloseDelim(token
::DelimToken
::Bracket
) => {
3872 if bracket_depth
< 0 {
3878 debug
!("recover_stmt_ return - Eof");
3883 if break_on_semi
== SemiColonMode
::Break
&&
3885 bracket_depth
== 0 {
3886 debug
!("recover_stmt_ return - Semi");
3897 fn parse_stmt_(&mut self, macro_legacy_warnings
: bool
) -> Option
<Stmt
> {
3898 self.parse_stmt_without_recovery(macro_legacy_warnings
).unwrap_or_else(|mut e
| {
3900 self.recover_stmt_(SemiColonMode
::Break
, BlockMode
::Ignore
);
3905 fn is_catch_expr(&mut self) -> bool
{
3906 self.token
.is_keyword(keywords
::Do
) &&
3907 self.look_ahead(1, |t
| t
.is_keyword(keywords
::Catch
)) &&
3908 self.look_ahead(2, |t
| *t
== token
::OpenDelim(token
::Brace
)) &&
3910 // prevent `while catch {} {}`, `if catch {} {} else {}`, etc.
3911 !self.restrictions
.contains(Restrictions
::NO_STRUCT_LITERAL
)
3914 fn is_union_item(&self) -> bool
{
3915 self.token
.is_keyword(keywords
::Union
) &&
3916 self.look_ahead(1, |t
| t
.is_ident() && !t
.is_reserved_ident())
3919 fn eat_auto_trait(&mut self) -> bool
{
3920 if self.token
.is_keyword(keywords
::Auto
)
3921 && self.look_ahead(1, |t
| t
.is_keyword(keywords
::Trait
))
3923 self.eat_keyword(keywords
::Auto
) && self.eat_keyword(keywords
::Trait
)
3929 fn is_defaultness(&self) -> bool
{
3930 // `pub` is included for better error messages
3931 self.token
.is_keyword(keywords
::Default
) &&
3932 self.look_ahead(1, |t
| t
.is_keyword(keywords
::Impl
) ||
3933 t
.is_keyword(keywords
::Const
) ||
3934 t
.is_keyword(keywords
::Fn
) ||
3935 t
.is_keyword(keywords
::Unsafe
) ||
3936 t
.is_keyword(keywords
::Extern
) ||
3937 t
.is_keyword(keywords
::Type
) ||
3938 t
.is_keyword(keywords
::Pub
))
3941 fn eat_defaultness(&mut self) -> bool
{
3942 let is_defaultness
= self.is_defaultness();
3946 self.expected_tokens
.push(TokenType
::Keyword(keywords
::Default
));
3951 fn eat_macro_def(&mut self, attrs
: &[Attribute
], vis
: &Visibility
, lo
: Span
)
3952 -> PResult
<'a
, Option
<P
<Item
>>> {
3953 let token_lo
= self.span
;
3954 let (ident
, def
) = match self.token
{
3955 token
::Ident(ident
) if ident
.name
== keywords
::Macro
.name() => {
3957 let ident
= self.parse_ident()?
;
3958 let tokens
= if self.check(&token
::OpenDelim(token
::Brace
)) {
3959 match self.parse_token_tree() {
3960 TokenTree
::Delimited(_
, ref delimited
) => delimited
.stream(),
3961 _
=> unreachable
!(),
3963 } else if self.check(&token
::OpenDelim(token
::Paren
)) {
3964 let args
= self.parse_token_tree();
3965 let body
= if self.check(&token
::OpenDelim(token
::Brace
)) {
3966 self.parse_token_tree()
3971 TokenStream
::concat(vec
![
3973 TokenTree
::Token(token_lo
.to(self.prev_span
), token
::FatArrow
).into(),
3981 (ident
, ast
::MacroDef { tokens: tokens.into(), legacy: false }
)
3983 token
::Ident(ident
) if ident
.name
== "macro_rules" &&
3984 self.look_ahead(1, |t
| *t
== token
::Not
) => {
3985 let prev_span
= self.prev_span
;
3986 self.complain_if_pub_macro(vis
, prev_span
);
3990 let ident
= self.parse_ident()?
;
3991 let (delim
, tokens
) = self.expect_delimited_token_tree()?
;
3992 if delim
!= token
::Brace
{
3993 if !self.eat(&token
::Semi
) {
3994 let msg
= "macros that expand to items must either \
3995 be surrounded with braces or followed by a semicolon";
3996 self.span_err(self.prev_span
, msg
);
4000 (ident
, ast
::MacroDef { tokens: tokens, legacy: true }
)
4002 _
=> return Ok(None
),
4005 let span
= lo
.to(self.prev_span
);
4006 Ok(Some(self.mk_item(span
, ident
, ItemKind
::MacroDef(def
), vis
.clone(), attrs
.to_vec())))
4009 fn parse_stmt_without_recovery(&mut self,
4010 macro_legacy_warnings
: bool
)
4011 -> PResult
<'a
, Option
<Stmt
>> {
4012 maybe_whole
!(self, NtStmt
, |x
| Some(x
));
4014 let attrs
= self.parse_outer_attributes()?
;
4017 Ok(Some(if self.eat_keyword(keywords
::Let
) {
4019 id
: ast
::DUMMY_NODE_ID
,
4020 node
: StmtKind
::Local(self.parse_local(attrs
.into())?
),
4021 span
: lo
.to(self.prev_span
),
4023 } else if let Some(macro_def
) = self.eat_macro_def(&attrs
, &Visibility
::Inherited
, lo
)?
{
4025 id
: ast
::DUMMY_NODE_ID
,
4026 node
: StmtKind
::Item(macro_def
),
4027 span
: lo
.to(self.prev_span
),
4029 // Starts like a simple path, but not a union item.
4030 } else if self.token
.is_path_start() &&
4031 !self.token
.is_qpath_start() &&
4032 !self.is_union_item() {
4033 let pth
= self.parse_path(PathStyle
::Expr
)?
;
4035 if !self.eat(&token
::Not
) {
4036 let expr
= if self.check(&token
::OpenDelim(token
::Brace
)) {
4037 self.parse_struct_expr(lo
, pth
, ThinVec
::new())?
4039 let hi
= self.prev_span
;
4040 self.mk_expr(lo
.to(hi
), ExprKind
::Path(None
, pth
), ThinVec
::new())
4043 let expr
= self.with_res(Restrictions
::STMT_EXPR
, |this
| {
4044 let expr
= this
.parse_dot_or_call_expr_with(expr
, lo
, attrs
.into())?
;
4045 this
.parse_assoc_expr_with(0, LhsExpr
::AlreadyParsed(expr
))
4048 return Ok(Some(Stmt
{
4049 id
: ast
::DUMMY_NODE_ID
,
4050 node
: StmtKind
::Expr(expr
),
4051 span
: lo
.to(self.prev_span
),
4055 // it's a macro invocation
4056 let id
= match self.token
{
4057 token
::OpenDelim(_
) => keywords
::Invalid
.ident(), // no special identifier
4058 _
=> self.parse_ident()?
,
4061 // check that we're pointing at delimiters (need to check
4062 // again after the `if`, because of `parse_ident`
4063 // consuming more tokens).
4064 let delim
= match self.token
{
4065 token
::OpenDelim(delim
) => delim
,
4067 // we only expect an ident if we didn't parse one
4069 let ident_str
= if id
.name
== keywords
::Invalid
.name() {
4074 let tok_str
= self.this_token_to_string();
4075 return Err(self.fatal(&format
!("expected {}`(` or `{{`, found `{}`",
4081 let (_
, tts
) = self.expect_delimited_token_tree()?
;
4082 let hi
= self.prev_span
;
4084 let style
= if delim
== token
::Brace
{
4085 MacStmtStyle
::Braces
4087 MacStmtStyle
::NoBraces
4090 if id
.name
== keywords
::Invalid
.name() {
4091 let mac
= respan(lo
.to(hi
), Mac_ { path: pth, tts: tts }
);
4092 let node
= if delim
== token
::Brace
||
4093 self.token
== token
::Semi
|| self.token
== token
::Eof
{
4094 StmtKind
::Mac(P((mac
, style
, attrs
.into())))
4096 // We used to incorrectly stop parsing macro-expanded statements here.
4097 // If the next token will be an error anyway but could have parsed with the
4098 // earlier behavior, stop parsing here and emit a warning to avoid breakage.
4099 else if macro_legacy_warnings
&& self.token
.can_begin_expr() && match self.token
{
4100 // These can continue an expression, so we can't stop parsing and warn.
4101 token
::OpenDelim(token
::Paren
) | token
::OpenDelim(token
::Bracket
) |
4102 token
::BinOp(token
::Minus
) | token
::BinOp(token
::Star
) |
4103 token
::BinOp(token
::And
) | token
::BinOp(token
::Or
) |
4104 token
::AndAnd
| token
::OrOr
|
4105 token
::DotDot
| token
::DotDotDot
| token
::DotDotEq
=> false,
4108 self.warn_missing_semicolon();
4109 StmtKind
::Mac(P((mac
, style
, attrs
.into())))
4111 let e
= self.mk_mac_expr(lo
.to(hi
), mac
.node
, ThinVec
::new());
4112 let e
= self.parse_dot_or_call_expr_with(e
, lo
, attrs
.into())?
;
4113 let e
= self.parse_assoc_expr_with(0, LhsExpr
::AlreadyParsed(e
))?
;
4117 id
: ast
::DUMMY_NODE_ID
,
4122 // if it has a special ident, it's definitely an item
4124 // Require a semicolon or braces.
4125 if style
!= MacStmtStyle
::Braces
{
4126 if !self.eat(&token
::Semi
) {
4127 self.span_err(self.prev_span
,
4128 "macros that expand to items must \
4129 either be surrounded with braces or \
4130 followed by a semicolon");
4133 let span
= lo
.to(hi
);
4135 id
: ast
::DUMMY_NODE_ID
,
4137 node
: StmtKind
::Item({
4139 span
, id
/*id is good here*/,
4140 ItemKind
::Mac(respan(span
, Mac_ { path: pth, tts: tts }
)),
4141 Visibility
::Inherited
,
4147 // FIXME: Bad copy of attrs
4148 let old_directory_ownership
=
4149 mem
::replace(&mut self.directory
.ownership
, DirectoryOwnership
::UnownedViaBlock
);
4150 let item
= self.parse_item_(attrs
.clone(), false, true)?
;
4151 self.directory
.ownership
= old_directory_ownership
;
4155 id
: ast
::DUMMY_NODE_ID
,
4156 span
: lo
.to(i
.span
),
4157 node
: StmtKind
::Item(i
),
4160 let unused_attrs
= |attrs
: &[Attribute
], s
: &mut Self| {
4161 if !attrs
.is_empty() {
4162 if s
.prev_token_kind
== PrevTokenKind
::DocComment
{
4163 s
.span_fatal_err(s
.prev_span
, Error
::UselessDocComment
).emit();
4164 } else if attrs
.iter().any(|a
| a
.style
== AttrStyle
::Outer
) {
4165 s
.span_err(s
.span
, "expected statement after outer attribute");
4170 // Do not attempt to parse an expression if we're done here.
4171 if self.token
== token
::Semi
{
4172 unused_attrs(&attrs
, self);
4177 if self.token
== token
::CloseDelim(token
::Brace
) {
4178 unused_attrs(&attrs
, self);
4182 // Remainder are line-expr stmts.
4183 let e
= self.parse_expr_res(
4184 Restrictions
::STMT_EXPR
, Some(attrs
.into()))?
;
4186 id
: ast
::DUMMY_NODE_ID
,
4187 span
: lo
.to(e
.span
),
4188 node
: StmtKind
::Expr(e
),
4195 /// Is this expression a successfully-parsed statement?
4196 fn expr_is_complete(&mut self, e
: &Expr
) -> bool
{
4197 self.restrictions
.contains(Restrictions
::STMT_EXPR
) &&
4198 !classify
::expr_requires_semi_to_be_stmt(e
)
4201 /// Parse a block. No inner attrs are allowed.
4202 pub fn parse_block(&mut self) -> PResult
<'a
, P
<Block
>> {
4203 maybe_whole
!(self, NtBlock
, |x
| x
);
4207 if !self.eat(&token
::OpenDelim(token
::Brace
)) {
4209 let tok
= self.this_token_to_string();
4210 let mut e
= self.span_fatal(sp
, &format
!("expected `{{`, found `{}`", tok
));
4212 // Check to see if the user has written something like
4217 // Which is valid in other languages, but not Rust.
4218 match self.parse_stmt_without_recovery(false) {
4220 let mut stmt_span
= stmt
.span
;
4221 // expand the span to include the semicolon, if it exists
4222 if self.eat(&token
::Semi
) {
4223 stmt_span
= stmt_span
.with_hi(self.prev_span
.hi());
4225 let sugg
= pprust
::to_string(|s
| {
4226 use print
::pprust
::{PrintState, INDENT_UNIT}
;
4227 s
.ibox(INDENT_UNIT
)?
;
4229 s
.print_stmt(&stmt
)?
;
4230 s
.bclose_maybe_open(stmt
.span
, INDENT_UNIT
, false)
4232 e
.span_suggestion(stmt_span
, "try placing this code inside a block", sugg
);
4235 self.recover_stmt_(SemiColonMode
::Break
, BlockMode
::Ignore
);
4236 self.cancel(&mut e
);
4243 self.parse_block_tail(lo
, BlockCheckMode
::Default
)
4246 /// Parse a block. Inner attrs are allowed.
4247 fn parse_inner_attrs_and_block(&mut self) -> PResult
<'a
, (Vec
<Attribute
>, P
<Block
>)> {
4248 maybe_whole
!(self, NtBlock
, |x
| (Vec
::new(), x
));
4251 self.expect(&token
::OpenDelim(token
::Brace
))?
;
4252 Ok((self.parse_inner_attributes()?
,
4253 self.parse_block_tail(lo
, BlockCheckMode
::Default
)?
))
4256 /// Parse the rest of a block expression or function body
4257 /// Precondition: already parsed the '{'.
4258 fn parse_block_tail(&mut self, lo
: Span
, s
: BlockCheckMode
) -> PResult
<'a
, P
<Block
>> {
4259 let mut stmts
= vec
![];
4261 while !self.eat(&token
::CloseDelim(token
::Brace
)) {
4262 if let Some(stmt
) = self.parse_full_stmt(false)?
{
4264 } else if self.token
== token
::Eof
{
4267 // Found only `;` or `}`.
4274 id
: ast
::DUMMY_NODE_ID
,
4276 span
: lo
.to(self.prev_span
),
4280 /// Parse a statement, including the trailing semicolon.
4281 pub fn parse_full_stmt(&mut self, macro_legacy_warnings
: bool
) -> PResult
<'a
, Option
<Stmt
>> {
4282 let mut stmt
= match self.parse_stmt_(macro_legacy_warnings
) {
4284 None
=> return Ok(None
),
4288 StmtKind
::Expr(ref expr
) if self.token
!= token
::Eof
=> {
4289 // expression without semicolon
4290 if classify
::expr_requires_semi_to_be_stmt(expr
) {
4291 // Just check for errors and recover; do not eat semicolon yet.
4293 self.expect_one_of(&[], &[token
::Semi
, token
::CloseDelim(token
::Brace
)])
4296 self.recover_stmt();
4300 StmtKind
::Local(..) => {
4301 // We used to incorrectly allow a macro-expanded let statement to lack a semicolon.
4302 if macro_legacy_warnings
&& self.token
!= token
::Semi
{
4303 self.warn_missing_semicolon();
4305 self.expect_one_of(&[token
::Semi
], &[])?
;
4311 if self.eat(&token
::Semi
) {
4312 stmt
= stmt
.add_trailing_semicolon();
4315 stmt
.span
= stmt
.span
.with_hi(self.prev_span
.hi());
4319 fn warn_missing_semicolon(&self) {
4320 self.diagnostic().struct_span_warn(self.span
, {
4321 &format
!("expected `;`, found `{}`", self.this_token_to_string())
4323 "This was erroneously allowed and will become a hard error in a future release"
4327 fn err_dotdotdot_syntax(&self, span
: Span
) {
4328 self.diagnostic().struct_span_err(span
, {
4329 "`...` syntax cannot be used in expressions"
4331 "Use `..` if you need an exclusive range (a < b)"
4333 "or `..=` if you need an inclusive range (a <= b)"
4337 // Parse bounds of a type parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
4338 // BOUND = TY_BOUND | LT_BOUND
4339 // LT_BOUND = LIFETIME (e.g. `'a`)
4340 // TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
4341 // TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g. `?for<'a: 'b> m::Trait<'a>`)
4342 fn parse_ty_param_bounds_common(&mut self, allow_plus
: bool
) -> PResult
<'a
, TyParamBounds
> {
4343 let mut bounds
= Vec
::new();
4345 // This needs to be syncronized with `Token::can_begin_bound`.
4346 let is_bound_start
= self.check_path() || self.check_lifetime() ||
4347 self.check(&token
::Question
) ||
4348 self.check_keyword(keywords
::For
) ||
4349 self.check(&token
::OpenDelim(token
::Paren
));
4351 let has_parens
= self.eat(&token
::OpenDelim(token
::Paren
));
4352 let question
= if self.eat(&token
::Question
) { Some(self.prev_span) }
else { None }
;
4353 if self.token
.is_lifetime() {
4354 if let Some(question_span
) = question
{
4355 self.span_err(question_span
,
4356 "`?` may only modify trait bounds, not lifetime bounds");
4358 bounds
.push(RegionTyParamBound(self.expect_lifetime()));
4361 let lifetime_defs
= self.parse_late_bound_lifetime_defs()?
;
4362 let path
= self.parse_path(PathStyle
::Type
)?
;
4363 let poly_trait
= PolyTraitRef
::new(lifetime_defs
, path
, lo
.to(self.prev_span
));
4364 let modifier
= if question
.is_some() {
4365 TraitBoundModifier
::Maybe
4367 TraitBoundModifier
::None
4369 bounds
.push(TraitTyParamBound(poly_trait
, modifier
));
4372 self.expect(&token
::CloseDelim(token
::Paren
))?
;
4373 if let Some(&RegionTyParamBound(..)) = bounds
.last() {
4374 self.span_err(self.prev_span
,
4375 "parenthesized lifetime bounds are not supported");
4382 if !allow_plus
|| !self.eat(&token
::BinOp(token
::Plus
)) {
4390 fn parse_ty_param_bounds(&mut self) -> PResult
<'a
, TyParamBounds
> {
4391 self.parse_ty_param_bounds_common(true)
4394 // Parse bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
4395 // BOUND = LT_BOUND (e.g. `'a`)
4396 fn parse_lt_param_bounds(&mut self) -> Vec
<Lifetime
> {
4397 let mut lifetimes
= Vec
::new();
4398 while self.check_lifetime() {
4399 lifetimes
.push(self.expect_lifetime());
4401 if !self.eat(&token
::BinOp(token
::Plus
)) {
4408 /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
4409 fn parse_ty_param(&mut self, preceding_attrs
: Vec
<Attribute
>) -> PResult
<'a
, TyParam
> {
4410 let span
= self.span
;
4411 let ident
= self.parse_ident()?
;
4413 // Parse optional colon and param bounds.
4414 let bounds
= if self.eat(&token
::Colon
) {
4415 self.parse_ty_param_bounds()?
4420 let default = if self.eat(&token
::Eq
) {
4421 Some(self.parse_ty()?
)
4427 attrs
: preceding_attrs
.into(),
4429 id
: ast
::DUMMY_NODE_ID
,
4436 /// Parses (possibly empty) list of lifetime and type parameters, possibly including
4437 /// trailing comma and erroneous trailing attributes.
4438 pub fn parse_generic_params(&mut self) -> PResult
<'a
, (Vec
<LifetimeDef
>, Vec
<TyParam
>)> {
4439 let mut lifetime_defs
= Vec
::new();
4440 let mut ty_params
= Vec
::new();
4441 let mut seen_ty_param
= false;
4443 let attrs
= self.parse_outer_attributes()?
;
4444 if self.check_lifetime() {
4445 let lifetime
= self.expect_lifetime();
4446 // Parse lifetime parameter.
4447 let bounds
= if self.eat(&token
::Colon
) {
4448 self.parse_lt_param_bounds()
4452 lifetime_defs
.push(LifetimeDef
{
4453 attrs
: attrs
.into(),
4458 self.span_err(self.prev_span
,
4459 "lifetime parameters must be declared prior to type parameters");
4461 } else if self.check_ident() {
4462 // Parse type parameter.
4463 ty_params
.push(self.parse_ty_param(attrs
)?
);
4464 seen_ty_param
= true;
4466 // Check for trailing attributes and stop parsing.
4467 if !attrs
.is_empty() {
4468 let param_kind
= if seen_ty_param { "type" }
else { "lifetime" }
;
4469 self.span_err(attrs
[0].span
,
4470 &format
!("trailing attribute after {} parameters", param_kind
));
4475 if !self.eat(&token
::Comma
) {
4479 Ok((lifetime_defs
, ty_params
))
4482 /// Parse a set of optional generic type parameter declarations. Where
4483 /// clauses are not parsed here, and must be added later via
4484 /// `parse_where_clause()`.
4486 /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
4487 /// | ( < lifetimes , typaramseq ( , )? > )
4488 /// where typaramseq = ( typaram ) | ( typaram , typaramseq )
4489 pub fn parse_generics(&mut self) -> PResult
<'a
, ast
::Generics
> {
4490 maybe_whole
!(self, NtGenerics
, |x
| x
);
4492 let span_lo
= self.span
;
4494 let (lifetime_defs
, ty_params
) = self.parse_generic_params()?
;
4497 lifetimes
: lifetime_defs
,
4499 where_clause
: WhereClause
{
4500 id
: ast
::DUMMY_NODE_ID
,
4501 predicates
: Vec
::new(),
4502 span
: syntax_pos
::DUMMY_SP
,
4504 span
: span_lo
.to(self.prev_span
),
4507 Ok(ast
::Generics
::default())
4511 /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
4512 /// possibly including trailing comma.
4513 fn parse_generic_args(&mut self) -> PResult
<'a
, (Vec
<Lifetime
>, Vec
<P
<Ty
>>, Vec
<TypeBinding
>)> {
4514 let mut lifetimes
= Vec
::new();
4515 let mut types
= Vec
::new();
4516 let mut bindings
= Vec
::new();
4517 let mut seen_type
= false;
4518 let mut seen_binding
= false;
4520 if self.check_lifetime() && self.look_ahead(1, |t
| t
!= &token
::BinOp(token
::Plus
)) {
4521 // Parse lifetime argument.
4522 lifetimes
.push(self.expect_lifetime());
4523 if seen_type
|| seen_binding
{
4524 self.span_err(self.prev_span
,
4525 "lifetime parameters must be declared prior to type parameters");
4527 } else if self.check_ident() && self.look_ahead(1, |t
| t
== &token
::Eq
) {
4528 // Parse associated type binding.
4530 let ident
= self.parse_ident()?
;
4532 let ty
= self.parse_ty()?
;
4533 bindings
.push(TypeBinding
{
4534 id
: ast
::DUMMY_NODE_ID
,
4537 span
: lo
.to(self.prev_span
),
4539 seen_binding
= true;
4540 } else if self.check_type() {
4541 // Parse type argument.
4542 types
.push(self.parse_ty()?
);
4544 self.span_err(types
[types
.len() - 1].span
,
4545 "type parameters must be declared prior to associated type bindings");
4552 if !self.eat(&token
::Comma
) {
4556 Ok((lifetimes
, types
, bindings
))
4559 /// Parses an optional `where` clause and places it in `generics`.
4561 /// ```ignore (only-for-syntax-highlight)
4562 /// where T : Trait<U, V> + 'b, 'a : 'b
4564 pub fn parse_where_clause(&mut self) -> PResult
<'a
, WhereClause
> {
4565 maybe_whole
!(self, NtWhereClause
, |x
| x
);
4567 let mut where_clause
= WhereClause
{
4568 id
: ast
::DUMMY_NODE_ID
,
4569 predicates
: Vec
::new(),
4570 span
: syntax_pos
::DUMMY_SP
,
4573 if !self.eat_keyword(keywords
::Where
) {
4574 return Ok(where_clause
);
4576 let lo
= self.prev_span
;
4578 // This is a temporary future proofing.
4580 // We are considering adding generics to the `where` keyword as an alternative higher-rank
4581 // parameter syntax (as in `where<'a>` or `where<T>`. To avoid that being a breaking
4582 // change, for now we refuse to parse `where < (ident | lifetime) (> | , | :)`.
4583 if token
::Lt
== self.token
{
4584 let ident_or_lifetime
= self.look_ahead(1, |t
| t
.is_ident() || t
.is_lifetime());
4585 if ident_or_lifetime
{
4586 let gt_comma_or_colon
= self.look_ahead(2, |t
| {
4587 *t
== token
::Gt
|| *t
== token
::Comma
|| *t
== token
::Colon
4589 if gt_comma_or_colon
{
4590 self.span_err(self.span
, "syntax `where<T>` is reserved for future use");
4597 if self.check_lifetime() && self.look_ahead(1, |t
| t
!= &token
::BinOp(token
::Plus
)) {
4598 let lifetime
= self.expect_lifetime();
4599 // Bounds starting with a colon are mandatory, but possibly empty.
4600 self.expect(&token
::Colon
)?
;
4601 let bounds
= self.parse_lt_param_bounds();
4602 where_clause
.predicates
.push(ast
::WherePredicate
::RegionPredicate(
4603 ast
::WhereRegionPredicate
{
4604 span
: lo
.to(self.prev_span
),
4609 } else if self.check_type() {
4610 // Parse optional `for<'a, 'b>`.
4611 // This `for` is parsed greedily and applies to the whole predicate,
4612 // the bounded type can have its own `for` applying only to it.
4613 // Example 1: for<'a> Trait1<'a>: Trait2<'a /*ok*/>
4614 // Example 2: (for<'a> Trait1<'a>): Trait2<'a /*not ok*/>
4615 // Example 3: for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /*ok*/, 'b /*not ok*/>
4616 let lifetime_defs
= self.parse_late_bound_lifetime_defs()?
;
4618 // Parse type with mandatory colon and (possibly empty) bounds,
4619 // or with mandatory equality sign and the second type.
4620 let ty
= self.parse_ty()?
;
4621 if self.eat(&token
::Colon
) {
4622 let bounds
= self.parse_ty_param_bounds()?
;
4623 where_clause
.predicates
.push(ast
::WherePredicate
::BoundPredicate(
4624 ast
::WhereBoundPredicate
{
4625 span
: lo
.to(self.prev_span
),
4626 bound_lifetimes
: lifetime_defs
,
4631 // FIXME: Decide what should be used here, `=` or `==`.
4632 } else if self.eat(&token
::Eq
) || self.eat(&token
::EqEq
) {
4633 let rhs_ty
= self.parse_ty()?
;
4634 where_clause
.predicates
.push(ast
::WherePredicate
::EqPredicate(
4635 ast
::WhereEqPredicate
{
4636 span
: lo
.to(self.prev_span
),
4639 id
: ast
::DUMMY_NODE_ID
,
4643 return self.unexpected();
4649 if !self.eat(&token
::Comma
) {
4654 where_clause
.span
= lo
.to(self.prev_span
);
4658 fn parse_fn_args(&mut self, named_args
: bool
, allow_variadic
: bool
)
4659 -> PResult
<'a
, (Vec
<Arg
> , bool
)> {
4661 let mut variadic
= false;
4662 let args
: Vec
<Option
<Arg
>> =
4663 self.parse_unspanned_seq(
4664 &token
::OpenDelim(token
::Paren
),
4665 &token
::CloseDelim(token
::Paren
),
4666 SeqSep
::trailing_allowed(token
::Comma
),
4668 if p
.token
== token
::DotDotDot
{
4671 if p
.token
!= token
::CloseDelim(token
::Paren
) {
4674 "`...` must be last in argument list for variadic function");
4679 "only foreign functions are allowed to be variadic");
4684 match p
.parse_arg_general(named_args
) {
4685 Ok(arg
) => Ok(Some(arg
)),
4688 let lo
= p
.prev_span
;
4689 // Skip every token until next possible arg or end.
4690 p
.eat_to_tokens(&[&token
::Comma
, &token
::CloseDelim(token
::Paren
)]);
4691 // Create a placeholder argument for proper arg count (#34264).
4692 let span
= lo
.to(p
.prev_span
);
4693 Ok(Some(dummy_arg(span
)))
4700 let args
: Vec
<_
> = args
.into_iter().filter_map(|x
| x
).collect();
4702 if variadic
&& args
.is_empty() {
4704 "variadic function must be declared with at least one named argument");
4707 Ok((args
, variadic
))
4710 /// Parse the argument list and result type of a function declaration
4711 pub fn parse_fn_decl(&mut self, allow_variadic
: bool
) -> PResult
<'a
, P
<FnDecl
>> {
4713 let (args
, variadic
) = self.parse_fn_args(true, allow_variadic
)?
;
4714 let ret_ty
= self.parse_ret_ty()?
;
4723 /// Returns the parsed optional self argument and whether a self shortcut was used.
4724 fn parse_self_arg(&mut self) -> PResult
<'a
, Option
<Arg
>> {
4725 let expect_ident
= |this
: &mut Self| match this
.token
{
4726 // Preserve hygienic context.
4727 token
::Ident(ident
) => { let sp = this.span; this.bump(); codemap::respan(sp, ident) }
4730 let isolated_self
= |this
: &mut Self, n
| {
4731 this
.look_ahead(n
, |t
| t
.is_keyword(keywords
::SelfValue
)) &&
4732 this
.look_ahead(n
+ 1, |t
| t
!= &token
::ModSep
)
4735 // Parse optional self parameter of a method.
4736 // Only a limited set of initial token sequences is considered self parameters, anything
4737 // else is parsed as a normal function parameter list, so some lookahead is required.
4738 let eself_lo
= self.span
;
4739 let (eself
, eself_ident
) = match self.token
{
4740 token
::BinOp(token
::And
) => {
4746 if isolated_self(self, 1) {
4748 (SelfKind
::Region(None
, Mutability
::Immutable
), expect_ident(self))
4749 } else if self.look_ahead(1, |t
| t
.is_keyword(keywords
::Mut
)) &&
4750 isolated_self(self, 2) {
4753 (SelfKind
::Region(None
, Mutability
::Mutable
), expect_ident(self))
4754 } else if self.look_ahead(1, |t
| t
.is_lifetime()) &&
4755 isolated_self(self, 2) {
4757 let lt
= self.expect_lifetime();
4758 (SelfKind
::Region(Some(lt
), Mutability
::Immutable
), expect_ident(self))
4759 } else if self.look_ahead(1, |t
| t
.is_lifetime()) &&
4760 self.look_ahead(2, |t
| t
.is_keyword(keywords
::Mut
)) &&
4761 isolated_self(self, 3) {
4763 let lt
= self.expect_lifetime();
4765 (SelfKind
::Region(Some(lt
), Mutability
::Mutable
), expect_ident(self))
4770 token
::BinOp(token
::Star
) => {
4775 // Emit special error for `self` cases.
4776 if isolated_self(self, 1) {
4778 self.span_err(self.span
, "cannot pass `self` by raw pointer");
4779 (SelfKind
::Value(Mutability
::Immutable
), expect_ident(self))
4780 } else if self.look_ahead(1, |t
| t
.is_mutability()) &&
4781 isolated_self(self, 2) {
4784 self.span_err(self.span
, "cannot pass `self` by raw pointer");
4785 (SelfKind
::Value(Mutability
::Immutable
), expect_ident(self))
4790 token
::Ident(..) => {
4791 if isolated_self(self, 0) {
4794 let eself_ident
= expect_ident(self);
4795 if self.eat(&token
::Colon
) {
4796 let ty
= self.parse_ty()?
;
4797 (SelfKind
::Explicit(ty
, Mutability
::Immutable
), eself_ident
)
4799 (SelfKind
::Value(Mutability
::Immutable
), eself_ident
)
4801 } else if self.token
.is_keyword(keywords
::Mut
) &&
4802 isolated_self(self, 1) {
4806 let eself_ident
= expect_ident(self);
4807 if self.eat(&token
::Colon
) {
4808 let ty
= self.parse_ty()?
;
4809 (SelfKind
::Explicit(ty
, Mutability
::Mutable
), eself_ident
)
4811 (SelfKind
::Value(Mutability
::Mutable
), eself_ident
)
4817 _
=> return Ok(None
),
4820 let eself
= codemap
::respan(eself_lo
.to(self.prev_span
), eself
);
4821 Ok(Some(Arg
::from_self(eself
, eself_ident
)))
4824 /// Parse the parameter list and result type of a function that may have a `self` parameter.
4825 fn parse_fn_decl_with_self
<F
>(&mut self, parse_arg_fn
: F
) -> PResult
<'a
, P
<FnDecl
>>
4826 where F
: FnMut(&mut Parser
<'a
>) -> PResult
<'a
, Arg
>,
4828 self.expect(&token
::OpenDelim(token
::Paren
))?
;
4830 // Parse optional self argument
4831 let self_arg
= self.parse_self_arg()?
;
4833 // Parse the rest of the function parameter list.
4834 let sep
= SeqSep
::trailing_allowed(token
::Comma
);
4835 let fn_inputs
= if let Some(self_arg
) = self_arg
{
4836 if self.check(&token
::CloseDelim(token
::Paren
)) {
4838 } else if self.eat(&token
::Comma
) {
4839 let mut fn_inputs
= vec
![self_arg
];
4840 fn_inputs
.append(&mut self.parse_seq_to_before_end(
4841 &token
::CloseDelim(token
::Paren
), sep
, parse_arg_fn
)?
4845 return self.unexpected();
4848 self.parse_seq_to_before_end(&token
::CloseDelim(token
::Paren
), sep
, parse_arg_fn
)?
4851 // Parse closing paren and return type.
4852 self.expect(&token
::CloseDelim(token
::Paren
))?
;
4855 output
: self.parse_ret_ty()?
,
4860 // parse the |arg, arg| header on a lambda
4861 fn parse_fn_block_decl(&mut self) -> PResult
<'a
, P
<FnDecl
>> {
4862 let inputs_captures
= {
4863 if self.eat(&token
::OrOr
) {
4866 self.expect(&token
::BinOp(token
::Or
))?
;
4867 let args
= self.parse_seq_to_before_tokens(
4868 &[&token
::BinOp(token
::Or
), &token
::OrOr
],
4869 SeqSep
::trailing_allowed(token
::Comma
),
4870 TokenExpectType
::NoExpect
,
4871 |p
| p
.parse_fn_block_arg()
4877 let output
= self.parse_ret_ty()?
;
4880 inputs
: inputs_captures
,
4886 /// Parse the name and optional generic types of a function header.
4887 fn parse_fn_header(&mut self) -> PResult
<'a
, (Ident
, ast
::Generics
)> {
4888 let id
= self.parse_ident()?
;
4889 let generics
= self.parse_generics()?
;
4893 fn mk_item(&mut self, span
: Span
, ident
: Ident
, node
: ItemKind
, vis
: Visibility
,
4894 attrs
: Vec
<Attribute
>) -> P
<Item
> {
4898 id
: ast
::DUMMY_NODE_ID
,
4906 /// Parse an item-position function declaration.
4907 fn parse_item_fn(&mut self,
4909 constness
: Spanned
<Constness
>,
4911 -> PResult
<'a
, ItemInfo
> {
4912 let (ident
, mut generics
) = self.parse_fn_header()?
;
4913 let decl
= self.parse_fn_decl(false)?
;
4914 generics
.where_clause
= self.parse_where_clause()?
;
4915 let (inner_attrs
, body
) = self.parse_inner_attrs_and_block()?
;
4916 Ok((ident
, ItemKind
::Fn(decl
, unsafety
, constness
, abi
, generics
, body
), Some(inner_attrs
)))
4919 /// true if we are looking at `const ID`, false for things like `const fn` etc
4920 pub fn is_const_item(&mut self) -> bool
{
4921 self.token
.is_keyword(keywords
::Const
) &&
4922 !self.look_ahead(1, |t
| t
.is_keyword(keywords
::Fn
)) &&
4923 !self.look_ahead(1, |t
| t
.is_keyword(keywords
::Unsafe
))
4926 /// parses all the "front matter" for a `fn` declaration, up to
4927 /// and including the `fn` keyword:
4931 /// - `const unsafe fn`
4934 pub fn parse_fn_front_matter(&mut self)
4935 -> PResult
<'a
, (Spanned
<ast
::Constness
>,
4938 let is_const_fn
= self.eat_keyword(keywords
::Const
);
4939 let const_span
= self.prev_span
;
4940 let unsafety
= self.parse_unsafety()?
;
4941 let (constness
, unsafety
, abi
) = if is_const_fn
{
4942 (respan(const_span
, Constness
::Const
), unsafety
, Abi
::Rust
)
4944 let abi
= if self.eat_keyword(keywords
::Extern
) {
4945 self.parse_opt_abi()?
.unwrap_or(Abi
::C
)
4949 (respan(self.prev_span
, Constness
::NotConst
), unsafety
, abi
)
4951 self.expect_keyword(keywords
::Fn
)?
;
4952 Ok((constness
, unsafety
, abi
))
4955 /// Parse an impl item.
4956 pub fn parse_impl_item(&mut self, at_end
: &mut bool
) -> PResult
<'a
, ImplItem
> {
4957 maybe_whole
!(self, NtImplItem
, |x
| x
);
4958 let attrs
= self.parse_outer_attributes()?
;
4959 let (mut item
, tokens
) = self.collect_tokens(|this
| {
4960 this
.parse_impl_item_(at_end
, attrs
)
4963 // See `parse_item` for why this clause is here.
4964 if !item
.attrs
.iter().any(|attr
| attr
.style
== AttrStyle
::Inner
) {
4965 item
.tokens
= Some(tokens
);
4970 fn parse_impl_item_(&mut self,
4972 mut attrs
: Vec
<Attribute
>) -> PResult
<'a
, ImplItem
> {
4974 let vis
= self.parse_visibility(false)?
;
4975 let defaultness
= self.parse_defaultness()?
;
4976 let (name
, node
, generics
) = if self.eat_keyword(keywords
::Type
) {
4977 let name
= self.parse_ident()?
;
4978 self.expect(&token
::Eq
)?
;
4979 let typ
= self.parse_ty()?
;
4980 self.expect(&token
::Semi
)?
;
4981 (name
, ast
::ImplItemKind
::Type(typ
), ast
::Generics
::default())
4982 } else if self.is_const_item() {
4983 self.expect_keyword(keywords
::Const
)?
;
4984 let name
= self.parse_ident()?
;
4985 self.expect(&token
::Colon
)?
;
4986 let typ
= self.parse_ty()?
;
4987 self.expect(&token
::Eq
)?
;
4988 let expr
= self.parse_expr()?
;
4989 self.expect(&token
::Semi
)?
;
4990 (name
, ast
::ImplItemKind
::Const(typ
, expr
), ast
::Generics
::default())
4992 let (name
, inner_attrs
, generics
, node
) = self.parse_impl_method(&vis
, at_end
)?
;
4993 attrs
.extend(inner_attrs
);
4994 (name
, node
, generics
)
4998 id
: ast
::DUMMY_NODE_ID
,
4999 span
: lo
.to(self.prev_span
),
5010 fn complain_if_pub_macro(&mut self, vis
: &Visibility
, sp
: Span
) {
5011 if let Err(mut err
) = self.complain_if_pub_macro_diag(vis
, sp
) {
5016 fn complain_if_pub_macro_diag(&mut self, vis
: &Visibility
, sp
: Span
) -> PResult
<'a
, ()> {
5018 Visibility
::Inherited
=> Ok(()),
5020 let is_macro_rules
: bool
= match self.token
{
5021 token
::Ident(sid
) => sid
.name
== Symbol
::intern("macro_rules"),
5025 let mut err
= self.diagnostic()
5026 .struct_span_err(sp
, "can't qualify macro_rules invocation with `pub`");
5027 err
.help("did you mean #[macro_export]?");
5030 let mut err
= self.diagnostic()
5031 .struct_span_err(sp
, "can't qualify macro invocation with `pub`");
5032 err
.help("try adjusting the macro to put `pub` inside the invocation");
5039 fn missing_assoc_item_kind_err(&mut self, item_type
: &str, prev_span
: Span
)
5040 -> DiagnosticBuilder
<'a
>
5042 // Given this code `path(`, it seems like this is not
5043 // setting the visibility of a macro invocation, but rather
5044 // a mistyped method declaration.
5045 // Create a diagnostic pointing out that `fn` is missing.
5047 // x | pub path(&self) {
5048 // | ^ missing `fn`, `type`, or `const`
5050 // ^^ `sp` below will point to this
5051 let sp
= prev_span
.between(self.prev_span
);
5052 let mut err
= self.diagnostic().struct_span_err(
5054 &format
!("missing `fn`, `type`, or `const` for {}-item declaration",
5056 err
.span_label(sp
, "missing `fn`, `type`, or `const`");
5060 /// Parse a method or a macro invocation in a trait impl.
5061 fn parse_impl_method(&mut self, vis
: &Visibility
, at_end
: &mut bool
)
5062 -> PResult
<'a
, (Ident
, Vec
<ast
::Attribute
>, ast
::Generics
,
5063 ast
::ImplItemKind
)> {
5064 // code copied from parse_macro_use_or_failure... abstraction!
5065 if self.token
.is_path_start() {
5068 let prev_span
= self.prev_span
;
5071 let pth
= self.parse_path(PathStyle
::Mod
)?
;
5072 if pth
.segments
.len() == 1 {
5073 if !self.eat(&token
::Not
) {
5074 return Err(self.missing_assoc_item_kind_err("impl", prev_span
));
5077 self.expect(&token
::Not
)?
;
5080 self.complain_if_pub_macro(vis
, prev_span
);
5082 // eat a matched-delimiter token tree:
5084 let (delim
, tts
) = self.expect_delimited_token_tree()?
;
5085 if delim
!= token
::Brace
{
5086 self.expect(&token
::Semi
)?
5089 let mac
= respan(lo
.to(self.prev_span
), Mac_ { path: pth, tts: tts }
);
5090 Ok((keywords
::Invalid
.ident(), vec
![], ast
::Generics
::default(),
5091 ast
::ImplItemKind
::Macro(mac
)))
5093 let (constness
, unsafety
, abi
) = self.parse_fn_front_matter()?
;
5094 let ident
= self.parse_ident()?
;
5095 let mut generics
= self.parse_generics()?
;
5096 let decl
= self.parse_fn_decl_with_self(|p
| p
.parse_arg())?
;
5097 generics
.where_clause
= self.parse_where_clause()?
;
5099 let (inner_attrs
, body
) = self.parse_inner_attrs_and_block()?
;
5100 Ok((ident
, inner_attrs
, generics
, ast
::ImplItemKind
::Method(ast
::MethodSig
{
5109 /// Parse trait Foo { ... }
5110 fn parse_item_trait(&mut self, is_auto
: IsAuto
, unsafety
: Unsafety
) -> PResult
<'a
, ItemInfo
> {
5111 let ident
= self.parse_ident()?
;
5112 let mut tps
= self.parse_generics()?
;
5114 // Parse optional colon and supertrait bounds.
5115 let bounds
= if self.eat(&token
::Colon
) {
5116 self.parse_ty_param_bounds()?
5121 tps
.where_clause
= self.parse_where_clause()?
;
5123 self.expect(&token
::OpenDelim(token
::Brace
))?
;
5124 let mut trait_items
= vec
![];
5125 while !self.eat(&token
::CloseDelim(token
::Brace
)) {
5126 let mut at_end
= false;
5127 match self.parse_trait_item(&mut at_end
) {
5128 Ok(item
) => trait_items
.push(item
),
5132 self.recover_stmt_(SemiColonMode
::Break
, BlockMode
::Break
);
5137 Ok((ident
, ItemKind
::Trait(is_auto
, unsafety
, tps
, bounds
, trait_items
), None
))
5140 /// Parses items implementations variants
5141 /// impl<T> Foo { ... }
5142 /// impl<T> ToString for &'static T { ... }
5143 /// impl Send for .. {}
5144 fn parse_item_impl(&mut self,
5145 unsafety
: ast
::Unsafety
,
5146 defaultness
: Defaultness
) -> PResult
<'a
, ItemInfo
> {
5147 let impl_span
= self.span
;
5149 // First, parse type parameters if necessary.
5150 let mut generics
= self.parse_generics()?
;
5152 // Special case: if the next identifier that follows is '(', don't
5153 // allow this to be parsed as a trait.
5154 let could_be_trait
= self.token
!= token
::OpenDelim(token
::Paren
);
5156 let neg_span
= self.span
;
5157 let polarity
= if self.eat(&token
::Not
) {
5158 ast
::ImplPolarity
::Negative
5160 ast
::ImplPolarity
::Positive
5164 let mut ty
= self.parse_ty()?
;
5166 // Parse traits, if necessary.
5167 let opt_trait
= if could_be_trait
&& self.eat_keyword(keywords
::For
) {
5168 // New-style trait. Reinterpret the type as a trait.
5170 TyKind
::Path(None
, ref path
) => {
5172 path
: (*path
).clone(),
5177 self.span_err(ty
.span
, "not a trait");
5182 if polarity
== ast
::ImplPolarity
::Negative
{
5183 // This is a negated type implementation
5184 // `impl !MyType {}`, which is not allowed.
5185 self.span_err(neg_span
, "inherent implementation can't be negated");
5190 if opt_trait
.is_some() && self.eat(&token
::DotDot
) {
5191 if generics
.is_parameterized() {
5192 self.span_err(impl_span
, "auto trait implementations are not \
5193 allowed to have generics");
5196 if let ast
::Defaultness
::Default
= defaultness
{
5197 self.span_err(impl_span
, "`default impl` is not allowed for \
5198 auto trait implementations");
5201 self.expect(&token
::OpenDelim(token
::Brace
))?
;
5202 self.expect(&token
::CloseDelim(token
::Brace
))?
;
5203 Ok((keywords
::Invalid
.ident(),
5204 ItemKind
::AutoImpl(unsafety
, opt_trait
.unwrap()), None
))
5206 if opt_trait
.is_some() {
5207 ty
= self.parse_ty()?
;
5209 generics
.where_clause
= self.parse_where_clause()?
;
5211 self.expect(&token
::OpenDelim(token
::Brace
))?
;
5212 let attrs
= self.parse_inner_attributes()?
;
5214 let mut impl_items
= vec
![];
5215 while !self.eat(&token
::CloseDelim(token
::Brace
)) {
5216 let mut at_end
= false;
5217 match self.parse_impl_item(&mut at_end
) {
5218 Ok(item
) => impl_items
.push(item
),
5222 self.recover_stmt_(SemiColonMode
::Break
, BlockMode
::Break
);
5228 Ok((keywords
::Invalid
.ident(),
5229 ItemKind
::Impl(unsafety
, polarity
, defaultness
, generics
, opt_trait
, ty
, impl_items
),
5234 fn parse_late_bound_lifetime_defs(&mut self) -> PResult
<'a
, Vec
<LifetimeDef
>> {
5235 if self.eat_keyword(keywords
::For
) {
5237 let (lifetime_defs
, ty_params
) = self.parse_generic_params()?
;
5239 if !ty_params
.is_empty() {
5240 self.span_err(ty_params
[0].span
,
5241 "only lifetime parameters can be used in this context");
5249 /// Parse struct Foo { ... }
5250 fn parse_item_struct(&mut self) -> PResult
<'a
, ItemInfo
> {
5251 let class_name
= self.parse_ident()?
;
5253 let mut generics
= self.parse_generics()?
;
5255 // There is a special case worth noting here, as reported in issue #17904.
5256 // If we are parsing a tuple struct it is the case that the where clause
5257 // should follow the field list. Like so:
5259 // struct Foo<T>(T) where T: Copy;
5261 // If we are parsing a normal record-style struct it is the case
5262 // that the where clause comes before the body, and after the generics.
5263 // So if we look ahead and see a brace or a where-clause we begin
5264 // parsing a record style struct.
5266 // Otherwise if we look ahead and see a paren we parse a tuple-style
5269 let vdata
= if self.token
.is_keyword(keywords
::Where
) {
5270 generics
.where_clause
= self.parse_where_clause()?
;
5271 if self.eat(&token
::Semi
) {
5272 // If we see a: `struct Foo<T> where T: Copy;` style decl.
5273 VariantData
::Unit(ast
::DUMMY_NODE_ID
)
5275 // If we see: `struct Foo<T> where T: Copy { ... }`
5276 VariantData
::Struct(self.parse_record_struct_body()?
, ast
::DUMMY_NODE_ID
)
5278 // No `where` so: `struct Foo<T>;`
5279 } else if self.eat(&token
::Semi
) {
5280 VariantData
::Unit(ast
::DUMMY_NODE_ID
)
5281 // Record-style struct definition
5282 } else if self.token
== token
::OpenDelim(token
::Brace
) {
5283 VariantData
::Struct(self.parse_record_struct_body()?
, ast
::DUMMY_NODE_ID
)
5284 // Tuple-style struct definition with optional where-clause.
5285 } else if self.token
== token
::OpenDelim(token
::Paren
) {
5286 let body
= VariantData
::Tuple(self.parse_tuple_struct_body()?
, ast
::DUMMY_NODE_ID
);
5287 generics
.where_clause
= self.parse_where_clause()?
;
5288 self.expect(&token
::Semi
)?
;
5291 let token_str
= self.this_token_to_string();
5292 return Err(self.fatal(&format
!("expected `where`, `{{`, `(`, or `;` after struct \
5293 name, found `{}`", token_str
)))
5296 Ok((class_name
, ItemKind
::Struct(vdata
, generics
), None
))
5299 /// Parse union Foo { ... }
5300 fn parse_item_union(&mut self) -> PResult
<'a
, ItemInfo
> {
5301 let class_name
= self.parse_ident()?
;
5303 let mut generics
= self.parse_generics()?
;
5305 let vdata
= if self.token
.is_keyword(keywords
::Where
) {
5306 generics
.where_clause
= self.parse_where_clause()?
;
5307 VariantData
::Struct(self.parse_record_struct_body()?
, ast
::DUMMY_NODE_ID
)
5308 } else if self.token
== token
::OpenDelim(token
::Brace
) {
5309 VariantData
::Struct(self.parse_record_struct_body()?
, ast
::DUMMY_NODE_ID
)
5311 let token_str
= self.this_token_to_string();
5312 return Err(self.fatal(&format
!("expected `where` or `{{` after union \
5313 name, found `{}`", token_str
)))
5316 Ok((class_name
, ItemKind
::Union(vdata
, generics
), None
))
5319 pub fn parse_record_struct_body(&mut self) -> PResult
<'a
, Vec
<StructField
>> {
5320 let mut fields
= Vec
::new();
5321 if self.eat(&token
::OpenDelim(token
::Brace
)) {
5322 while self.token
!= token
::CloseDelim(token
::Brace
) {
5323 fields
.push(self.parse_struct_decl_field().map_err(|e
| {
5324 self.recover_stmt();
5325 self.eat(&token
::CloseDelim(token
::Brace
));
5332 let token_str
= self.this_token_to_string();
5333 return Err(self.fatal(&format
!("expected `where`, or `{{` after struct \
5341 pub fn parse_tuple_struct_body(&mut self) -> PResult
<'a
, Vec
<StructField
>> {
5342 // This is the case where we find `struct Foo<T>(T) where T: Copy;`
5343 // Unit like structs are handled in parse_item_struct function
5344 let fields
= self.parse_unspanned_seq(
5345 &token
::OpenDelim(token
::Paren
),
5346 &token
::CloseDelim(token
::Paren
),
5347 SeqSep
::trailing_allowed(token
::Comma
),
5349 let attrs
= p
.parse_outer_attributes()?
;
5351 let vis
= p
.parse_visibility(true)?
;
5352 let ty
= p
.parse_ty()?
;
5354 span
: lo
.to(p
.span
),
5357 id
: ast
::DUMMY_NODE_ID
,
5366 /// Parse a structure field declaration
5367 pub fn parse_single_struct_field(&mut self,
5370 attrs
: Vec
<Attribute
> )
5371 -> PResult
<'a
, StructField
> {
5372 let a_var
= self.parse_name_and_ty(lo
, vis
, attrs
)?
;
5377 token
::CloseDelim(token
::Brace
) => {}
5378 token
::DocComment(_
) => return Err(self.span_fatal_err(self.span
,
5379 Error
::UselessDocComment
)),
5380 _
=> return Err(self.span_fatal_help(self.span
,
5381 &format
!("expected `,`, or `}}`, found `{}`", self.this_token_to_string()),
5382 "struct fields should be separated by commas")),
5387 /// Parse an element of a struct definition
5388 fn parse_struct_decl_field(&mut self) -> PResult
<'a
, StructField
> {
5389 let attrs
= self.parse_outer_attributes()?
;
5391 let vis
= self.parse_visibility(false)?
;
5392 self.parse_single_struct_field(lo
, vis
, attrs
)
5395 /// Parse `pub`, `pub(crate)` and `pub(in path)` plus shortcuts `pub(self)` for `pub(in self)`
5396 /// and `pub(super)` for `pub(in super)`. If the following element can't be a tuple (i.e. it's
5397 /// a function definition, it's not a tuple struct field) and the contents within the parens
5398 /// isn't valid, emit a proper diagnostic.
5399 pub fn parse_visibility(&mut self, can_take_tuple
: bool
) -> PResult
<'a
, Visibility
> {
5400 maybe_whole
!(self, NtVis
, |x
| x
);
5402 if self.eat_keyword(keywords
::Crate
) {
5403 return Ok(Visibility
::Crate(self.prev_span
, CrateSugar
::JustCrate
));
5406 if !self.eat_keyword(keywords
::Pub
) {
5407 return Ok(Visibility
::Inherited
)
5410 if self.check(&token
::OpenDelim(token
::Paren
)) {
5411 // We don't `self.bump()` the `(` yet because this might be a struct definition where
5412 // `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`.
5413 // Because of this, we only `bump` the `(` if we're assured it is appropriate to do so
5414 // by the following tokens.
5415 if self.look_ahead(1, |t
| t
.is_keyword(keywords
::Crate
)) {
5418 self.bump(); // `crate`
5419 let vis
= Visibility
::Crate(self.prev_span
, CrateSugar
::PubCrate
);
5420 self.expect(&token
::CloseDelim(token
::Paren
))?
; // `)`
5422 } else if self.look_ahead(1, |t
| t
.is_keyword(keywords
::In
)) {
5425 self.bump(); // `in`
5426 let path
= self.parse_path(PathStyle
::Mod
)?
.default_to_global(); // `path`
5427 let vis
= Visibility
::Restricted { path: P(path), id: ast::DUMMY_NODE_ID }
;
5428 self.expect(&token
::CloseDelim(token
::Paren
))?
; // `)`
5430 } else if self.look_ahead(2, |t
| t
== &token
::CloseDelim(token
::Paren
)) &&
5431 self.look_ahead(1, |t
| t
.is_keyword(keywords
::Super
) ||
5432 t
.is_keyword(keywords
::SelfValue
)) {
5433 // `pub(self)` or `pub(super)`
5435 let path
= self.parse_path(PathStyle
::Mod
)?
.default_to_global(); // `super`/`self`
5436 let vis
= Visibility
::Restricted { path: P(path), id: ast::DUMMY_NODE_ID }
;
5437 self.expect(&token
::CloseDelim(token
::Paren
))?
; // `)`
5439 } else if !can_take_tuple
{ // Provide this diagnostic if this is not a tuple struct
5440 // `pub(something) fn ...` or `struct X { pub(something) y: Z }`
5442 let msg
= "incorrect visibility restriction";
5443 let suggestion
= r
##"some possible visibility restrictions are:
5444 `pub(crate)`: visible only on the current crate
5445 `pub(super)`: visible only in the current module's parent
5446 `pub(in path::to::module)`: visible only on the specified path"##;
5447 let path
= self.parse_path(PathStyle
::Mod
)?
;
5448 let path_span
= self.prev_span
;
5449 let help_msg
= format
!("make this visible only to module `{}` with `in`", path
);
5450 self.expect(&token
::CloseDelim(token
::Paren
))?
; // `)`
5451 let mut err
= self.span_fatal_help(path_span
, msg
, suggestion
);
5452 err
.span_suggestion(path_span
, &help_msg
, format
!("in {}", path
));
5453 err
.emit(); // emit diagnostic, but continue with public visibility
5457 Ok(Visibility
::Public
)
5460 /// Parse defaultness: DEFAULT or nothing
5461 fn parse_defaultness(&mut self) -> PResult
<'a
, Defaultness
> {
5462 if self.eat_defaultness() {
5463 Ok(Defaultness
::Default
)
5465 Ok(Defaultness
::Final
)
5469 /// Given a termination token, parse all of the items in a module
5470 fn parse_mod_items(&mut self, term
: &token
::Token
, inner_lo
: Span
) -> PResult
<'a
, Mod
> {
5471 let mut items
= vec
![];
5472 while let Some(item
) = self.parse_item()?
{
5476 if !self.eat(term
) {
5477 let token_str
= self.this_token_to_string();
5478 return Err(self.fatal(&format
!("expected item, found `{}`", token_str
)));
5481 let hi
= if self.span
== syntax_pos
::DUMMY_SP
{
5488 inner
: inner_lo
.to(hi
),
5493 fn parse_item_const(&mut self, m
: Option
<Mutability
>) -> PResult
<'a
, ItemInfo
> {
5494 let id
= self.parse_ident()?
;
5495 self.expect(&token
::Colon
)?
;
5496 let ty
= self.parse_ty()?
;
5497 self.expect(&token
::Eq
)?
;
5498 let e
= self.parse_expr()?
;
5499 self.expect(&token
::Semi
)?
;
5500 let item
= match m
{
5501 Some(m
) => ItemKind
::Static(ty
, m
, e
),
5502 None
=> ItemKind
::Const(ty
, e
),
5504 Ok((id
, item
, None
))
5507 /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
5508 fn parse_item_mod(&mut self, outer_attrs
: &[Attribute
]) -> PResult
<'a
, ItemInfo
> {
5509 let (in_cfg
, outer_attrs
) = {
5510 let mut strip_unconfigured
= ::config
::StripUnconfigured
{
5512 should_test
: false, // irrelevant
5513 features
: None
, // don't perform gated feature checking
5515 let outer_attrs
= strip_unconfigured
.process_cfg_attrs(outer_attrs
.to_owned());
5516 (!self.cfg_mods
|| strip_unconfigured
.in_cfg(&outer_attrs
), outer_attrs
)
5519 let id_span
= self.span
;
5520 let id
= self.parse_ident()?
;
5521 if self.check(&token
::Semi
) {
5523 if in_cfg
&& self.recurse_into_file_modules
{
5524 // This mod is in an external file. Let's go get it!
5525 let ModulePathSuccess { path, directory_ownership, warn }
=
5526 self.submod_path(id
, &outer_attrs
, id_span
)?
;
5527 let (module
, mut attrs
) =
5528 self.eval_src_mod(path
, directory_ownership
, id
.to_string(), id_span
)?
;
5530 let attr
= ast
::Attribute
{
5531 id
: attr
::mk_attr_id(),
5532 style
: ast
::AttrStyle
::Outer
,
5533 path
: ast
::Path
::from_ident(syntax_pos
::DUMMY_SP
,
5534 Ident
::from_str("warn_directory_ownership")),
5535 tokens
: TokenStream
::empty(),
5536 is_sugared_doc
: false,
5537 span
: syntax_pos
::DUMMY_SP
,
5539 attr
::mark_known(&attr
);
5542 Ok((id
, module
, Some(attrs
)))
5544 let placeholder
= ast
::Mod { inner: syntax_pos::DUMMY_SP, items: Vec::new() }
;
5545 Ok((id
, ItemKind
::Mod(placeholder
), None
))
5548 let old_directory
= self.directory
.clone();
5549 self.push_directory(id
, &outer_attrs
);
5551 self.expect(&token
::OpenDelim(token
::Brace
))?
;
5552 let mod_inner_lo
= self.span
;
5553 let attrs
= self.parse_inner_attributes()?
;
5554 let module
= self.parse_mod_items(&token
::CloseDelim(token
::Brace
), mod_inner_lo
)?
;
5556 self.directory
= old_directory
;
5557 Ok((id
, ItemKind
::Mod(module
), Some(attrs
)))
5561 fn push_directory(&mut self, id
: Ident
, attrs
: &[Attribute
]) {
5562 if let Some(path
) = attr
::first_attr_value_str_by_name(attrs
, "path") {
5563 self.directory
.path
.push(&path
.as_str());
5564 self.directory
.ownership
= DirectoryOwnership
::Owned
;
5566 self.directory
.path
.push(&id
.name
.as_str());
5570 pub fn submod_path_from_attr(attrs
: &[ast
::Attribute
], dir_path
: &Path
) -> Option
<PathBuf
> {
5571 attr
::first_attr_value_str_by_name(attrs
, "path").map(|d
| dir_path
.join(&d
.as_str()))
5574 /// Returns either a path to a module, or .
5575 pub fn default_submod_path(id
: ast
::Ident
, dir_path
: &Path
, codemap
: &CodeMap
) -> ModulePath
{
5576 let mod_name
= id
.to_string();
5577 let default_path_str
= format
!("{}.rs", mod_name
);
5578 let secondary_path_str
= format
!("{}{}mod.rs", mod_name
, path
::MAIN_SEPARATOR
);
5579 let default_path
= dir_path
.join(&default_path_str
);
5580 let secondary_path
= dir_path
.join(&secondary_path_str
);
5581 let default_exists
= codemap
.file_exists(&default_path
);
5582 let secondary_exists
= codemap
.file_exists(&secondary_path
);
5584 let result
= match (default_exists
, secondary_exists
) {
5585 (true, false) => Ok(ModulePathSuccess
{
5587 directory_ownership
: DirectoryOwnership
::UnownedViaMod(false),
5590 (false, true) => Ok(ModulePathSuccess
{
5591 path
: secondary_path
,
5592 directory_ownership
: DirectoryOwnership
::Owned
,
5595 (false, false) => Err(Error
::FileNotFoundForModule
{
5596 mod_name
: mod_name
.clone(),
5597 default_path
: default_path_str
,
5598 secondary_path
: secondary_path_str
,
5599 dir_path
: format
!("{}", dir_path
.display()),
5601 (true, true) => Err(Error
::DuplicatePaths
{
5602 mod_name
: mod_name
.clone(),
5603 default_path
: default_path_str
,
5604 secondary_path
: secondary_path_str
,
5610 path_exists
: default_exists
|| secondary_exists
,
5615 fn submod_path(&mut self,
5617 outer_attrs
: &[ast
::Attribute
],
5619 -> PResult
<'a
, ModulePathSuccess
> {
5620 if let Some(path
) = Parser
::submod_path_from_attr(outer_attrs
, &self.directory
.path
) {
5621 return Ok(ModulePathSuccess
{
5622 directory_ownership
: match path
.file_name().and_then(|s
| s
.to_str()) {
5623 Some("mod.rs") => DirectoryOwnership
::Owned
,
5624 _
=> DirectoryOwnership
::UnownedViaMod(true),
5631 let paths
= Parser
::default_submod_path(id
, &self.directory
.path
, self.sess
.codemap());
5633 if let DirectoryOwnership
::UnownedViaBlock
= self.directory
.ownership
{
5635 "Cannot declare a non-inline module inside a block unless it has a path attribute";
5636 let mut err
= self.diagnostic().struct_span_err(id_sp
, msg
);
5637 if paths
.path_exists
{
5638 let msg
= format
!("Maybe `use` the module `{}` instead of redeclaring it",
5640 err
.span_note(id_sp
, &msg
);
5643 } else if let DirectoryOwnership
::UnownedViaMod(warn
) = self.directory
.ownership
{
5645 if let Ok(result
) = paths
.result
{
5646 return Ok(ModulePathSuccess { warn: true, ..result }
);
5649 let mut err
= self.diagnostic().struct_span_err(id_sp
,
5650 "cannot declare a new module at this location");
5651 if id_sp
!= syntax_pos
::DUMMY_SP
{
5652 let src_path
= PathBuf
::from(self.sess
.codemap().span_to_filename(id_sp
));
5653 if let Some(stem
) = src_path
.file_stem() {
5654 let mut dest_path
= src_path
.clone();
5655 dest_path
.set_file_name(stem
);
5656 dest_path
.push("mod.rs");
5657 err
.span_note(id_sp
,
5658 &format
!("maybe move this module `{}` to its own \
5659 directory via `{}`", src_path
.to_string_lossy(),
5660 dest_path
.to_string_lossy()));
5663 if paths
.path_exists
{
5664 err
.span_note(id_sp
,
5665 &format
!("... or maybe `use` the module `{}` instead \
5666 of possibly redeclaring it",
5671 paths
.result
.map_err(|err
| self.span_fatal_err(id_sp
, err
))
5675 /// Read a module from a source file.
5676 fn eval_src_mod(&mut self,
5678 directory_ownership
: DirectoryOwnership
,
5681 -> PResult
<'a
, (ast
::ItemKind
, Vec
<ast
::Attribute
> )> {
5682 let mut included_mod_stack
= self.sess
.included_mod_stack
.borrow_mut();
5683 if let Some(i
) = included_mod_stack
.iter().position(|p
| *p
== path
) {
5684 let mut err
= String
::from("circular modules: ");
5685 let len
= included_mod_stack
.len();
5686 for p
in &included_mod_stack
[i
.. len
] {
5687 err
.push_str(&p
.to_string_lossy());
5688 err
.push_str(" -> ");
5690 err
.push_str(&path
.to_string_lossy());
5691 return Err(self.span_fatal(id_sp
, &err
[..]));
5693 included_mod_stack
.push(path
.clone());
5694 drop(included_mod_stack
);
5697 new_sub_parser_from_file(self.sess
, &path
, directory_ownership
, Some(name
), id_sp
);
5698 p0
.cfg_mods
= self.cfg_mods
;
5699 let mod_inner_lo
= p0
.span
;
5700 let mod_attrs
= p0
.parse_inner_attributes()?
;
5701 let m0
= p0
.parse_mod_items(&token
::Eof
, mod_inner_lo
)?
;
5702 self.sess
.included_mod_stack
.borrow_mut().pop();
5703 Ok((ast
::ItemKind
::Mod(m0
), mod_attrs
))
5706 /// Parse a function declaration from a foreign module
5707 fn parse_item_foreign_fn(&mut self, vis
: ast
::Visibility
, lo
: Span
, attrs
: Vec
<Attribute
>)
5708 -> PResult
<'a
, ForeignItem
> {
5709 self.expect_keyword(keywords
::Fn
)?
;
5711 let (ident
, mut generics
) = self.parse_fn_header()?
;
5712 let decl
= self.parse_fn_decl(true)?
;
5713 generics
.where_clause
= self.parse_where_clause()?
;
5715 self.expect(&token
::Semi
)?
;
5716 Ok(ast
::ForeignItem
{
5719 node
: ForeignItemKind
::Fn(decl
, generics
),
5720 id
: ast
::DUMMY_NODE_ID
,
5726 /// Parse a static item from a foreign module.
5727 /// Assumes that the `static` keyword is already parsed.
5728 fn parse_item_foreign_static(&mut self, vis
: ast
::Visibility
, lo
: Span
, attrs
: Vec
<Attribute
>)
5729 -> PResult
<'a
, ForeignItem
> {
5730 let mutbl
= self.eat_keyword(keywords
::Mut
);
5731 let ident
= self.parse_ident()?
;
5732 self.expect(&token
::Colon
)?
;
5733 let ty
= self.parse_ty()?
;
5735 self.expect(&token
::Semi
)?
;
5739 node
: ForeignItemKind
::Static(ty
, mutbl
),
5740 id
: ast
::DUMMY_NODE_ID
,
5746 /// Parse a type from a foreign module
5747 fn parse_item_foreign_type(&mut self, vis
: ast
::Visibility
, lo
: Span
, attrs
: Vec
<Attribute
>)
5748 -> PResult
<'a
, ForeignItem
> {
5749 self.expect_keyword(keywords
::Type
)?
;
5751 let ident
= self.parse_ident()?
;
5753 self.expect(&token
::Semi
)?
;
5754 Ok(ast
::ForeignItem
{
5757 node
: ForeignItemKind
::Ty
,
5758 id
: ast
::DUMMY_NODE_ID
,
5764 /// Parse extern crate links
5768 /// extern crate foo;
5769 /// extern crate bar as foo;
5770 fn parse_item_extern_crate(&mut self,
5772 visibility
: Visibility
,
5773 attrs
: Vec
<Attribute
>)
5774 -> PResult
<'a
, P
<Item
>> {
5776 let crate_name
= self.parse_ident()?
;
5777 let (maybe_path
, ident
) = if let Some(ident
) = self.parse_rename()?
{
5778 (Some(crate_name
.name
), ident
)
5782 self.expect(&token
::Semi
)?
;
5784 let prev_span
= self.prev_span
;
5785 Ok(self.mk_item(lo
.to(prev_span
),
5787 ItemKind
::ExternCrate(maybe_path
),
5792 /// Parse `extern` for foreign ABIs
5795 /// `extern` is expected to have been
5796 /// consumed before calling this method
5802 fn parse_item_foreign_mod(&mut self,
5804 opt_abi
: Option
<abi
::Abi
>,
5805 visibility
: Visibility
,
5806 mut attrs
: Vec
<Attribute
>)
5807 -> PResult
<'a
, P
<Item
>> {
5808 self.expect(&token
::OpenDelim(token
::Brace
))?
;
5810 let abi
= opt_abi
.unwrap_or(Abi
::C
);
5812 attrs
.extend(self.parse_inner_attributes()?
);
5814 let mut foreign_items
= vec
![];
5815 while let Some(item
) = self.parse_foreign_item()?
{
5816 foreign_items
.push(item
);
5818 self.expect(&token
::CloseDelim(token
::Brace
))?
;
5820 let prev_span
= self.prev_span
;
5821 let m
= ast
::ForeignMod
{
5823 items
: foreign_items
5825 let invalid
= keywords
::Invalid
.ident();
5826 Ok(self.mk_item(lo
.to(prev_span
), invalid
, ItemKind
::ForeignMod(m
), visibility
, attrs
))
5829 /// Parse type Foo = Bar;
5830 fn parse_item_type(&mut self) -> PResult
<'a
, ItemInfo
> {
5831 let ident
= self.parse_ident()?
;
5832 let mut tps
= self.parse_generics()?
;
5833 tps
.where_clause
= self.parse_where_clause()?
;
5834 self.expect(&token
::Eq
)?
;
5835 let ty
= self.parse_ty()?
;
5836 self.expect(&token
::Semi
)?
;
5837 Ok((ident
, ItemKind
::Ty(ty
, tps
), None
))
5840 /// Parse the part of an "enum" decl following the '{'
5841 fn parse_enum_def(&mut self, _generics
: &ast
::Generics
) -> PResult
<'a
, EnumDef
> {
5842 let mut variants
= Vec
::new();
5843 let mut all_nullary
= true;
5844 let mut any_disr
= None
;
5845 while self.token
!= token
::CloseDelim(token
::Brace
) {
5846 let variant_attrs
= self.parse_outer_attributes()?
;
5847 let vlo
= self.span
;
5850 let mut disr_expr
= None
;
5851 let ident
= self.parse_ident()?
;
5852 if self.check(&token
::OpenDelim(token
::Brace
)) {
5853 // Parse a struct variant.
5854 all_nullary
= false;
5855 struct_def
= VariantData
::Struct(self.parse_record_struct_body()?
,
5856 ast
::DUMMY_NODE_ID
);
5857 } else if self.check(&token
::OpenDelim(token
::Paren
)) {
5858 all_nullary
= false;
5859 struct_def
= VariantData
::Tuple(self.parse_tuple_struct_body()?
,
5860 ast
::DUMMY_NODE_ID
);
5861 } else if self.eat(&token
::Eq
) {
5862 disr_expr
= Some(self.parse_expr()?
);
5863 any_disr
= disr_expr
.as_ref().map(|expr
| expr
.span
);
5864 struct_def
= VariantData
::Unit(ast
::DUMMY_NODE_ID
);
5866 struct_def
= VariantData
::Unit(ast
::DUMMY_NODE_ID
);
5869 let vr
= ast
::Variant_
{
5871 attrs
: variant_attrs
,
5875 variants
.push(respan(vlo
.to(self.prev_span
), vr
));
5877 if !self.eat(&token
::Comma
) { break; }
5879 self.expect(&token
::CloseDelim(token
::Brace
))?
;
5881 Some(disr_span
) if !all_nullary
=>
5882 self.span_err(disr_span
,
5883 "discriminator values can only be used with a c-like enum"),
5887 Ok(ast
::EnumDef { variants: variants }
)
5890 /// Parse an "enum" declaration
5891 fn parse_item_enum(&mut self) -> PResult
<'a
, ItemInfo
> {
5892 let id
= self.parse_ident()?
;
5893 let mut generics
= self.parse_generics()?
;
5894 generics
.where_clause
= self.parse_where_clause()?
;
5895 self.expect(&token
::OpenDelim(token
::Brace
))?
;
5897 let enum_definition
= self.parse_enum_def(&generics
).map_err(|e
| {
5898 self.recover_stmt();
5899 self.eat(&token
::CloseDelim(token
::Brace
));
5902 Ok((id
, ItemKind
::Enum(enum_definition
, generics
), None
))
5905 /// Parses a string as an ABI spec on an extern type or module. Consumes
5906 /// the `extern` keyword, if one is found.
5907 fn parse_opt_abi(&mut self) -> PResult
<'a
, Option
<abi
::Abi
>> {
5909 token
::Literal(token
::Str_(s
), suf
) | token
::Literal(token
::StrRaw(s
, _
), suf
) => {
5911 self.expect_no_suffix(sp
, "ABI spec", suf
);
5913 match abi
::lookup(&s
.as_str()) {
5914 Some(abi
) => Ok(Some(abi
)),
5916 let prev_span
= self.prev_span
;
5919 &format
!("invalid ABI: expected one of [{}], \
5921 abi
::all_names().join(", "),
5932 /// Parse one of the items allowed by the flags.
5933 /// NB: this function no longer parses the items inside an
5935 fn parse_item_(&mut self, attrs
: Vec
<Attribute
>,
5936 macros_allowed
: bool
, attributes_allowed
: bool
) -> PResult
<'a
, Option
<P
<Item
>>> {
5937 maybe_whole
!(self, NtItem
, |item
| {
5938 let mut item
= item
.unwrap();
5939 let mut attrs
= attrs
;
5940 mem
::swap(&mut item
.attrs
, &mut attrs
);
5941 item
.attrs
.extend(attrs
);
5947 let visibility
= self.parse_visibility(false)?
;
5949 if self.eat_keyword(keywords
::Use
) {
5951 let item_
= ItemKind
::Use(self.parse_view_path()?
);
5952 self.expect(&token
::Semi
)?
;
5954 let prev_span
= self.prev_span
;
5955 let invalid
= keywords
::Invalid
.ident();
5956 let item
= self.mk_item(lo
.to(prev_span
), invalid
, item_
, visibility
, attrs
);
5957 return Ok(Some(item
));
5960 if self.eat_keyword(keywords
::Extern
) {
5961 if self.eat_keyword(keywords
::Crate
) {
5962 return Ok(Some(self.parse_item_extern_crate(lo
, visibility
, attrs
)?
));
5965 let opt_abi
= self.parse_opt_abi()?
;
5967 if self.eat_keyword(keywords
::Fn
) {
5968 // EXTERN FUNCTION ITEM
5969 let fn_span
= self.prev_span
;
5970 let abi
= opt_abi
.unwrap_or(Abi
::C
);
5971 let (ident
, item_
, extra_attrs
) =
5972 self.parse_item_fn(Unsafety
::Normal
,
5973 respan(fn_span
, Constness
::NotConst
),
5975 let prev_span
= self.prev_span
;
5976 let item
= self.mk_item(lo
.to(prev_span
),
5980 maybe_append(attrs
, extra_attrs
));
5981 return Ok(Some(item
));
5982 } else if self.check(&token
::OpenDelim(token
::Brace
)) {
5983 return Ok(Some(self.parse_item_foreign_mod(lo
, opt_abi
, visibility
, attrs
)?
));
5989 if self.eat_keyword(keywords
::Static
) {
5991 let m
= if self.eat_keyword(keywords
::Mut
) {
5994 Mutability
::Immutable
5996 let (ident
, item_
, extra_attrs
) = self.parse_item_const(Some(m
))?
;
5997 let prev_span
= self.prev_span
;
5998 let item
= self.mk_item(lo
.to(prev_span
),
6002 maybe_append(attrs
, extra_attrs
));
6003 return Ok(Some(item
));
6005 if self.eat_keyword(keywords
::Const
) {
6006 let const_span
= self.prev_span
;
6007 if self.check_keyword(keywords
::Fn
)
6008 || (self.check_keyword(keywords
::Unsafe
)
6009 && self.look_ahead(1, |t
| t
.is_keyword(keywords
::Fn
))) {
6010 // CONST FUNCTION ITEM
6011 let unsafety
= if self.eat_keyword(keywords
::Unsafe
) {
6017 let (ident
, item_
, extra_attrs
) =
6018 self.parse_item_fn(unsafety
,
6019 respan(const_span
, Constness
::Const
),
6021 let prev_span
= self.prev_span
;
6022 let item
= self.mk_item(lo
.to(prev_span
),
6026 maybe_append(attrs
, extra_attrs
));
6027 return Ok(Some(item
));
6031 if self.eat_keyword(keywords
::Mut
) {
6032 let prev_span
= self.prev_span
;
6033 self.diagnostic().struct_span_err(prev_span
, "const globals cannot be mutable")
6034 .help("did you mean to declare a static?")
6037 let (ident
, item_
, extra_attrs
) = self.parse_item_const(None
)?
;
6038 let prev_span
= self.prev_span
;
6039 let item
= self.mk_item(lo
.to(prev_span
),
6043 maybe_append(attrs
, extra_attrs
));
6044 return Ok(Some(item
));
6046 if self.check_keyword(keywords
::Unsafe
) &&
6047 (self.look_ahead(1, |t
| t
.is_keyword(keywords
::Trait
)) ||
6048 self.look_ahead(1, |t
| t
.is_keyword(keywords
::Auto
)))
6050 // UNSAFE TRAIT ITEM
6051 self.expect_keyword(keywords
::Unsafe
)?
;
6052 let is_auto
= if self.eat_keyword(keywords
::Trait
) {
6055 self.eat_auto_trait();
6058 let (ident
, item_
, extra_attrs
) =
6059 self.parse_item_trait(is_auto
, ast
::Unsafety
::Unsafe
)?
;
6060 let prev_span
= self.prev_span
;
6061 let item
= self.mk_item(lo
.to(prev_span
),
6065 maybe_append(attrs
, extra_attrs
));
6066 return Ok(Some(item
));
6068 if (self.check_keyword(keywords
::Unsafe
) &&
6069 self.look_ahead(1, |t
| t
.is_keyword(keywords
::Impl
))) ||
6070 (self.check_keyword(keywords
::Default
) &&
6071 self.look_ahead(1, |t
| t
.is_keyword(keywords
::Unsafe
)) &&
6072 self.look_ahead(2, |t
| t
.is_keyword(keywords
::Impl
)))
6075 let defaultness
= self.parse_defaultness()?
;
6076 self.expect_keyword(keywords
::Unsafe
)?
;
6077 self.expect_keyword(keywords
::Impl
)?
;
6080 extra_attrs
) = self.parse_item_impl(ast
::Unsafety
::Unsafe
, defaultness
)?
;
6081 let prev_span
= self.prev_span
;
6082 let item
= self.mk_item(lo
.to(prev_span
),
6086 maybe_append(attrs
, extra_attrs
));
6087 return Ok(Some(item
));
6089 if self.check_keyword(keywords
::Fn
) {
6092 let fn_span
= self.prev_span
;
6093 let (ident
, item_
, extra_attrs
) =
6094 self.parse_item_fn(Unsafety
::Normal
,
6095 respan(fn_span
, Constness
::NotConst
),
6097 let prev_span
= self.prev_span
;
6098 let item
= self.mk_item(lo
.to(prev_span
),
6102 maybe_append(attrs
, extra_attrs
));
6103 return Ok(Some(item
));
6105 if self.check_keyword(keywords
::Unsafe
)
6106 && self.look_ahead(1, |t
| *t
!= token
::OpenDelim(token
::Brace
)) {
6107 // UNSAFE FUNCTION ITEM
6109 let abi
= if self.eat_keyword(keywords
::Extern
) {
6110 self.parse_opt_abi()?
.unwrap_or(Abi
::C
)
6114 self.expect_keyword(keywords
::Fn
)?
;
6115 let fn_span
= self.prev_span
;
6116 let (ident
, item_
, extra_attrs
) =
6117 self.parse_item_fn(Unsafety
::Unsafe
,
6118 respan(fn_span
, Constness
::NotConst
),
6120 let prev_span
= self.prev_span
;
6121 let item
= self.mk_item(lo
.to(prev_span
),
6125 maybe_append(attrs
, extra_attrs
));
6126 return Ok(Some(item
));
6128 if self.eat_keyword(keywords
::Mod
) {
6130 let (ident
, item_
, extra_attrs
) =
6131 self.parse_item_mod(&attrs
[..])?
;
6132 let prev_span
= self.prev_span
;
6133 let item
= self.mk_item(lo
.to(prev_span
),
6137 maybe_append(attrs
, extra_attrs
));
6138 return Ok(Some(item
));
6140 if self.eat_keyword(keywords
::Type
) {
6142 let (ident
, item_
, extra_attrs
) = self.parse_item_type()?
;
6143 let prev_span
= self.prev_span
;
6144 let item
= self.mk_item(lo
.to(prev_span
),
6148 maybe_append(attrs
, extra_attrs
));
6149 return Ok(Some(item
));
6151 if self.eat_keyword(keywords
::Enum
) {
6153 let (ident
, item_
, extra_attrs
) = self.parse_item_enum()?
;
6154 let prev_span
= self.prev_span
;
6155 let item
= self.mk_item(lo
.to(prev_span
),
6159 maybe_append(attrs
, extra_attrs
));
6160 return Ok(Some(item
));
6162 if self.check_keyword(keywords
::Trait
)
6163 || (self.check_keyword(keywords
::Auto
)
6164 && self.look_ahead(1, |t
| t
.is_keyword(keywords
::Trait
)))
6166 let is_auto
= if self.eat_keyword(keywords
::Trait
) {
6169 self.eat_auto_trait();
6173 let (ident
, item_
, extra_attrs
) =
6174 self.parse_item_trait(is_auto
, ast
::Unsafety
::Normal
)?
;
6175 let prev_span
= self.prev_span
;
6176 let item
= self.mk_item(lo
.to(prev_span
),
6180 maybe_append(attrs
, extra_attrs
));
6181 return Ok(Some(item
));
6183 if (self.check_keyword(keywords
::Impl
)) ||
6184 (self.check_keyword(keywords
::Default
) &&
6185 self.look_ahead(1, |t
| t
.is_keyword(keywords
::Impl
)))
6188 let defaultness
= self.parse_defaultness()?
;
6189 self.expect_keyword(keywords
::Impl
)?
;
6192 extra_attrs
) = self.parse_item_impl(ast
::Unsafety
::Normal
, defaultness
)?
;
6193 let prev_span
= self.prev_span
;
6194 let item
= self.mk_item(lo
.to(prev_span
),
6198 maybe_append(attrs
, extra_attrs
));
6199 return Ok(Some(item
));
6201 if self.eat_keyword(keywords
::Struct
) {
6203 let (ident
, item_
, extra_attrs
) = self.parse_item_struct()?
;
6204 let prev_span
= self.prev_span
;
6205 let item
= self.mk_item(lo
.to(prev_span
),
6209 maybe_append(attrs
, extra_attrs
));
6210 return Ok(Some(item
));
6212 if self.is_union_item() {
6215 let (ident
, item_
, extra_attrs
) = self.parse_item_union()?
;
6216 let prev_span
= self.prev_span
;
6217 let item
= self.mk_item(lo
.to(prev_span
),
6221 maybe_append(attrs
, extra_attrs
));
6222 return Ok(Some(item
));
6224 if let Some(macro_def
) = self.eat_macro_def(&attrs
, &visibility
, lo
)?
{
6225 return Ok(Some(macro_def
));
6228 self.parse_macro_use_or_failure(attrs
,macros_allowed
,attributes_allowed
,lo
,visibility
)
6231 /// Parse a foreign item.
6232 fn parse_foreign_item(&mut self) -> PResult
<'a
, Option
<ForeignItem
>> {
6233 let attrs
= self.parse_outer_attributes()?
;
6235 let visibility
= self.parse_visibility(false)?
;
6237 // FOREIGN STATIC ITEM
6238 // Treat `const` as `static` for error recovery, but don't add it to expected tokens.
6239 if self.check_keyword(keywords
::Static
) || self.token
.is_keyword(keywords
::Const
) {
6240 if self.token
.is_keyword(keywords
::Const
) {
6242 .struct_span_err(self.span
, "extern items cannot be `const`")
6243 .span_suggestion(self.span
, "instead try using", "static".to_owned())
6246 self.bump(); // `static` or `const`
6247 return Ok(Some(self.parse_item_foreign_static(visibility
, lo
, attrs
)?
));
6249 // FOREIGN FUNCTION ITEM
6250 if self.check_keyword(keywords
::Fn
) {
6251 return Ok(Some(self.parse_item_foreign_fn(visibility
, lo
, attrs
)?
));
6253 // FOREIGN TYPE ITEM
6254 if self.check_keyword(keywords
::Type
) {
6255 return Ok(Some(self.parse_item_foreign_type(visibility
, lo
, attrs
)?
));
6258 // FIXME #5668: this will occur for a macro invocation:
6259 match self.parse_macro_use_or_failure(attrs
, true, false, lo
, visibility
)?
{
6261 return Err(self.span_fatal(item
.span
, "macros cannot expand to foreign items"));
6267 /// This is the fall-through for parsing items.
6268 fn parse_macro_use_or_failure(
6270 attrs
: Vec
<Attribute
> ,
6271 macros_allowed
: bool
,
6272 attributes_allowed
: bool
,
6274 visibility
: Visibility
6275 ) -> PResult
<'a
, Option
<P
<Item
>>> {
6276 if macros_allowed
&& self.token
.is_path_start() {
6277 // MACRO INVOCATION ITEM
6279 let prev_span
= self.prev_span
;
6280 self.complain_if_pub_macro(&visibility
, prev_span
);
6282 let mac_lo
= self.span
;
6285 let pth
= self.parse_path(PathStyle
::Mod
)?
;
6286 self.expect(&token
::Not
)?
;
6288 // a 'special' identifier (like what `macro_rules!` uses)
6289 // is optional. We should eventually unify invoc syntax
6291 let id
= if self.token
.is_ident() {
6294 keywords
::Invalid
.ident() // no special identifier
6296 // eat a matched-delimiter token tree:
6297 let (delim
, tts
) = self.expect_delimited_token_tree()?
;
6298 if delim
!= token
::Brace
{
6299 if !self.eat(&token
::Semi
) {
6300 self.span_err(self.prev_span
,
6301 "macros that expand to items must either \
6302 be surrounded with braces or followed by \
6307 let hi
= self.prev_span
;
6308 let mac
= respan(mac_lo
.to(hi
), Mac_ { path: pth, tts: tts }
);
6309 let item
= self.mk_item(lo
.to(hi
), id
, ItemKind
::Mac(mac
), visibility
, attrs
);
6310 return Ok(Some(item
));
6313 // FAILURE TO PARSE ITEM
6315 Visibility
::Inherited
=> {}
6317 return Err(self.span_fatal(self.prev_span
, "unmatched visibility `pub`"));
6321 if !attributes_allowed
&& !attrs
.is_empty() {
6322 self.expected_item_err(&attrs
);
6327 fn collect_tokens
<F
, R
>(&mut self, f
: F
) -> PResult
<'a
, (R
, TokenStream
)>
6328 where F
: FnOnce(&mut Self) -> PResult
<'a
, R
>
6330 // Record all tokens we parse when parsing this item.
6331 let mut tokens
= Vec
::new();
6332 match self.token_cursor
.frame
.last_token
{
6333 LastToken
::Collecting(_
) => {
6334 panic
!("cannot collect tokens recursively yet")
6336 LastToken
::Was(ref mut last
) => tokens
.extend(last
.take()),
6338 self.token_cursor
.frame
.last_token
= LastToken
::Collecting(tokens
);
6339 let prev
= self.token_cursor
.stack
.len();
6341 let last_token
= if self.token_cursor
.stack
.len() == prev
{
6342 &mut self.token_cursor
.frame
.last_token
6344 &mut self.token_cursor
.stack
[prev
].last_token
6346 let mut tokens
= match *last_token
{
6347 LastToken
::Collecting(ref mut v
) => mem
::replace(v
, Vec
::new()),
6348 LastToken
::Was(_
) => panic
!("our vector went away?"),
6351 // If we're not at EOF our current token wasn't actually consumed by
6352 // `f`, but it'll still be in our list that we pulled out. In that case
6354 if self.token
== token
::Eof
{
6355 *last_token
= LastToken
::Was(None
);
6357 *last_token
= LastToken
::Was(tokens
.pop());
6360 Ok((ret?
, tokens
.into_iter().collect()))
6363 pub fn parse_item(&mut self) -> PResult
<'a
, Option
<P
<Item
>>> {
6364 let attrs
= self.parse_outer_attributes()?
;
6366 let (ret
, tokens
) = self.collect_tokens(|this
| {
6367 this
.parse_item_(attrs
, true, false)
6370 // Once we've parsed an item and recorded the tokens we got while
6371 // parsing we may want to store `tokens` into the item we're about to
6372 // return. Note, though, that we specifically didn't capture tokens
6373 // related to outer attributes. The `tokens` field here may later be
6374 // used with procedural macros to convert this item back into a token
6375 // stream, but during expansion we may be removing attributes as we go
6378 // If we've got inner attributes then the `tokens` we've got above holds
6379 // these inner attributes. If an inner attribute is expanded we won't
6380 // actually remove it from the token stream, so we'll just keep yielding
6381 // it (bad!). To work around this case for now we just avoid recording
6382 // `tokens` if we detect any inner attributes. This should help keep
6383 // expansion correct, but we should fix this bug one day!
6386 if !i
.attrs
.iter().any(|attr
| attr
.style
== AttrStyle
::Inner
) {
6387 i
.tokens
= Some(tokens
);
6394 fn parse_path_list_items(&mut self) -> PResult
<'a
, Vec
<ast
::PathListItem
>> {
6395 self.parse_unspanned_seq(&token
::OpenDelim(token
::Brace
),
6396 &token
::CloseDelim(token
::Brace
),
6397 SeqSep
::trailing_allowed(token
::Comma
), |this
| {
6399 let ident
= if this
.eat_keyword(keywords
::SelfValue
) {
6400 keywords
::SelfValue
.ident()
6404 let rename
= this
.parse_rename()?
;
6405 let node
= ast
::PathListItem_
{
6408 id
: ast
::DUMMY_NODE_ID
6410 Ok(respan(lo
.to(this
.prev_span
), node
))
6415 fn is_import_coupler(&mut self) -> bool
{
6416 self.check(&token
::ModSep
) &&
6417 self.look_ahead(1, |t
| *t
== token
::OpenDelim(token
::Brace
) ||
6418 *t
== token
::BinOp(token
::Star
))
6421 /// Matches ViewPath:
6422 /// MOD_SEP? non_global_path
6423 /// MOD_SEP? non_global_path as IDENT
6424 /// MOD_SEP? non_global_path MOD_SEP STAR
6425 /// MOD_SEP? non_global_path MOD_SEP LBRACE item_seq RBRACE
6426 /// MOD_SEP? LBRACE item_seq RBRACE
6427 fn parse_view_path(&mut self) -> PResult
<'a
, P
<ViewPath
>> {
6429 if self.check(&token
::OpenDelim(token
::Brace
)) || self.check(&token
::BinOp(token
::Star
)) ||
6430 self.is_import_coupler() {
6431 // `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`.
6432 self.eat(&token
::ModSep
);
6433 let prefix
= ast
::Path
{
6434 segments
: vec
![PathSegment
::crate_root(lo
)],
6435 span
: lo
.to(self.span
),
6437 let view_path_kind
= if self.eat(&token
::BinOp(token
::Star
)) {
6438 ViewPathGlob(prefix
)
6440 ViewPathList(prefix
, self.parse_path_list_items()?
)
6442 Ok(P(respan(lo
.to(self.span
), view_path_kind
)))
6444 let prefix
= self.parse_path(PathStyle
::Mod
)?
.default_to_global();
6445 if self.is_import_coupler() {
6446 // `foo::bar::{a, b}` or `foo::bar::*`
6448 if self.check(&token
::BinOp(token
::Star
)) {
6450 Ok(P(respan(lo
.to(self.span
), ViewPathGlob(prefix
))))
6452 let items
= self.parse_path_list_items()?
;
6453 Ok(P(respan(lo
.to(self.span
), ViewPathList(prefix
, items
))))
6456 // `foo::bar` or `foo::bar as baz`
6457 let rename
= self.parse_rename()?
.
6458 unwrap_or(prefix
.segments
.last().unwrap().identifier
);
6459 Ok(P(respan(lo
.to(self.prev_span
), ViewPathSimple(rename
, prefix
))))
6464 fn parse_rename(&mut self) -> PResult
<'a
, Option
<Ident
>> {
6465 if self.eat_keyword(keywords
::As
) {
6466 self.parse_ident().map(Some
)
6472 /// Parses a source module as a crate. This is the main
6473 /// entry point for the parser.
6474 pub fn parse_crate_mod(&mut self) -> PResult
<'a
, Crate
> {
6477 attrs
: self.parse_inner_attributes()?
,
6478 module
: self.parse_mod_items(&token
::Eof
, lo
)?
,
6479 span
: lo
.to(self.span
),
6483 pub fn parse_optional_str(&mut self) -> Option
<(Symbol
, ast
::StrStyle
, Option
<ast
::Name
>)> {
6484 let ret
= match self.token
{
6485 token
::Literal(token
::Str_(s
), suf
) => (s
, ast
::StrStyle
::Cooked
, suf
),
6486 token
::Literal(token
::StrRaw(s
, n
), suf
) => (s
, ast
::StrStyle
::Raw(n
), suf
),
6493 pub fn parse_str(&mut self) -> PResult
<'a
, (Symbol
, StrStyle
)> {
6494 match self.parse_optional_str() {
6495 Some((s
, style
, suf
)) => {
6496 let sp
= self.prev_span
;
6497 self.expect_no_suffix(sp
, "string literal", suf
);
6500 _
=> Err(self.fatal("expected string literal"))