Skip to content

Commit bb48c16

Browse files
committed
Simplify logic slightly
1 parent 4305769 commit bb48c16

File tree

1 file changed

+22
-15
lines changed
  • compiler/rustc_parse/src/parser

1 file changed

+22
-15
lines changed

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3612,20 +3612,36 @@ impl<'a> Parser<'a> {
36123612
self.token.is_keyword(kw::Async) && self.is_gen_block(kw::Gen, 1)
36133613
}
36143614

3615+
fn is_likely_struct_lit(&self) -> bool {
3616+
// `{ ident, ` and `{ ident: ` cannot start a block.
3617+
self.look_ahead(1, |t| t.is_ident())
3618+
&& self.look_ahead(2, |t| t == &token::Comma || t == &token::Colon)
3619+
}
3620+
36153621
fn maybe_parse_struct_expr(
36163622
&mut self,
36173623
qself: &Option<Box<ast::QSelf>>,
36183624
path: &ast::Path,
36193625
) -> Option<PResult<'a, Box<Expr>>> {
36203626
let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
3621-
let is_ident = self.look_ahead(1, |t| t.is_ident());
3622-
let is_comma = self.look_ahead(2, |t| t == &token::Comma);
3623-
let is_colon = self.look_ahead(2, |t| t == &token::Colon);
3624-
match (struct_allowed, is_ident, is_comma, is_colon) {
3625-
(false, true, true, _) | (false, true, _, true) => {
3627+
match (struct_allowed, self.is_likely_struct_lit()) {
3628+
// A struct literal isn't expected and one is pretty much assured not to be present. The
3629+
// only situation that isn't detected is when a struct with a single field was attempted
3630+
// in a place where a struct literal wasn't expected, but regular parser errors apply.
3631+
// Happy path.
3632+
(false, false) => None,
3633+
(true, _) => {
3634+
// A struct is accepted here, try to parse it and rely on `parse_expr_struct` for
3635+
// any kind of recovery. Happy path.
3636+
if let Err(err) = self.expect(exp!(OpenBrace)) {
3637+
return Some(Err(err));
3638+
}
3639+
Some(self.parse_expr_struct(qself.clone(), path.clone(), true))
3640+
}
3641+
(false, true) => {
36263642
// We have something like `match foo { bar,` or `match foo { bar:`, which means the
36273643
// user might have meant to write a struct literal as part of the `match`
3628-
// discriminant.
3644+
// discriminant. This is done purely for error recovery.
36293645
let snapshot = self.create_snapshot_for_diagnostic();
36303646
if let Err(err) = self.expect(exp!(OpenBrace)) {
36313647
return Some(Err(err));
@@ -3651,15 +3667,6 @@ impl<'a> Parser<'a> {
36513667
}
36523668
}
36533669
}
3654-
(true, _, _, _) => {
3655-
// A struct is accepted here, try to parse it and rely on `parse_expr_struct` for
3656-
// any kind of recovery.
3657-
if let Err(err) = self.expect(exp!(OpenBrace)) {
3658-
return Some(Err(err));
3659-
}
3660-
Some(self.parse_expr_struct(qself.clone(), path.clone(), true))
3661-
}
3662-
(false, _, _, _) => None,
36633670
}
36643671
}
36653672

0 commit comments

Comments
 (0)