Skip to content

Commit 1f28313

Browse files
committed
Auto merge of #22720 - edwardw:enum-struct-ident-walk-into-a-bar, r=<try>
Closes #22426 Closes #22589 Closes #22665 Closes #22712
2 parents 2890508 + 2931c21 commit 1f28313

File tree

3 files changed

+79
-45
lines changed

3 files changed

+79
-45
lines changed

src/libsyntax/parse/parser.rs

+37-45
Original file line numberDiff line numberDiff line change
@@ -3508,52 +3508,44 @@ impl<'a> Parser<'a> {
35083508
self.bump();
35093509
pat = PatStruct(enum_path, fields, etc);
35103510
}
3511-
_ => {
3512-
let mut args: Vec<P<Pat>> = Vec::new();
3513-
match self.token {
3514-
token::OpenDelim(token::Paren) => {
3515-
let is_dotdot = self.look_ahead(1, |t| {
3516-
match *t {
3517-
token::DotDot => true,
3518-
_ => false,
3519-
}
3520-
});
3521-
if is_dotdot {
3522-
// This is a "top constructor only" pat
3523-
self.bump();
3524-
self.bump();
3525-
self.expect(&token::CloseDelim(token::Paren));
3526-
pat = PatEnum(enum_path, None);
3527-
} else {
3528-
args = self.parse_enum_variant_seq(
3529-
&token::OpenDelim(token::Paren),
3530-
&token::CloseDelim(token::Paren),
3531-
seq_sep_trailing_allowed(token::Comma),
3532-
|p| p.parse_pat()
3533-
);
3534-
pat = PatEnum(enum_path, Some(args));
3511+
token::OpenDelim(token::Paren) => {
3512+
let is_dotdot = self.look_ahead(1, |t| {
3513+
match *t {
3514+
token::DotDot => true,
3515+
_ => false,
35353516
}
3536-
},
3537-
_ => {
3538-
if !enum_path.global &&
3539-
enum_path.segments.len() == 1 &&
3540-
enum_path.segments[0].parameters.is_empty()
3541-
{
3542-
// NB: If enum_path is a single identifier,
3543-
// this should not be reachable due to special
3544-
// handling further above.
3545-
//
3546-
// However, previously a PatIdent got emitted
3547-
// here, so we preserve the branch just in case.
3548-
//
3549-
// A rewrite of the logic in this function
3550-
// would probably make this obvious.
3551-
self.span_bug(enum_path.span,
3552-
"ident only path should have been covered already");
3553-
} else {
3554-
pat = PatEnum(enum_path, Some(args));
3555-
}
3556-
}
3517+
});
3518+
if is_dotdot {
3519+
// This is a "top constructor only" pat
3520+
self.bump();
3521+
self.bump();
3522+
self.expect(&token::CloseDelim(token::Paren));
3523+
pat = PatEnum(enum_path, None);
3524+
} else {
3525+
let args = self.parse_enum_variant_seq(
3526+
&token::OpenDelim(token::Paren),
3527+
&token::CloseDelim(token::Paren),
3528+
seq_sep_trailing_allowed(token::Comma),
3529+
|p| p.parse_pat()
3530+
);
3531+
pat = PatEnum(enum_path, Some(args));
3532+
}
3533+
}
3534+
_ => {
3535+
if !enum_path.global &&
3536+
enum_path.segments.len() == 1 &&
3537+
enum_path.segments[0].parameters.is_empty()
3538+
{
3539+
// We expect an identifier, but due to
3540+
// `can_be_enum_or_struct` is true above,
3541+
// we reach here instead.
3542+
let tok_str = pprust::path_to_string(&enum_path);
3543+
self.span_fatal(
3544+
enum_path.span,
3545+
&format!("expected identifier, found enum or struct `{}`",
3546+
tok_str));
3547+
} else {
3548+
pat = PatEnum(enum_path, Some(Vec::new()));
35573549
}
35583550
}
35593551
}

src/test/parse-fail/issue-22426.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub struct Foo<T>(T, T);
12+
13+
impl<T> Foo<T> {
14+
fn foo(&self) {
15+
match *self {
16+
// The error message is not ideal in this case, can we do
17+
// better here?
18+
Foo<T>(ref x, ref y) => {} //~ ERROR expected identifier, found enum or struct
19+
}
20+
}
21+
}
22+
23+
fn main() {}

src/test/parse-fail/issue-22712.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct Foo<B> {
12+
buffer: B
13+
}
14+
15+
fn bar() {
16+
let Foo<Vec<u8>> //~ ERROR expected identifier, found enum or struct
17+
}
18+
19+
fn main() {}

0 commit comments

Comments
 (0)