Simplify logic slightly · rust-lang/rust@bb48c16 (original) (raw)
`@@ -3612,20 +3612,36 @@ impl<'a> Parser<'a> {
`
3612
3612
`self.token.is_keyword(kw::Async) && self.is_gen_block(kw::Gen, 1)
`
3613
3613
`}
`
3614
3614
``
``
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
+
3615
3621
`fn maybe_parse_struct_expr(
`
3616
3622
`&mut self,
`
3617
3623
`qself: &Option<Boxast::QSelf>,
`
3618
3624
`path: &ast::Path,
`
3619
3625
`) -> Option<PResult<'a, Box>> {
`
3620
3626
`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) => {
`
3626
3642
`` // We have something like match foo { bar, or match foo { bar:, which means the
``
3627
3643
`` // 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.
`
3629
3645
`let snapshot = self.create_snapshot_for_diagnostic();
`
3630
3646
`if let Err(err) = self.expect(exp!(OpenBrace)) {
`
3631
3647
`return Some(Err(err));
`
`@@ -3651,15 +3667,6 @@ impl<'a> Parser<'a> {
`
3651
3667
`}
`
3652
3668
`}
`
3653
3669
`}
`
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,
`
3663
3670
`}
`
3664
3671
`}
`
3665
3672
``