@@ -113,6 +113,13 @@ pub enum BoundParsingMode {
113
113
Modified ,
114
114
}
115
115
116
+ /// `pub` should be parsed in struct fields and not parsed in variant fields
117
+ #[ derive( Clone , Copy , PartialEq ) ]
118
+ pub enum ParsePub {
119
+ Yes ,
120
+ No ,
121
+ }
122
+
116
123
/// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
117
124
/// dropped into the token stream, which happens while parsing the result of
118
125
/// macro expansion). Placement of these is not as complex as I feared it would
@@ -4686,18 +4693,23 @@ impl<'a> Parser<'a> {
4686
4693
VariantData :: Unit ( ast:: DUMMY_NODE_ID )
4687
4694
} else {
4688
4695
// If we see: `struct Foo<T> where T: Copy { ... }`
4689
- VariantData :: Struct ( try!( self . parse_record_struct_body ( ) ) , ast:: DUMMY_NODE_ID )
4696
+ VariantData :: Struct ( try!( self . parse_record_struct_body ( ParsePub :: Yes ) ) ,
4697
+ ast:: DUMMY_NODE_ID )
4690
4698
}
4691
4699
// No `where` so: `struct Foo<T>;`
4692
4700
} else if try!( self . eat ( & token:: Semi ) ) {
4693
4701
VariantData :: Unit ( ast:: DUMMY_NODE_ID )
4694
4702
// Record-style struct definition
4695
4703
} else if self . token == token:: OpenDelim ( token:: Brace ) {
4696
- VariantData :: Struct ( try!( self . parse_record_struct_body ( ) ) , ast:: DUMMY_NODE_ID )
4704
+ VariantData :: Struct ( try!( self . parse_record_struct_body ( ParsePub :: Yes ) ) ,
4705
+ ast:: DUMMY_NODE_ID )
4697
4706
// Tuple-style struct definition with optional where-clause.
4698
4707
} else if self . token == token:: OpenDelim ( token:: Paren ) {
4699
- VariantData :: Tuple ( try!( self . parse_tuple_struct_body ( & mut generics) ) ,
4700
- ast:: DUMMY_NODE_ID )
4708
+ let body = VariantData :: Tuple ( try!( self . parse_tuple_struct_body ( ParsePub :: Yes ) ) ,
4709
+ ast:: DUMMY_NODE_ID ) ;
4710
+ generics. where_clause = try!( self . parse_where_clause ( ) ) ;
4711
+ try!( self . expect ( & token:: Semi ) ) ;
4712
+ body
4701
4713
} else {
4702
4714
let token_str = self . this_token_to_string ( ) ;
4703
4715
return Err ( self . fatal ( & format ! ( "expected `where`, `{{`, `(`, or `;` after struct \
@@ -4707,11 +4719,11 @@ impl<'a> Parser<'a> {
4707
4719
Ok ( ( class_name, ItemStruct ( vdata, generics) , None ) )
4708
4720
}
4709
4721
4710
- pub fn parse_record_struct_body ( & mut self ) -> PResult < Vec < StructField > > {
4722
+ pub fn parse_record_struct_body ( & mut self , parse_pub : ParsePub ) -> PResult < Vec < StructField > > {
4711
4723
let mut fields = Vec :: new ( ) ;
4712
4724
if try!( self . eat ( & token:: OpenDelim ( token:: Brace ) ) ) {
4713
4725
while self . token != token:: CloseDelim ( token:: Brace ) {
4714
- fields. push ( try!( self . parse_struct_decl_field ( true ) ) ) ;
4726
+ fields. push ( try!( self . parse_struct_decl_field ( parse_pub ) ) ) ;
4715
4727
}
4716
4728
4717
4729
try!( self . bump ( ) ) ;
@@ -4725,9 +4737,7 @@ impl<'a> Parser<'a> {
4725
4737
Ok ( fields)
4726
4738
}
4727
4739
4728
- pub fn parse_tuple_struct_body ( & mut self ,
4729
- generics : & mut ast:: Generics )
4730
- -> PResult < Vec < StructField > > {
4740
+ pub fn parse_tuple_struct_body ( & mut self , parse_pub : ParsePub ) -> PResult < Vec < StructField > > {
4731
4741
// This is the case where we find `struct Foo<T>(T) where T: Copy;`
4732
4742
// Unit like structs are handled in parse_item_struct function
4733
4743
let fields = try!( self . parse_unspanned_seq (
@@ -4738,16 +4748,20 @@ impl<'a> Parser<'a> {
4738
4748
let attrs = try!( p. parse_outer_attributes ( ) ) ;
4739
4749
let lo = p. span . lo ;
4740
4750
let struct_field_ = ast:: StructField_ {
4741
- kind : UnnamedField ( try!( p. parse_visibility ( ) ) ) ,
4751
+ kind : UnnamedField (
4752
+ if parse_pub == ParsePub :: Yes {
4753
+ try!( p. parse_visibility ( ) )
4754
+ } else {
4755
+ Inherited
4756
+ }
4757
+ ) ,
4742
4758
id : ast:: DUMMY_NODE_ID ,
4743
4759
ty : try!( p. parse_ty_sum ( ) ) ,
4744
4760
attrs : attrs,
4745
4761
} ;
4746
4762
Ok ( spanned ( lo, p. span . hi , struct_field_) )
4747
4763
} ) ) ;
4748
4764
4749
- generics. where_clause = try!( self . parse_where_clause ( ) ) ;
4750
- try!( self . expect ( & token:: Semi ) ) ;
4751
4765
Ok ( fields)
4752
4766
}
4753
4767
@@ -4775,12 +4789,12 @@ impl<'a> Parser<'a> {
4775
4789
}
4776
4790
4777
4791
/// Parse an element of a struct definition
4778
- fn parse_struct_decl_field ( & mut self , allow_pub : bool ) -> PResult < StructField > {
4792
+ fn parse_struct_decl_field ( & mut self , parse_pub : ParsePub ) -> PResult < StructField > {
4779
4793
4780
4794
let attrs = try!( self . parse_outer_attributes ( ) ) ;
4781
4795
4782
4796
if try!( self . eat_keyword ( keywords:: Pub ) ) {
4783
- if !allow_pub {
4797
+ if parse_pub == ParsePub :: No {
4784
4798
let span = self . last_span ;
4785
4799
self . span_err ( span, "`pub` is not allowed here" ) ;
4786
4800
}
@@ -5133,18 +5147,6 @@ impl<'a> Parser<'a> {
5133
5147
Ok ( ( ident, ItemTy ( ty, tps) , None ) )
5134
5148
}
5135
5149
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
-
5148
5150
/// Parse the part of an "enum" decl following the '{'
5149
5151
fn parse_enum_def ( & mut self , _generics : & ast:: Generics ) -> PResult < EnumDef > {
5150
5152
let mut variants = Vec :: new ( ) ;
@@ -5157,34 +5159,21 @@ impl<'a> Parser<'a> {
5157
5159
let struct_def;
5158
5160
let mut disr_expr = None ;
5159
5161
let ident = try!( self . parse_ident ( ) ) ;
5160
- if try! ( self . eat ( & token:: OpenDelim ( token:: Brace ) ) ) {
5162
+ if self . check ( & token:: OpenDelim ( token:: Brace ) ) {
5161
5163
// Parse a struct variant.
5162
5164
all_nullary = false ;
5163
- struct_def = try!( self . parse_struct_def ( ) ) ;
5165
+ struct_def = VariantData :: Struct ( try!( self . parse_record_struct_body ( ParsePub :: No ) ) ,
5166
+ ast:: DUMMY_NODE_ID ) ;
5164
5167
} else if self . check ( & token:: OpenDelim ( token:: Paren ) ) {
5165
5168
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 ) ;
5169
+ struct_def = VariantData :: Tuple ( try!( self . parse_tuple_struct_body ( ParsePub :: No ) ) ,
5170
+ ast:: DUMMY_NODE_ID ) ;
5182
5171
} else if try!( self . eat ( & token:: Eq ) ) {
5183
5172
disr_expr = Some ( try!( self . parse_expr_nopanic ( ) ) ) ;
5184
5173
any_disr = disr_expr. as_ref ( ) . map ( |expr| expr. span ) ;
5185
- struct_def = ast :: VariantData :: Unit ( ast:: DUMMY_NODE_ID ) ;
5174
+ struct_def = VariantData :: Unit ( ast:: DUMMY_NODE_ID ) ;
5186
5175
} else {
5187
- struct_def = ast :: VariantData :: Unit ( ast:: DUMMY_NODE_ID ) ;
5176
+ struct_def = VariantData :: Unit ( ast:: DUMMY_NODE_ID ) ;
5188
5177
}
5189
5178
5190
5179
let vr = ast:: Variant_ {
0 commit comments