mirror of https://github.com/rust-lang/rust.git
review comment: rework `parse_for_head` to reduce branching
This commit is contained in:
parent
147faa54d5
commit
1575e6e96e
|
@ -2610,28 +2610,42 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_for_head(&mut self) -> PResult<'a, (P<Pat>, P<Expr>)> {
|
fn parse_for_head(&mut self) -> PResult<'a, (P<Pat>, P<Expr>)> {
|
||||||
let pat = if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) {
|
let begin_paren = if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) {
|
||||||
// Record whether we are about to parse `for (`.
|
// Record whether we are about to parse `for (`.
|
||||||
// This is used below for recovery in case of `for ( $stuff ) $block`
|
// This is used below for recovery in case of `for ( $stuff ) $block`
|
||||||
// in which case we will suggest `for $stuff $block`.
|
// in which case we will suggest `for $stuff $block`.
|
||||||
let start_span = self.token.span;
|
let start_span = self.token.span;
|
||||||
let left = self.prev_token.span.between(self.look_ahead(1, |t| t.span));
|
let left = self.prev_token.span.between(self.look_ahead(1, |t| t.span));
|
||||||
match self.parse_pat_allow_top_alt(
|
Some((start_span, left))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
// Try to parse the pattern `for ($PAT) in $EXPR`.
|
||||||
|
let pat = match (
|
||||||
|
self.parse_pat_allow_top_alt(
|
||||||
None,
|
None,
|
||||||
RecoverComma::Yes,
|
RecoverComma::Yes,
|
||||||
RecoverColon::Yes,
|
RecoverColon::Yes,
|
||||||
CommaRecoveryMode::LikelyTuple,
|
CommaRecoveryMode::LikelyTuple,
|
||||||
|
),
|
||||||
|
begin_paren,
|
||||||
) {
|
) {
|
||||||
Ok(pat) => pat,
|
(Ok(pat), _) => pat, // Happy path.
|
||||||
Err(err) if self.eat_keyword(kw::In) => {
|
(Err(err), Some((start_span, left))) if self.eat_keyword(kw::In) => {
|
||||||
|
// We know for sure we have seen `for ($SOMETHING in`. In the happy path this would
|
||||||
|
// happen right before the return of this method.
|
||||||
let expr = match self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None) {
|
let expr = match self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None) {
|
||||||
Ok(expr) => expr,
|
Ok(expr) => expr,
|
||||||
Err(expr_err) => {
|
Err(expr_err) => {
|
||||||
|
// We don't know what followed the `in`, so cancel and bubble up the
|
||||||
|
// original error.
|
||||||
expr_err.cancel();
|
expr_err.cancel();
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return if self.token.kind == token::CloseDelim(Delimiter::Parenthesis) {
|
return if self.token.kind == token::CloseDelim(Delimiter::Parenthesis) {
|
||||||
|
// We know for sure we have seen `for ($SOMETHING in $EXPR)`, so we recover the
|
||||||
|
// parser state and emit a targetted suggestion.
|
||||||
let span = vec![start_span, self.token.span];
|
let span = vec![start_span, self.token.span];
|
||||||
let right = self.prev_token.span.between(self.look_ahead(1, |t| t.span));
|
let right = self.prev_token.span.between(self.look_ahead(1, |t| t.span));
|
||||||
self.bump(); // )
|
self.bump(); // )
|
||||||
|
@ -2645,18 +2659,10 @@ impl<'a> Parser<'a> {
|
||||||
});
|
});
|
||||||
Ok((self.mk_pat(start_span.to(right), ast::PatKind::Wild), expr))
|
Ok((self.mk_pat(start_span.to(right), ast::PatKind::Wild), expr))
|
||||||
} else {
|
} else {
|
||||||
Err(err)
|
Err(err) // Some other error, bubble up.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Err(err) => return Err(err),
|
(Err(err), _) => return Err(err), // Some other error, bubble up.
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.parse_pat_allow_top_alt(
|
|
||||||
None,
|
|
||||||
RecoverComma::Yes,
|
|
||||||
RecoverColon::Yes,
|
|
||||||
CommaRecoveryMode::LikelyTuple,
|
|
||||||
)?
|
|
||||||
};
|
};
|
||||||
if !self.eat_keyword(kw::In) {
|
if !self.eat_keyword(kw::In) {
|
||||||
self.error_missing_in_for_loop();
|
self.error_missing_in_for_loop();
|
||||||
|
|
Loading…
Reference in New Issue