Simplify logic slightly

This commit is contained in:
Esteban Küber
2025-09-24 23:25:29 +00:00
parent 43057698c1
commit bb48c162b6

View File

@@ -3612,20 +3612,36 @@ impl<'a> Parser<'a> {
self.token.is_keyword(kw::Async) && self.is_gen_block(kw::Gen, 1)
}
fn is_likely_struct_lit(&self) -> bool {
// `{ ident, ` and `{ ident: ` cannot start a block.
self.look_ahead(1, |t| t.is_ident())
&& self.look_ahead(2, |t| t == &token::Comma || t == &token::Colon)
}
fn maybe_parse_struct_expr(
&mut self,
qself: &Option<Box<ast::QSelf>>,
path: &ast::Path,
) -> Option<PResult<'a, Box<Expr>>> {
let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
let is_ident = self.look_ahead(1, |t| t.is_ident());
let is_comma = self.look_ahead(2, |t| t == &token::Comma);
let is_colon = self.look_ahead(2, |t| t == &token::Colon);
match (struct_allowed, is_ident, is_comma, is_colon) {
(false, true, true, _) | (false, true, _, true) => {
match (struct_allowed, self.is_likely_struct_lit()) {
// A struct literal isn't expected and one is pretty much assured not to be present. The
// only situation that isn't detected is when a struct with a single field was attempted
// in a place where a struct literal wasn't expected, but regular parser errors apply.
// Happy path.
(false, false) => None,
(true, _) => {
// A struct is accepted here, try to parse it and rely on `parse_expr_struct` for
// any kind of recovery. Happy path.
if let Err(err) = self.expect(exp!(OpenBrace)) {
return Some(Err(err));
}
Some(self.parse_expr_struct(qself.clone(), path.clone(), true))
}
(false, true) => {
// We have something like `match foo { bar,` or `match foo { bar:`, which means the
// user might have meant to write a struct literal as part of the `match`
// discriminant.
// discriminant. This is done purely for error recovery.
let snapshot = self.create_snapshot_for_diagnostic();
if let Err(err) = self.expect(exp!(OpenBrace)) {
return Some(Err(err));
@@ -3651,15 +3667,6 @@ impl<'a> Parser<'a> {
}
}
}
(true, _, _, _) => {
// A struct is accepted here, try to parse it and rely on `parse_expr_struct` for
// any kind of recovery.
if let Err(err) = self.expect(exp!(OpenBrace)) {
return Some(Err(err));
}
Some(self.parse_expr_struct(qself.clone(), path.clone(), true))
}
(false, _, _, _) => None,
}
}