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

``