@@ -892,10 +892,6 @@ impl<Pat: RustInputPat> RuleWithFieldsGenerateMethods<Pat> for RuleWithFields {
892
892
quote ! ( ( #left, #right) )
893
893
}
894
894
Rule :: Or ( ref cases) => {
895
- let cases_idx = cases
896
- . iter ( )
897
- . enumerate ( )
898
- . map ( |( i, _) | Src :: ident ( format ! ( "_{}" , i) ) ) ;
899
895
// HACK(eddyb) only collected to a `Vec` to avoid `rules` borrow conflicts.
900
896
let cases_shape = cases
901
897
. iter ( )
@@ -906,7 +902,7 @@ impl<Pat: RustInputPat> RuleWithFieldsGenerateMethods<Pat> for RuleWithFields {
906
902
. collect :: < Vec < _ > > ( ) ;
907
903
let cases_node_kind = cases. iter ( ) . map ( |rule| rule. node_kind ( cx, rules) ) ;
908
904
let cases_node_kind_src = cases_node_kind. map ( |kind| kind. to_src ( ) ) ;
909
- quote ! ( { # ( #cases_idx : #cases_node_kind_src => #cases_shape, ) * } )
905
+ quote ! ( { _P ; # ( #cases_node_kind_src => #cases_shape, ) * } )
910
906
}
911
907
Rule :: Opt ( rule) => {
912
908
let shape = child ( rule, 0 ) . generate_traverse_shape ( cx, rules, rust_fields) ;
@@ -1133,7 +1129,7 @@ where
1133
1129
Pat : RustInputPat ,
1134
1130
{
1135
1131
let ident = Src :: ident ( & cx[ name] ) ;
1136
- let ( one, all) = match rust_adt {
1132
+ let ( consts , one, all) = match rust_adt {
1137
1133
RustAdt :: Enum ( variants) => {
1138
1134
let variants_fields_len = variants. values ( ) . map ( |( _, variant) | match variant {
1139
1135
RustVariant :: Newtype ( _) => 0 ,
@@ -1156,6 +1152,10 @@ where
1156
1152
. iter ( )
1157
1153
. map ( |kind| kind. to_src ( ) )
1158
1154
. collect :: < Vec < _ > > ( ) ;
1155
+ let variants_shape_ident = variants
1156
+ . keys ( )
1157
+ . map ( |& v_name| Src :: ident ( format ! ( "{}_SHAPE" , & cx[ v_name] ) ) )
1158
+ . collect :: < Vec < _ > > ( ) ;
1159
1159
let variants_shape = variants
1160
1160
. values ( )
1161
1161
. map ( |( v_rule, variant) | match variant {
@@ -1167,16 +1167,22 @@ where
1167
1167
. collect :: < Vec < _ > > ( ) ;
1168
1168
1169
1169
(
1170
+ quote ! ( #(
1171
+ #[ allow( non_upper_case_globals) ]
1172
+ const #variants_shape_ident: traverse:: ty!( #variants_shape) = traverse:: new!( #variants_shape) ;
1173
+ ) * ) ,
1170
1174
quote ! (
1171
- let node = forest. one_choice( node) ?;
1172
- match node. kind {
1175
+ forest. one_choice( node) . and_then( |node| match node. kind {
1173
1176
#( #variants_kind_src => {
1174
1177
let mut r = [ None ; #variants_fields_len] ;
1175
- traverse!( one( forest, node, r) #variants_shape) ;
1176
- #ident:: #variants_from_forest_ident( self . forest, node, r)
1178
+ #ident:: <I >:: #variants_shape_ident
1179
+ . one( forest, node, & mut r)
1180
+ . map( |( ) | {
1181
+ #ident:: #variants_from_forest_ident( self . forest, node, r)
1182
+ } )
1177
1183
} ) *
1178
1184
_ => unreachable!( )
1179
- }
1185
+ } )
1180
1186
) ,
1181
1187
quote ! (
1182
1188
#[ derive( Clone ) ]
@@ -1195,13 +1201,14 @@ where
1195
1201
1196
1202
forest. all_choices( node) . flat_map( move |node| {
1197
1203
match node. kind {
1198
- #( #variants_kind_src => Iter :: #i_ident(
1199
- traverse!( all( forest, node) #variants_shape)
1204
+ #( #variants_kind_src => Iter :: #i_ident( {
1205
+ #ident:: <I >:: #variants_shape_ident
1206
+ . all( forest, node)
1200
1207
. into_iter( )
1201
1208
. map( move |r| {
1202
1209
#ident:: #variants_from_forest_ident( self . forest, node, r)
1203
1210
} )
1204
- ) , ) *
1211
+ } ) , ) *
1205
1212
_ => unreachable!( ) ,
1206
1213
}
1207
1214
} )
@@ -1212,13 +1219,19 @@ where
1212
1219
let fields_len = fields. len ( ) ;
1213
1220
let shape = rule. generate_traverse_shape ( cx, rules, fields) ;
1214
1221
(
1222
+ quote ! (
1223
+ #[ allow( non_upper_case_globals) ]
1224
+ const SHAPE : traverse:: ty!( #shape) = traverse:: new!( #shape) ;
1225
+ ) ,
1215
1226
quote ! (
1216
1227
let mut r = [ None ; #fields_len] ;
1217
- traverse!( one( forest, node, r) #shape) ;
1218
- #ident:: from_forest( self . forest, node, r)
1228
+ #ident:: <I >:: SHAPE
1229
+ . one( forest, node, & mut r)
1230
+ . map( |( ) | #ident:: from_forest( self . forest, node, r) )
1219
1231
) ,
1220
1232
quote ! (
1221
- traverse!( all( forest, node) #shape)
1233
+ #ident:: <I >:: SHAPE
1234
+ . all( forest, node)
1222
1235
. into_iter( )
1223
1236
. map( move |r| {
1224
1237
#ident:: from_forest( self . forest, node, r)
@@ -1228,24 +1241,29 @@ where
1228
1241
}
1229
1242
} ;
1230
1243
1231
- quote ! ( impl <' a, ' i, I > Handle <' a, ' i, I , #ident<' a, ' i, I >>
1244
+ quote ! (
1245
+ impl <' a, ' i, I : gll:: grammer:: input:: Input > #ident<' a, ' i, I > {
1246
+ #consts
1247
+ }
1248
+
1249
+ impl <' a, ' i, I > Handle <' a, ' i, I , #ident<' a, ' i, I >>
1232
1250
where I : gll:: grammer:: input:: Input ,
1233
1251
{
1252
+ #consts
1253
+
1234
1254
pub fn one( self ) -> Result <#ident<' a, ' i, I >, Ambiguity <Self >> {
1235
- // HACK(eddyb) using a closure to catch `Err`s from `?`
1236
- ( || Ok ( {
1237
- let forest = self . forest;
1238
- let node = forest. unpack_alias( self . node) ;
1239
- #one
1240
- } ) ) ( ) . map_err( |gll:: grammer:: forest:: MoreThanOne | Ambiguity ( self ) )
1255
+ let forest = self . forest;
1256
+ let node = forest. unpack_alias( self . node) ;
1257
+ #one. map_err( |gll:: grammer:: forest:: MoreThanOne | Ambiguity ( self ) )
1241
1258
}
1242
1259
1243
1260
pub fn all( self ) -> impl Iterator <Item = #ident<' a, ' i, I >> {
1244
1261
let forest = self . forest;
1245
1262
let node = forest. unpack_alias( self . node) ;
1246
1263
#all
1247
1264
}
1248
- } )
1265
+ }
1266
+ )
1249
1267
}
1250
1268
1251
1269
fn rule_debug_impls < Pat > ( cx : & Context < Pat > , name : IStr , rust_adt : & RustAdt ) -> Src {
0 commit comments