@@ -304,7 +304,7 @@ impl<Pat: RustInputPat> NodeShapeMethods<Pat> for NodeShape<IRule> {
304
304
let variant = match shape {
305
305
NodeShape :: Opaque => quote ! ( Opaque ) ,
306
306
NodeShape :: Alias ( inner) => quote ! ( Alias ( #inner) ) ,
307
- NodeShape :: Choice => quote ! ( Choice ) ,
307
+ NodeShape :: Choice ( count ) => quote ! ( Choice ( #count ) ) ,
308
308
NodeShape :: Opt ( inner) => quote ! ( Opt ( #inner) ) ,
309
309
NodeShape :: Split ( left, right) => quote ! ( Split ( #left, #right) ) ,
310
310
} ;
@@ -389,6 +389,13 @@ impl<Pat: MatchesEmpty + RustInputPat> GrammarGenerateMethods<Pat> for grammer::
389
389
let rule = * rules. anon . get_index ( i) . unwrap ( ) ;
390
390
rule. node_shape ( cx, Some ( rules. named ) )
391
391
. map ( |rule| rule. node_kind ( cx, & mut rules) ) ;
392
+ // HACK(eddyb) this is needed because `NodeShape` doesn't
393
+ // encode `Choice` cases directly, only their count.
394
+ if let Rule :: Or ( cases) = & cx[ rule] {
395
+ for & rule in cases {
396
+ rule. node_kind ( cx, & mut rules) ;
397
+ }
398
+ }
392
399
i += 1 ;
393
400
}
394
401
@@ -727,12 +734,11 @@ fn reify_as<Pat>(label: Rc<CodeLabel>) -> Thunk<impl ContFn<Pat>> {
727
734
} )
728
735
}
729
736
730
- fn forest_add_choice < Pat : RustInputPat > ( rule : IRule , choice : IRule ) -> Thunk < impl ContFn < Pat > > {
737
+ fn forest_add_choice < Pat : RustInputPat > ( rule : IRule , choice : usize ) -> Thunk < impl ContFn < Pat > > {
731
738
Thunk :: new ( move |mut cont| {
732
739
if let Some ( rules) = & mut cont. rules . as_mut ( ) {
733
740
let node_kind_src = rule. node_kind ( cont. cx , rules) . to_src ( ) ;
734
- let choice_src = choice. node_kind ( cont. cx , rules) . to_src ( ) ;
735
- cont = thunk ! ( rt. forest_add_choice( #node_kind_src, #choice_src) ; ) . apply ( cont) ;
741
+ cont = thunk ! ( rt. forest_add_choice( #node_kind_src, #choice) ; ) . apply ( cont) ;
736
742
}
737
743
cont
738
744
} )
@@ -794,8 +800,8 @@ impl<Pat: RustInputPat> RuleGenerateMethods<Pat> for IRule {
794
800
concat_and_forest_add ( self , left, right. generate_parse ( ) ) . apply ( cont)
795
801
}
796
802
Rule :: Or ( ref cases) => {
797
- parallel ( ThunkIter ( cases. iter ( ) . map ( |& rule| {
798
- rule. generate_parse ( ) + forest_add_choice ( self , rule )
803
+ parallel ( ThunkIter ( cases. iter ( ) . enumerate ( ) . map ( |( i , & rule) | {
804
+ rule. generate_parse ( ) + forest_add_choice ( self , i )
799
805
} ) ) )
800
806
. apply ( cont)
801
807
}
@@ -1407,6 +1413,19 @@ fn declare_node_kind<Pat: RustInputPat>(
1407
1413
. iter ( )
1408
1414
. map ( |& rule| rule. node_shape ( cx, Some ( rules. named ) ) . to_src ( cx, rules) )
1409
1415
. collect :: < Vec < _ > > ( ) ;
1416
+ let nodes_shape_choices = all_rules
1417
+ . iter ( )
1418
+ . map ( |& rule| {
1419
+ let choices = match & cx[ rule] {
1420
+ Rule :: Or ( choices) => & choices[ ..] ,
1421
+ _ => & [ ] ,
1422
+ } ;
1423
+ let choices = choices
1424
+ . iter ( )
1425
+ . map ( |rule| rule. node_kind ( cx, rules) . to_src ( ) ) ;
1426
+ quote ! ( [ #( #choices, ) * ] )
1427
+ } )
1428
+ . collect :: < Vec < _ > > ( ) ;
1410
1429
1411
1430
quote ! (
1412
1431
pub struct _G;
@@ -1427,6 +1446,11 @@ fn declare_node_kind<Pat: RustInputPat>(
1427
1446
#( #nodes_kind_src => #nodes_shape_src) , *
1428
1447
}
1429
1448
}
1449
+ fn node_shape_choice_get( & self , kind: _P, i: usize ) -> _P {
1450
+ match kind {
1451
+ #( #nodes_kind_src => #nodes_shape_choices[ i] ) , *
1452
+ }
1453
+ }
1430
1454
fn node_desc( & self , kind: _P) -> String {
1431
1455
let s = match kind {
1432
1456
#( #nodes_kind_src => #nodes_desc) , *
0 commit comments