Skip to content

Commit e6b14aa

Browse files
committed
syntax: Merge parsing code for structures and variants
1 parent 5b4986f commit e6b14aa

File tree

3 files changed

+32
-50
lines changed

3 files changed

+32
-50
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4686,18 +4686,21 @@ impl<'a> Parser<'a> {
46864686
VariantData::Unit(ast::DUMMY_NODE_ID)
46874687
} else {
46884688
// If we see: `struct Foo<T> where T: Copy { ... }`
4689-
VariantData::Struct(try!(self.parse_record_struct_body()), ast::DUMMY_NODE_ID)
4689+
VariantData::Struct(try!(self.parse_record_struct_body(true)), ast::DUMMY_NODE_ID)
46904690
}
46914691
// No `where` so: `struct Foo<T>;`
46924692
} else if try!(self.eat(&token::Semi) ){
46934693
VariantData::Unit(ast::DUMMY_NODE_ID)
46944694
// Record-style struct definition
46954695
} else if self.token == token::OpenDelim(token::Brace) {
4696-
VariantData::Struct(try!(self.parse_record_struct_body()), ast::DUMMY_NODE_ID)
4696+
VariantData::Struct(try!(self.parse_record_struct_body(true)), ast::DUMMY_NODE_ID)
46974697
// Tuple-style struct definition with optional where-clause.
46984698
} else if self.token == token::OpenDelim(token::Paren) {
4699-
VariantData::Tuple(try!(self.parse_tuple_struct_body(&mut generics)),
4700-
ast::DUMMY_NODE_ID)
4699+
let body = VariantData::Tuple(try!(self.parse_tuple_struct_body(true)),
4700+
ast::DUMMY_NODE_ID);
4701+
generics.where_clause = try!(self.parse_where_clause());
4702+
try!(self.expect(&token::Semi));
4703+
body
47014704
} else {
47024705
let token_str = self.this_token_to_string();
47034706
return Err(self.fatal(&format!("expected `where`, `{{`, `(`, or `;` after struct \
@@ -4707,11 +4710,11 @@ impl<'a> Parser<'a> {
47074710
Ok((class_name, ItemStruct(vdata, generics), None))
47084711
}
47094712

4710-
pub fn parse_record_struct_body(&mut self) -> PResult<Vec<StructField>> {
4713+
pub fn parse_record_struct_body(&mut self, allow_pub: bool) -> PResult<Vec<StructField>> {
47114714
let mut fields = Vec::new();
47124715
if try!(self.eat(&token::OpenDelim(token::Brace)) ){
47134716
while self.token != token::CloseDelim(token::Brace) {
4714-
fields.push(try!(self.parse_struct_decl_field(true)));
4717+
fields.push(try!(self.parse_struct_decl_field(allow_pub)));
47154718
}
47164719

47174720
try!(self.bump());
@@ -4725,9 +4728,7 @@ impl<'a> Parser<'a> {
47254728
Ok(fields)
47264729
}
47274730

4728-
pub fn parse_tuple_struct_body(&mut self,
4729-
generics: &mut ast::Generics)
4730-
-> PResult<Vec<StructField>> {
4731+
pub fn parse_tuple_struct_body(&mut self, allow_pub: bool) -> PResult<Vec<StructField>> {
47314732
// This is the case where we find `struct Foo<T>(T) where T: Copy;`
47324733
// Unit like structs are handled in parse_item_struct function
47334734
let fields = try!(self.parse_unspanned_seq(
@@ -4738,16 +4739,16 @@ impl<'a> Parser<'a> {
47384739
let attrs = try!(p.parse_outer_attributes());
47394740
let lo = p.span.lo;
47404741
let struct_field_ = ast::StructField_ {
4741-
kind: UnnamedField(try!(p.parse_visibility())),
4742+
kind: UnnamedField (
4743+
if allow_pub { try!(p.parse_visibility()) } else { Inherited }
4744+
),
47424745
id: ast::DUMMY_NODE_ID,
47434746
ty: try!(p.parse_ty_sum()),
47444747
attrs: attrs,
47454748
};
47464749
Ok(spanned(lo, p.span.hi, struct_field_))
47474750
}));
47484751

4749-
generics.where_clause = try!(self.parse_where_clause());
4750-
try!(self.expect(&token::Semi));
47514752
Ok(fields)
47524753
}
47534754

@@ -5133,18 +5134,6 @@ impl<'a> Parser<'a> {
51335134
Ok((ident, ItemTy(ty, tps), None))
51345135
}
51355136

5136-
/// Parse a structure-like enum variant definition
5137-
/// this should probably be renamed or refactored...
5138-
fn parse_struct_def(&mut self) -> PResult<VariantData> {
5139-
let mut fields: Vec<StructField> = Vec::new();
5140-
while self.token != token::CloseDelim(token::Brace) {
5141-
fields.push(try!(self.parse_struct_decl_field(false)));
5142-
}
5143-
try!(self.bump());
5144-
5145-
Ok(VariantData::Struct(fields, ast::DUMMY_NODE_ID))
5146-
}
5147-
51485137
/// Parse the part of an "enum" decl following the '{'
51495138
fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> {
51505139
let mut variants = Vec::new();
@@ -5157,34 +5146,21 @@ impl<'a> Parser<'a> {
51575146
let struct_def;
51585147
let mut disr_expr = None;
51595148
let ident = try!(self.parse_ident());
5160-
if try!(self.eat(&token::OpenDelim(token::Brace)) ){
5149+
if self.check(&token::OpenDelim(token::Brace)) {
51615150
// Parse a struct variant.
51625151
all_nullary = false;
5163-
struct_def = try!(self.parse_struct_def());
5152+
struct_def = VariantData::Struct(try!(self.parse_record_struct_body(false)),
5153+
ast::DUMMY_NODE_ID);
51645154
} else if self.check(&token::OpenDelim(token::Paren)) {
51655155
all_nullary = false;
5166-
let arg_tys = try!(self.parse_enum_variant_seq(
5167-
&token::OpenDelim(token::Paren),
5168-
&token::CloseDelim(token::Paren),
5169-
seq_sep_trailing_allowed(token::Comma),
5170-
|p| p.parse_ty_sum()
5171-
));
5172-
let mut fields = Vec::new();
5173-
for ty in arg_tys {
5174-
fields.push(Spanned { span: ty.span, node: ast::StructField_ {
5175-
ty: ty,
5176-
kind: ast::UnnamedField(ast::Inherited),
5177-
attrs: Vec::new(),
5178-
id: ast::DUMMY_NODE_ID,
5179-
}});
5180-
}
5181-
struct_def = ast::VariantData::Tuple(fields, ast::DUMMY_NODE_ID);
5156+
struct_def = VariantData::Tuple(try!(self.parse_tuple_struct_body(false)),
5157+
ast::DUMMY_NODE_ID);
51825158
} else if try!(self.eat(&token::Eq) ){
51835159
disr_expr = Some(try!(self.parse_expr_nopanic()));
51845160
any_disr = disr_expr.as_ref().map(|expr| expr.span);
5185-
struct_def = ast::VariantData::Unit(ast::DUMMY_NODE_ID);
5161+
struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
51865162
} else {
5187-
struct_def = ast::VariantData::Unit(ast::DUMMY_NODE_ID);
5163+
struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
51885164
}
51895165

51905166
let vr = ast::Variant_ {

src/test/parse-fail/issue-12560-1.rs renamed to src/test/compile-fail/issue-12560-1.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// compile-flags: -Z parse-only
12-
1311
// For style and consistency reasons, non-parametrized enum variants must
1412
// be used simply as `ident` instead of `ident ()`.
1513
// This test-case covers enum declaration.
1614

1715
enum Foo {
18-
Bar(), //~ ERROR nullary enum variants are written with no trailing `( )`
19-
Baz(), //~ ERROR nullary enum variants are written with no trailing `( )`
16+
Bar(), //~ ERROR empty tuple structs and enum variants are not allowed
17+
Baz(), //~ ERROR empty tuple structs and enum variants are not allowed
2018
Bazar
2119
}
2220

src/test/compile-fail/issue-16819.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,17 @@
1010

1111
struct TS ( //~ ERROR empty tuple structs and enum variants are not allowed
1212
#[cfg(untrue)]
13-
int,
13+
i32,
1414
);
1515

16+
enum E {
17+
TV ( //~ ERROR empty tuple structs and enum variants are not allowed
18+
#[cfg(untrue)]
19+
i32,
20+
)
21+
}
22+
1623
fn main() {
17-
let s = S;
24+
let s = TS;
25+
let tv = E::TV;
1826
}

0 commit comments

Comments
 (0)