File tree Expand file tree Collapse file tree 2 files changed +41
-12
lines changed Expand file tree Collapse file tree 2 files changed +41
-12
lines changed Original file line number Diff line number Diff line change @@ -398,20 +398,29 @@ impl Hir {
398
398
/// Returns the alternation of the given expressions.
399
399
///
400
400
/// This flattens the alternation as appropriate.
401
- pub fn alternation ( mut exprs : Vec < Hir > ) -> Hir {
402
- if exprs. is_empty ( ) {
403
- return Hir :: fail ( ) ;
404
- } else if exprs. len ( ) == 1 {
405
- return exprs. pop ( ) . unwrap ( ) ;
406
- }
407
- match exprs. len ( ) {
408
- 0 => Hir :: empty ( ) ,
409
- 1 => exprs. pop ( ) . unwrap ( ) ,
410
- _ => {
411
- let props = Properties :: alternation ( & exprs) ;
412
- Hir { kind : HirKind :: Alternation ( exprs) , props }
401
+ pub fn alternation ( hirs : Vec < Hir > ) -> Hir {
402
+ // We rebuild the alternation by simplifying it. We proceed similarly
403
+ // as the concatenation case. But in this case, there's no literal
404
+ // simplification happening. We're just flattening alternations.
405
+ let mut new = vec ! [ ] ;
406
+ for hir in hirs {
407
+ let ( kind, props) = hir. into_parts ( ) ;
408
+ match kind {
409
+ HirKind :: Alternation ( hirs2) => {
410
+ new. extend ( hirs2) ;
411
+ }
412
+ kind => {
413
+ new. push ( Hir { kind, props } ) ;
414
+ }
413
415
}
414
416
}
417
+ if new. is_empty ( ) {
418
+ return Hir :: fail ( ) ;
419
+ } else if new. len ( ) == 1 {
420
+ return new. pop ( ) . unwrap ( ) ;
421
+ }
422
+ let props = Properties :: alternation ( & new) ;
423
+ Hir { kind : HirKind :: Alternation ( new) , props }
415
424
}
416
425
417
426
/// Returns an HIR expression for `.`.
Original file line number Diff line number Diff line change @@ -3335,4 +3335,24 @@ mod tests {
3335
3335
] )
3336
3336
) ;
3337
3337
}
3338
+
3339
+ // This tests that the smart Hir::alternation constructor simplifies the
3340
+ // given exprs in a way we expect.
3341
+ #[ test]
3342
+ fn smart_alternation ( ) {
3343
+ assert_eq ! (
3344
+ t( "(?:foo)|(?:bar)" ) ,
3345
+ hir_alt( vec![ hir_lit( "foo" ) , hir_lit( "bar" ) ] )
3346
+ ) ;
3347
+ assert_eq ! (
3348
+ t( "quux|(?:abc|def|xyz)|baz" ) ,
3349
+ hir_alt( vec![
3350
+ hir_lit( "quux" ) ,
3351
+ hir_lit( "abc" ) ,
3352
+ hir_lit( "def" ) ,
3353
+ hir_lit( "xyz" ) ,
3354
+ hir_lit( "baz" ) ,
3355
+ ] )
3356
+ ) ;
3357
+ }
3338
3358
}
You can’t perform that action at this time.
0 commit comments