Parser in rustc_parse::parser - Rust (original) (raw)
pub struct Parser<'a> {Show 17 fields
pub psess: &'a ParseSess,
pub token: Token,
token_spacing: Spacing,
pub prev_token: Token,
pub capture_cfg: bool,
restrictions: Restrictions,
expected_token_types: TokenTypeSet,
token_cursor: TokenCursor,
num_bump_calls: u32,
break_last_token: u32,
unmatched_angle_bracket_count: u16,
angle_bracket_nesting: u16,
last_unexpected_token_span: Option<Span>,
subparser_name: Option<&'static str>,
capture_state: CaptureState,
current_closure: Option<ClosureSpans>,
recovery: Recovery,
}
The current token.
The spacing for the current token.
The previous token.
This field is used to keep track of how many left angle brackets we have seen. This is required in order to detect extra leading left angle brackets (<
characters) and error appropriately.
See the comments in the parse_path_segment
function for more details.
If present, this Parser
is not parsing Rust code but rather a macro call.
This allows us to recover when the user forget to add braces around multiple statements in the closure body.
Whether the parser is allowed to do recovery. This is disabled when parsing macro arguments, see #103534
Parses attributes that appear before an item.
Matches attribute = # ! [ meta_item ]
.inner_parse_policy
prescribes how to handle inner attributes.
Parses an inner part of an attribute (the path and following tokens). The tokens must be either a delimited token stream, or empty token stream, or the “legacy” key-value form. PATH (
TOKEN_STREAM )
PATH [
TOKEN_STREAM ]
PATH {
TOKEN_STREAM }
PATH PATH =
UNSUFFIXED_LIT The delimiters or =
are still put into the resulting token stream.
Parses attributes that appear after the opening of an item. These should be preceded by an exclamation mark, but we accept and warn about one terminated by a semicolon.
Matches inner_attrs*
.
Parses cfg_attr(pred, attr_item_list)
where attr_item_list
is comma-delimited.
Matches COMMASEP(meta_item_inner)
.
Parse a meta item per RFC 1559.
MetaItem = SimplePath ( '=' UNSUFFIXED_LIT | '(' MetaSeq? ')' )? ;
MetaSeq = MetaItemInner (',' MetaItemInner)* ','? ;
Parse an inner meta item per RFC 1559.
MetaItemInner = UNSUFFIXED_LIT | MetaItem ;
Parses code with f
. If appropriate, it records the tokens (inLazyAttrTokenStream
form) that were parsed in the result, accessible via the HasTokens
trait. The Trailing
part of the callback’s result indicates if an extra token should be captured, e.g. a comma or semicolon. The UsePreAttrPos
part of the callback’s result indicates if we should use pre_attr_pos
as the collection start position (only required in a few cases).
The attrs
passed in are in AttrWrapper
form, which is opaque. TheAttrVec
within is passed to f
. See the comment on AttrWrapper
for details.
pre_attr_pos
is the position before the outer attributes (or the node itself, if no outer attributes are present). It is only needed if f
can return UsePreAttrPos::Yes
.
Note: If your callback consumes an opening delimiter (including the case where self.token
is an opening delimiter on entry to this function), you must also consume the corresponding closing delimiter. E.g. you can consume something ([{ }])
or ([{}])
, but not ([{}]
. This restriction isn’t a problem in practice, because parsed AST items always have matching delimiters.
The following example code will be used to explain things in comments below. It has an outer attribute and an inner attribute. Parsing it involves two calls to this method, one of which is indirectly recursive.
#[cfg_eval] // token pos
mod m { // 0.. 3
#[cfg_attr(cond1, attr1)] // 3..12
fn g() { // 12..17
#![cfg_attr(cond2, attr2)] // 17..27
let _x = 3; // 27..32
} // 32..33
} // 33..34
Replace self
with snapshot.parser
.
Create a snapshot of the Parser
.
Emits an error with suggestions if an identifier was expected but not found.
Returns a possibly recovered identifier.
Checks if the current token is a integer or float literal and looks like it could be a invalid identifier with digits at the start.
Returns the number of characters (bytes) composing the invalid portion of the identifier and the valid portion of the identifier.
Adds a label when &raw EXPR
was written instead of &raw const EXPR
/&raw mut EXPR
.
Given that not all parser diagnostics flow through expected_one_of_not_found
, this label may need added to other diagnostics emission paths as needed.
Checks if the current token or the previous token are misspelled keywords and adds a helpful suggestion.
The user has written #[attr] expr
which is unsupported. (#106020)
Eats and discards tokens until one of closes
is encountered. Respects token trees, passes through any errors encountered. Used for error recovery.
This function checks if there are trailing angle brackets and produces a diagnostic to suggest removing them.
let _ = [1, 2, 3].into_iter().collect::<Vec<usize>>>>();
^^ help: remove extra angle brackets
If true
is returned, then trailing brackets were recovered, tokens were consumed up until one of the tokens in ‘end’ was encountered, and an error was emitted.
Check if a method call with an intended turbofish has been written without surrounding angle brackets.
When writing a turbofish with multiple type parameters missing the leading ::
, we will encounter a parse error when encountering the first ,
.
Suggest add the missing let
before the identifier in stmta: Ty = 1
-> let a: Ty = 1
Check to see if a pair of chained operators looks like an attempt at chained comparison, e.g. 1 < x <= 3
. If so, suggest either splitting the comparison into two, or parenthesising the leftmost comparison. The return value indicates if recovery happened.
Produces an error if comparison operators are chained (RFC #558). We only need to check the LHS, not the RHS, because all comparison ops have same precedence (see fn precedence
) and are left-associative (see fn fixity
).
This can also be hit if someone incorrectly writes foo<bar>()
when they should have used the turbofish (foo::<bar>()
) syntax. We attempt some heuristic recovery if that is the case.
Keep in mind that given that outer_op.is_comparison()
holds and comparison ops are left associative we can infer that we have:
outer_op
/ \
inner_op r2
/ \
l1 r1
Swift lets users write Ty?
to mean Option<Ty>
. Parse the construct and recover from it.
Rust has no ternary operator (cond ? then : else
). Parse it and try to recover from it if then
and else
are valid expressions. Returns an err if this appears to be a ternary expression.
Tries to recover from associated item paths like [T]::AssocItem
/ (T, U)::AssocItem
. Attempts to convert the base expression/pattern/type into a type, parses the ::AssocItem
tail, and combines them into a <Ty>::AssocItem
expression/pattern/type.
Given an already parsed Ty
, parses the ::AssocItem
tail and combines them into a <Ty>::AssocItem
expression/pattern/type.
This function gets called in places where a semicolon is NOT expected and if there’s a semicolon it emits the appropriate error and returns true.
Creates a Diag
for an unexpected token t
and tries to recover if it is a closing delimiter.
Consumes alternative await syntaxes like await!(<expr>)
, await <expr>
,await? <expr>
, await(<expr>)
, and await { <expr> }
.
If encountering future.await()
, consumes and emits an error.
If encountering x.use()
, consumes and emits an error.
When trying to close a generics list and encountering code like
impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {}
// ^ missing > here
we provide a structured suggestion on the error from expect_gt
.
Eats tokens until we can be relatively sure we reached the end of the statement. This is something of a best-effort heuristic.
We terminate when we find an unmatched }
(without consuming it).
If break_on_semi
is Break
, then we will stop consuming tokens after finding (and consuming) a ;
outside of {}
or []
(note that this is approximate – it can mean we break too early due to macros, but that should only lead to sub-optimal recovery, not inaccurate parsing).
If break_on_block
is Break
, then we will stop consuming tokens after finding (and consuming) a brace-delimited block.
Replace duplicated recovered parameters with _
pattern to avoid unnecessary errors.
This is necessary because at this point we don’t know whether we parsed a function with anonymous parameters or a function with names but no types. In order to minimize unnecessary errors, we assume the parameters are in the shape of fn foo(a, b, c)
where the parameters are names (so we don’t emit errors about not being able to find b
in the local scope), but if we find the same name multiple times, like in fn foo(i8, i8)
, we deduplicate them to not complain about duplicated parameter names.
Handle encountering a symbol in a generic argument list that is not a ,
or >
. In this case, we emit an error and try to suggest enclosing a const argument in braces if it looks like the user has forgotten them.
Attempt to parse a generic const argument that has not been enclosed in braces. There are a limited number of expressions that are permitted without being encoded in braces:
- Literals.
- Single-segment paths (i.e. standalone generic const parameters). All other expressions that can be parsed will emit an error suggesting the expression be wrapped in braces.
Try to recover from possible generic const argument without {
and }
.
When encountering code like foo::< bar + 3 >
or foo::< bar - baz >
we suggestfoo::<{ bar + 3 }>
and foo::<{ bar - baz }>
, respectively. We only provide a suggestion if we think that the resulting expression would be well formed.
Try to recover from an unbraced const argument whose first token could begin a type.
Creates a dummy const argument, and reports that the expression must be enclosed in braces
Some special error handling for the “top-level” patterns in a match arm,for
loop, let
, &c. (in contrast to subpatterns within such).
If loop_header
is Some
and an unexpected block label is encountered, it is suggested to be moved just before loop_header
, else it is suggested to be removed.
Some special error handling for the “top-level” patterns in a match arm,for
loop, let
, &c. (in contrast to subpatterns within such).
Check for exclusive ranges written as ..<
This checks if this is a conflict marker, depending of the parameter passed.
<<<<<<<
|||||||
=======
>>>>>>>
Parse and throw away a parenthesized comma separated sequence of patterns until )
is reached.
Parses an expression.
Parses an expression, forcing tokens to be collected.
Parses a sequence of expressions delimited by parentheses.
Parses an expression, subject to the given restrictions.
Parses an associative expression with operators of at least min_prec
precedence. The bool
in the return value indicates if it was an assoc expr, i.e. with an operator followed by a subexpression (e.g. 1 + 2
).
Parses the rest of an associative expression (i.e. the part after the lhs) with operators of at least min_prec
precedence. The bool
in the return value indicates if something was actually parsed.
We’ve found an expression that would be parsed as a statement, but the next token implies this should be parsed as an expression. For example: if let Some(x) = x { x } else { 0 } / 2
.
Possibly translate the current token to an associative operator. The method does not advance the current token.
Also performs recovery for and
/ or
which are mistaken for &&
and ||
respectively.
Checks if this expression is a successfully parsed statement.
Parses x..y
, x..=y
, and x..
/x..=
. The other two variants are handled in parse_prefix_range_expr
below.
Parses prefix-forms of range notation: ..expr
, ..
, ..=expr
.
Parses a prefix-unary-operator expr.
Recover on ~expr
in favor of !expr
.
Parse box expr
- this syntax has been removed, but we still parse this for now to provide a more useful error
Recover on not expr
in favor of !expr
.
Returns the span of expr if it was not interpolated, or the span of the interpolated token.
Parse & mut? <expr>
or & raw [ const | mut ] <expr>
.
Parse mut?
or raw [ const | mut ]
.
Parses a.b
or a(13)
or a[4]
or just a
.
We need an identifier or integer, but the next token is a float. Break the float into components to extract the identifier or integer.
See also TokenKind::break_two_token_op which does similar splitting of >>
into >
.
Parse the field access used in offset_of, matched by $(e:expr)+
. Currently returns a list of idents. However, it should be possible in future to also do array indices, which might be arbitrary expressions.
Parse a function call expression, expr(...)
.
If we encounter a parser state that looks like the user has written a struct
literal with parentheses instead of braces, recover the parser state and provide suggestions.
Parse an indexing expression expr[...]
.
Assuming we have just parsed .
, continue parsing into an expression.
At the bottom (top?) of the precedence hierarchy, Parses things like parenthesized exprs, macros, return
, etc.
N.B., this does not parse outer attributes, and is private because it only works correctly if called from parse_expr_dot_or_call
.
Parse 'label: $expr
. The label is already parsed.
Emit an error when a char is parsed as a lifetime or label because of a missing quote.
Recover on the syntax do catch { ... }
suggesting try { ... }
instead.
Parse an expression if the token can begin one.
Parse "return" expr?
.
Parse "do" "yeet" expr?
.
Parse "become" expr
, with "become"
token already eaten.
Parse "break" (('label (:? expr)?) | expr?)
with "break"
token already eaten. If the label is followed immediately by a :
token, the label and :
are parsed as part of the expression (i.e. a labeled loop). The language team has decided in #87026 to require parentheses as a visual aid to avoid confusion if the break expression of an unlabeled break is a labeled loop (as inbreak 'lbl: loop {}
); a labeled break with an unlabeled loop as its value expression only gets a warning for compatibility reasons; and a labeled break with a labeled loop does not even get a warning because there is no ambiguity.
Parse "continue" label?
.
Parse "yield" expr?
.
Parse builtin # ident(args,*)
.
Built-in macro for offset_of!
expressions.
Built-in macro for type ascription expressions.
Returns a string literal if the next token is a string literal. In case of error returns Some(lit)
if the next token is a literal with a wrong kind, and returns None
if the next token is not literal at all.
Keep this in sync with Token::can_begin_literal_maybe_minus
andLit::from_token
(excluding unary negation).
Matches lit = true | false | token_lit
. Returns None
if the next token is not a literal.
Matches lit = true | false | token_lit
. Returns None
if the next token is not a literal.
Matches '-' lit | lit
(cf. ast_validation::AstValidator::check_expr_within_pat
). Keep this in sync with Token::can_begin_literal_maybe_minus
.
Emits a suggestion if it looks like the user meant an array but accidentally used braces, causing the code to be interpreted as a block expression.
Parses a block or unsafe block.
Parse a block which takes no attributes and has no label
Parses a closure expression (e.g., move |args| expr
).
If an explicit return type is given, require a block to appear (RFC 968).
Parses an optional move
or use
prefix to a closure-like construct.
Parses the |arg, arg|
header of a closure.
Parses a parameter in a closure header (e.g., |arg, arg|
).
Parses an if
expression (if
token already eaten).
Parses the condition of a if
or while
expression.
The specified edition
in let_chains_policy
should be that of the whole if
construct, i.e. the same span we use to later decide whether the drop behaviour should be that of edition ..=2021
or that of 2024..
.
Parses a let <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>a</mi><mi>t</mi><mo>=</mo></mrow><annotation encoding="application/x-tex">pat = </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8095em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>expr
pseudo-expression.
Parses an else { ... }
expression (else
token already eaten).
Parses for await? <src_pat> in <src_expr> <src_loop_block>
(for
token already eaten).
Recovers from an else
clause after a loop (for...else
, while...else
)
Parses a while
or while let
expression (while
token already eaten).
Parses loop { ... }
(loop
token already eaten).
Parses a match ... { ... }
expression (match
token already eaten).
Parses the block of a match expr { ... }
or a expr.match { ... }
expression. This is after the match token and scrutinee are eaten
Attempt to recover from match arm body with statements and no surrounding braces.
Parses a try {...}
expression (try
token already eaten).
Parses an async move? {...}
or gen move? {...}
expression.
Precondition: already parsed the ‘{’.
Converts an ident into ’label and emits an “expected a label, found an identifier” error.
Parses ident (COLON expr)?
.
Check for =
. This means the source incorrectly attempts to initialize a field with an eq rather than a colon.
Create expression span ensuring the span of the parent node is larger than the span of lhs and rhs, including the attributes.
Parses bounds of a lifetime parameter BOUND + BOUND + BOUND
, possibly with trailing +
.
BOUND = LT_BOUND (e.g., `'a`)
Matches typaram = IDENT (
? unbound)? optbounds ( EQ ty )?
.
Parses a (possibly empty) list of lifetime and type parameters, possibly including a trailing comma and erroneous trailing attributes.
Parses a set of optional generic type parameter declarations. Where clauses are not parsed here, and must be added later viaparse_where_clause()
.
matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > ) | ( < lifetimes , typaramseq ( , )? > ) where typaramseq = ( typaram ) | ( typaram , typaramseq )
Parses an experimental fn contract (contract_requires(WWW) contract_ensures(ZZZ)
)
Parses an optional where-clause.
where T : Trait<U, V> + 'b, 'a : 'b
Parses a source module as a crate. This is the main entry point for the parser.
Parses a mod <foo> { ... }
or mod <foo>;
item.
Parses the contents of a module (inner attributes followed by module items). We exit once we hit term
which can be either
- EOF (for files)
}
for mod items
Error in-case default
was parsed in an in-appropriate context.
Parses one of the items allowed by the flags.
When parsing a statement, would the start of a path be an item?
Are we sure this could not possibly be a macro invocation?
Recover on encountering a struct, enum, or method definition where the user forgot to add the struct
, enum
, or fn
keyword
Parses an item macro, e.g., item!();
.
Recover if we parsed attributes and expected an item but there was none.
Parses an implementation item.
impl<'a, T> TYPE { /* impl items */ }
impl<'a, T> TRAIT for TYPE { /* impl items */ }
impl<'a, T> !TRAIT for TYPE { /* impl items */ }
impl<'a, T> const TRAIT for TYPE { /* impl items */ }
We actually parse slightly more relaxed grammar for better error reporting and recovery.
"impl" GENERICS "const"? "!"? TYPE "for"? (TYPE | "..") ("where" PREDICATES)? "{" BODY "}"
"impl" GENERICS "const"? "!"? TYPE ("where" PREDICATES)? "{" BODY "}"
Recover on a doc comment before }
.
Parses defaultness (i.e., default
or nothing).
Is this an (unsafe auto? | auto) trait
item?
Parses unsafe? auto? trait Foo { ... }
or trait Foo = Bar;
.
Parses associated items.
Parses a type
alias with the following grammar:
TypeAlias = "type" Ident Generics (":" GenericBounds)? WhereClause ("=" Ty)? WhereClause ";" ;
The "type"
has already been eaten.
Parses a UseTree
.
USE_TREE = [`::`] `*` |
[`::`] `{` USE_TREE_LIST `}` |
PATH `::` `*` |
PATH `::` `{` USE_TREE_LIST `}` |
PATH [`as` IDENT]
Parses *
or {...}
.
Parses a UseTreeKind::Nested(list)
.
USE_TREE_LIST = ∅ | (USE_TREE `,`)* USE_TREE [`,`]
Parses extern crate
links.
§Examples
extern crate foo;
extern crate bar as foo;
Parses extern
for foreign ABIs modules.
extern
is expected to have been consumed before calling this method.
§Examples
Parses a foreign item (one in an extern { ... }
block).
Recover on const mut
with const
already eaten.
Recover on const impl
with const
already eaten.
Parse a static item with the prefix "static" "mut"?
already parsed and stored inmutability
.
Static = "static" "mut"? <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mi>d</mi><mi>e</mi><mi>n</mi><mi>t</mi><mi mathvariant="normal">"</mi><mo>:</mo><mi mathvariant="normal">"</mi></mrow><annotation encoding="application/x-tex">ident ":" </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord">"</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord">"</span></span></span></span>ty (= $expr)? ";" ;
Parse a constant item with the prefix "const"
already parsed.
Const = "const" ($ident | "_") Generics ":" <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mi>y</mi><mo stretchy="false">(</mo><mo>=</mo></mrow><annotation encoding="application/x-tex">ty (= </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mopen">(</span><span class="mrel">=</span></span></span></span>expr)? WhereClause ";" ;
We were supposed to parse ":" $ty
but the :
or the type was missing. This means that the type is missing.
Parses an enum declaration.
Parses struct Foo { ... }
.
Parses union Foo { ... }
.
This function parses the fields of record structs:
struct S { ... }
enum E { Variant { ... } }
Parses an element of a struct declaration.
Parses a structure field declaration.
Parses a structure field.
Parses a field identifier. Specialized version of parse_ident_common
for better diagnostics and suggestions.
Parses a declarative macro 2.0 definition. The macro
keyword has already been parsed.
MacBody = "{" TOKEN_STREAM "}" ;
MacParams = "(" TOKEN_STREAM ")" ;
DeclMac = "macro" Ident MacParams? MacBody ;
Is this a possibly malformed start of a macro_rules! foo
item definition?
Parses a macro_rules! foo { ... }
declarative macro.
Item macro invocations or macro_rules!
definitions need inherited visibility. If that’s not the case, emit an error.
Checks if current token is one of tokens which cannot be nested like kw::Enum
. In case it is, we try to parse the item and report error about nested types.
Parsing of functions and methods.
Parse a function starting from the front matter (const ...
) to the body { ... }
or ;
.
Provide diagnostics when function body is not found
Parse the “body” of a function. This can either be ;
when there’s no body, or e.g. a block when the function is a provided one.
Is the current token the start of an FnHeader
/ not a valid parse?
check_pub
adds additional pub
to the checks in case users place it wrongly, can be used to ensure pub
never comes after default
.
Parses all the “front matter” (or “qualifiers”) for a fn
declaration, up to and including the fn
keyword. The formal grammar is:
Extern = "extern" StringLit? ;
FnQual = "const"? "async"? "unsafe"? Extern? ;
FnFrontMatter = FnQual "fn" ;
vis
represents the visibility that was already parsed, if any. UseVisibility::Inherited
when no visibility is known.
Parses the parameter list and result type of a function declaration.
Parses the parameter list of a function, including the (
and )
delimiters.
Parses a single function parameter.
self
is syntactically allowed whenfirst_param
holds.recover_arg_parse
is used to recover from a failed argument parse.
Returns the parsed optional self parameter and whether a self shortcut was used.
Checks whether a non-terminal may begin with a particular token.
Returning false
is a stability guarantee that such a matcher will never begin with that token. Be conservative (return true) if not sure. Inlined because it has a single call site.
Parse a non-terminal (e.g. MBE :pat
or :ident
). Inlined because there is only one call site.
Parses a pattern.
Corresponds to Pattern
in RFC 3637 and admits guard patterns at the top level. Used when parsing patterns in all cases where neither PatternNoTopGuard
norPatternNoTopAlt
(see below) are used.
Parses a pattern.
Corresponds to PatternNoTopAlt
in RFC 3637 and does not admit or-patterns or guard patterns at the top level. Used when parsing the parameters of lambda expressions, functions, function pointers, and pat_param
macro fragments.
Parses a pattern.
Corresponds to PatternNoTopGuard
in RFC 3637 and allows or-patterns, but not guard patterns, at the top level. Used for parsing patterns in pat
fragments (until the next edition) and let
, if let
, and while let
expressions.
Note that after the FCP in https://github.com/rust-lang/rust/issues/81415, a leading vert is allowed in nested or-patterns, too. This allows us to simplify the grammar somewhat.
Returns the pattern and a bool indicating whether we recovered from a trailing vert (true = recovered).
Parse a pattern and (maybe) a Colon
in positions where a pattern may be followed by a type annotation (e.g. for let
bindings or fn
params).
Generally, this corresponds to pat_no_top_alt
followed by an optional Colon
. It will eat the Colon
token if one is present.
The return value represents the parsed pattern and true
if a Colon
was parsed (false
otherwise).
Parse the pattern for a function or function pointer parameter, followed by a colon.
The return value represents the parsed pattern and true
if a Colon
was parsed (false
otherwise).
Eat the or-pattern |
separator. If instead a ||
token is encountered, recover and pretend we parsed |
.
Recover if |
or ||
is the current token and we have one of the tokens =>
, if
, =
, :
, ;
, ,
, ]
, )
, or }
ahead of us.
These tokens all indicate that we reached the end of the or-pattern list and can now reliably say that the |
was an illegal trailing vert. Note that there are more tokens such as @
for which we know that the |
is an illegal parse. However, the user’s intent is less clear in that case.
Ensures that the last parsed pattern (or pattern range bound) is not followed by an expression.
is_end_bound
indicates whether the last parsed thing was the end bound of a range pattern (see parse_pat_range_end) in order to say “expected a pattern range bound” instead of “expected a pattern”;
Only the end bound is spanned in this case, and this function has no idea if there was a ..=
before pat_span
, hence the parameter.
This function returns Some
if a trailing expression was recovered, and said expression’s span.
Parses a pattern, with a setting whether modern range patterns (e.g., a..=b
, a..b
are allowed).
Recover from a typoed ...
pattern that was encountered Ref: Issue #70388
Try to recover the more general form intersect ::= <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>a</mi><msub><mi>t</mi><mi>l</mi></msub><mi>h</mi><mi>s</mi><mi mathvariant="normal">@</mi></mrow><annotation encoding="application/x-tex">pat_lhs @ </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord"><span class="mord mathnormal">t</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal">h</span><span class="mord mathnormal">s</span><span class="mord">@</span></span></span></span>pat_rhs
.
Allowed binding patterns generated by binding ::= ref? mut? <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mi>d</mi><mi>e</mi><mi>n</mi><mi>t</mi><mi mathvariant="normal">@</mi></mrow><annotation encoding="application/x-tex">ident @ </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord">@</span></span></span></span>pat_rhs
should already have been parsed by now at this point, if the next token is @
then we can try to parse the more general form.
Consult parse_pat_ident
for the binding
grammar.
The notion of intersection patterns are found in e.g. F# where they are called AND-patterns.
Ban a range pattern if it has an ambiguous interpretation.
Parse &pat
/ &mut pat
.
Parse a tuple or parenthesis pattern.
Parse a mutable binding with the mut
token already eaten.
Turn all by-value immutable bindings in a pattern into mutable bindings. Returns true
if any change was made.
Error on mut <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>a</mi><mi>t</mi><mi mathvariant="normal">‘</mi><mi>w</mi><mi>h</mi><mi>e</mi><mi>r</mi><mi>e</mi><mi mathvariant="normal">‘</mi></mrow><annotation encoding="application/x-tex">pat
where </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord">‘</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal">ere</span><span class="mord">‘</span></span></span></span>pat
is not an ident.
Eat any extraneous mut
s and error + recover if we ate any.
Parse macro invocation
Parses the range pattern end form ".." | "..." | "..=" ;
.
Parse a range pattern $begin <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mi>o</mi><mi>r</mi><mi>m</mi></mrow><annotation encoding="application/x-tex">form </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.02778em;">or</span><span class="mord mathnormal">m</span></span></span></span>end?
where $form = ".." | "..." | "..=" ;
.$begin $form
has already been parsed.
Parse a range-to pattern, ..X
or ..=X
where X
remains to be parsed.
The form ...X
is prohibited to reduce confusion with the potential expression syntax ...expr
for splatting in expressions.
Is the token dist
away from the current suitable as the start of a range patterns end?
Parse a range pattern end bound
Is this the start of a pattern beginning with a path?
Would parse_pat_ident
be appropriate here?
Parses ident
or ident @ pat
. Used by the copy foo and ref foo patterns to give a good error message when parsing mistakes like ref foo(a, b)
.
Parse a struct (“record”) pattern (e.g. Foo { ... }
or Foo::Bar { ... }
).
Parse tuple struct or tuple variant pattern (e.g. Foo(...)
or Foo::Bar(...)
).
Are we sure this could not possibly be the start of a pattern?
Currently, this only accounts for tokens that can follow identifiers in patterns, but this can be extended as necessary.
Parses box pat
Parses the fields of a struct-like pattern.
If the user writes S { ref field: name }
instead of S { field: ref name }
, we suggest the correct code.
Recover on ...
or _
as if it were ..
to avoid further errors. See issue #46718.
Parses a qualified path. Assumes that the leading <
has been parsed already.
qualified_path = <type [as trait_ref]>::path
§Examples
<T>::default
<T as U>::a
<T as U>::F::a<S>
(without disambiguator)<T as U>::F::a::<S>
(with disambiguator)
Recover from an invalid single colon, when the user likely meant a qualified path. We avoid emitting this if not followed by an identifier, as our assumption that the user intended this to be a qualified path may not be correct.
<Bar as Baz<T>>:Qux
^ help: use double colon
Parses simple paths.
path = [::] segment+
segment = ident | ident[::]<args> | ident[::](args) [-> type]
§Examples
a::b::C<D>
(without disambiguator)a::b::C::<D>
(with disambiguator)Fn(Args)
(without disambiguator)Fn::(Args)
(with disambiguator)
Eat ::
or, potentially, :::
.
Recover $path::(...)
as $path(...)
.
foo::(420, "bar")
^^ remove extra separator to make the function call
// or
match x {
Foo::(420, "bar") => { ... },
^^ remove extra separator to turn this into tuple struct pattern
_ => { ... },
}
Parses generic args (within a path segment) with recovery for extra leading angle brackets. For the purposes of understanding the parsing logic of generic arguments, this function can be thought of being the same as just calling self.parse_angle_args()
if the source had the correct amount of leading angle brackets.
bar::<<<<T as Foo>::Output>();
^^ help: remove extra angle brackets
Parses (possibly empty) list of generic arguments / associated item constraints, possibly including trailing comma.
Parses a single argument in the angle arguments <...>
of a path segment.
Parse the term to the right of an associated item equality constraint.
That is, parse $term
in Item = <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mi>e</mi><mi>r</mi><mi>m</mi><mi mathvariant="normal">‘</mi><mi>w</mi><mi>h</mi><mi>e</mi><mi>r</mi><mi>e</mi><mi mathvariant="normal">‘</mi></mrow><annotation encoding="application/x-tex">term
where </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mord mathnormal">m</span><span class="mord">‘</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal">ere</span><span class="mord">‘</span></span></span></span>term
is a type or a const expression (wrapped in curly braces if complex).
We do not permit arbitrary expressions as const arguments. They must be one of:
- An expression surrounded in
{}
. - A literal.
- A numeric literal prefixed by
-
. - A single-segment path.
Parse a const argument, e.g. <3>
. It is assumed the angle brackets will be parsed by the caller.
Parse a generic argument in a path segment. This does not include constraints, e.g., Item = u8
, which is handled in parse_angle_arg
.
Given a arg inside of generics, we try to destructure it as if it were the LHS inLHS = ...
, i.e. an associated item binding. This returns a bool indicating if there are any for<'a, 'b>
binder args, the identifier, and any GAT arguments.
Parses a statement. This stops just before trailing semicolons on everything but items. e.g., a StmtKind::Semi
parses to a StmtKind::Expr
, leaving the trailing ;
unconsumed.
If force_collect
is ForceCollect::Yes, forces collection of tokens regardless of whether or not we have attributes.
If force_collect
is ForceCollect::Yes, forces collection of tokens regardless of whether or not we have attributes. If force_full_expr
is true, parses the stmt without using Restriction::STMT_EXPR
. Public for cfg_eval
macro expansion.
Parses a statement macro mac!(args)
provided a path
representing mac
. At this point, the !
token after the path has already been eaten.
Error on outer attributes in this context. Also error if the previous token was a doc comment.
Parses a local variable declaration.
Parses the RHS of a local variable declaration (e.g., = 14;
).
Parses a block. No inner attributes are allowed.
Parses a block. Inner attributes are allowed, block labels are not.
If loop_header
is Some
and an unexpected block label is encountered, it is suggested to be moved just before loop_header
, else it is suggested to be removed.
Parses a block. Inner attributes are allowed, block labels are not.
If loop_header
is Some
and an unexpected block label is encountered, it is suggested to be moved just before loop_header
, else it is suggested to be removed.
Parses the rest of a block expression or function body. Precondition: already parsed the ‘{’.
Parses a statement, including the trailing semicolon.
Parses a type.
Parse a type suitable for a function or function pointer parameter. The difference from parse_ty
is that this version allows ...
(CVarArgs
) at the top level of the type.
Parses a type in restricted contexts where +
is not permitted.
Example 1: &'a TYPE
+
is prohibited to maintain operator priority (P(+) < P(&)). Example 2: value1 as TYPE + value2
+
is prohibited to avoid interactions with expression grammar.
Parses a type following an as
cast. Similar to parse_ty_no_plus
, but signaling origin for better diagnostics involving ?
.
Parse a type without recovering :
as ->
to avoid breaking code such as where fn() : for<'a>
.
Parses an optional return type [ -> TY ]
in a function declaration.
Parses either:
(TYPE)
, a parenthesized type.(TYPE,)
, a tuple with a single field of type TYPE.
Parse the remainder of a bare trait object type given an already parsed list.
Parses a raw pointer type: *[const | mut] $type
.
Parses an array ([TYPE; EXPR]
) or slice ([TYPE]
) type. The opening [
bracket is already eaten.
Parses pin
and mut
annotations on references.
It must be either pin const
or pin mut
.
Parses a function pointer type (TyKind::BareFn
).
[unsafe] [extern "ABI"] fn (S) -> T
// ^~~~~^ ^~~~^ ^~^ ^
// | | | |
// | | | Return type
// Function Style ABI Parameter types
We actually parse FnHeader FnDecl
, but we error on const
and async
qualifiers.
Recover from function pointer types with a generic parameter list (e.g. fn<'a>(&'a str)
).
Parses an impl B0 + ... + Bn
type.
Is a dyn B0 + ... + Bn
type allowed here?
Parses a dyn B0 + ... + Bn
type.
Note that this does not parse bare trait objects.
Parses a type starting with a path.
This can be:
- a type macro,
mac!(...)
, - a bare trait object,
B0 + ... + Bn
, - or a path,
path::to::MyType
.
Parses bounds of a type parameter BOUND + BOUND + ...
, possibly with trailing +
.
See parse_generic_bound
for the BOUND
grammar.
Can the current token begin a bound?
Parses a bound according to the grammar:
BOUND = TY_BOUND | LT_BOUND
Parses a lifetime (“outlives”) bound, e.g. 'a
, according to:
Emits an error if any trait bound modifiers were present.
Recover on ('lifetime)
with (
already eaten.
Parses the modifiers that may precede a trait in a bound, e.g. ?Trait
or ~const Trait
.
If no modifiers are present, this does not consume any tokens.
CONSTNESS = [["~"] "const"]
ASYNCNESS = ["async"]
POLARITY = ["?" | "!"]
See parse_generic_ty_bound
for the complete grammar of trait bound modifiers.
Parses a type bound according to:
TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
TY_BOUND_NOPAREN = [for<GENERIC_PARAMS> CONSTNESS ASYNCNESS | POLARITY] SIMPLE_PATH
For example, this grammar accepts for<'a: 'b> ~const ?m::Trait<'a>
.
Optionally parses for<$generic_params>
.
Recover from Fn
-family traits (Fn, FnMut, FnOnce) with lifetime arguments (e.g. FnOnce<'a>(&'a str) -> bool
). Up to generic arguments have already been eaten.
Parses a single lifetime 'a
or panics.
Whether the parser is allowed to recover from broken code.
If this returns false, recovering broken code into valid code (especially if this recovery does lookahead) is not allowed. All recovery done by the parser must be gated behind this check.
Technically, this only needs to restrict eager recovery by doing lookahead at more tokens. But making the distinction is very subtle, and simply forbidding all recovery is a lot simpler to uphold.
Version of unexpected that “returns” any type in the Ok
(both those functions never return “Ok”, and so can lie like that in the type).
Expects and consumes the token t
. Signals an error if the next token is not t
.
Expect next token to be edible or inedible token. If edible, then consume it; if inedible, then return without consuming anything. Signal a fatal error if next token is unexpected.
Checks if the next token is tok
, and returns true
if so.
This method will automatically add tok
to expected_token_types
if tok
is not encountered.
Consumes a token ‘tok’ if it exists. Returns whether the given token was present.
the main purpose of this function is to reduce the cluttering of the suggestions list which using the normal eat method could introduce in some cases.
Consumes a token ‘tok’ if it exists. Returns whether the given token was present.
If the next token is the given keyword, returns true
without eating it. An expectation is also added for diagnostics purposes.
If the next token is the given keyword, eats it and returns true
. Otherwise, returns false
. An expectation is also added for diagnostics purposes.
Eats a keyword, optionally ignoring the case. If the case differs (and is ignored) an error is issued. This is useful for recovery.
If the next token is the given keyword, eats it and returns true
. Otherwise, returns false
. No expectation is added.
If the given word is not a keyword, signals an error. If the next token is not the given word, signals an error. Otherwise, eats it.
Consume a sequence produced by a metavar expansion, if present.
A slightly more general form of eat_metavar_seq
, for use with theMetaVarKind
variants that have parameters, where an exact match isn’t desired.
Is the given keyword kw
followed by a non-reserved identifier?
Checks to see if the next token is either +
or +=
. Otherwise returns false
.
Eats the expected token if it’s present possibly breaking compound tokens like multi-character operators in process. Returns true
if the token was eaten.
Eats +
possibly breaking tokens like +=
in process.
Eats &
possibly breaking tokens like &&
in process. Signals an error if &
is not eaten.
Eats |
possibly breaking tokens like ||
in process. Signals an error if |
was not eaten.
Eats <
possibly breaking tokens like <<
in process.
Eats <
possibly breaking tokens like <<
in process. Signals an error if <
was not eaten.
Eats >
possibly breaking tokens like >>
in process. Signals an error if >
was not eaten.
Checks if the next token is contained within closes
, and returns true
if so.
Parses a sequence until the specified delimiters. The functionf
must consume tokens until reaching the next separator or closing bracket.
Parses a sequence, not including the delimiters. The functionf
must consume tokens until reaching the next separator or closing bracket.
Parses a sequence, including only the closing delimiter. The functionf
must consume tokens until reaching the next separator or closing bracket.
Parses a sequence, including both delimiters. The functionf
must consume tokens until reaching the next separator or closing bracket.
Parses a comma-separated sequence, including both delimiters. The function f
must consume tokens until reaching the next separator or closing bracket.
Parses a comma-separated sequence delimited by parentheses (e.g. (x, y)
). The function f
must consume tokens until reaching the next separator or closing bracket.
Advance the parser by one token using provided token as the next one.
This always-inlined version should only be used on hot code paths.
Advance the parser by one token.
Look-ahead dist
tokens of self.token
and get access to that token there. When dist == 0
then the current token is looked at. Eof
will be returned if the look-ahead is any distance past the end of the tokens.
Like lookahead
, but skips over token trees rather than tokens. Useful when looking past possible metavariable pasting sites.
Returns whether any of the given keywords are dist
tokens ahead of the current one.
Parses asyncness: async
or nothing.
Parses fn unsafety: unsafe
, safe
or nothing.
Parses constness: const
or nothing.
Parses constness for closures (case sensitive, feature-gated)
Parses inline const expressions.
Parses mutability (mut
or nothing).
Parses reference binding mode (ref
, ref mut
, or nothing).
Possibly parses mutability (const
or mut
).
Parses a single token tree from the input.
Evaluates the closure with restrictions in place.
Afters the closure is evaluated, restrictions are reset.
Parses pub
and pub(in path)
plus shortcuts pub(crate)
for pub(in crate)
, pub(self)
for pub(in self)
and pub(super)
for pub(in super)
. If the following element can’t be a tuple (i.e., it’s a function definition), then it’s not a tuple struct field), and the contents within the parentheses aren’t valid, so emit a proper diagnostic.
Recovery for e.g. pub(something) fn ...
or struct X { pub(something) y: Z }
Parses extern string_literal?
.
Parses a string literal as an ABI spec.
Checks for ::
or, potentially, :::
and then look ahead after it.
::{
or ::*
For interpolated self.token
, returns a span of the fragment to which the interpolated token refers. For all other tokens this is just a regular span. It is particularly important to use this for identifiers and lifetimes for which spans affect name resolution and edition checks. Note that keywords are also identifiers, so they should use this if they keep spans or perform edition checks.
Like token_uninterpolated_span
, but works on self.prev_token
.
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 288 bytes