@@ -429,19 +429,9 @@ pub struct Comment {
429
429
///
430
430
/// This type defines its own destructor that uses constant stack space and
431
431
/// heap space proportional to the size of the `Ast`.
432
- ///
433
- /// This type boxes the actual kind of the AST element so that an `Ast` value
434
- /// itself has a very small size. This in turn makes things like `Vec<Ast>` use
435
- /// a lot less memory than it might otherwise, which is particularly beneficial
436
- /// for representing long concatenations or alternations.
437
- #[ derive( Clone , Debug , Eq , PartialEq ) ]
438
- #[ cfg_attr( feature = "arbitrary" , derive( arbitrary:: Arbitrary ) ) ]
439
- pub struct Ast ( pub Box < AstKind > ) ;
440
-
441
- /// The kind of an abstract syntax element.
442
432
#[ derive( Clone , Debug , Eq , PartialEq ) ]
443
433
#[ cfg_attr( feature = "arbitrary" , derive( arbitrary:: Arbitrary ) ) ]
444
- pub enum AstKind {
434
+ pub enum Ast {
445
435
/// An empty regex that matches everything.
446
436
Empty ( Box < Span > ) ,
447
437
/// A set of flags, e.g., `(?is)`.
@@ -473,106 +463,106 @@ pub enum AstKind {
473
463
impl Ast {
474
464
/// Create an "empty" AST item.
475
465
pub fn empty ( span : Span ) -> Ast {
476
- Ast ( Box :: new ( AstKind :: Empty ( Box :: new ( span) ) ) )
466
+ Ast :: Empty ( Box :: new ( span) )
477
467
}
478
468
479
469
/// Create a "flags" AST item.
480
470
pub fn flags ( e : SetFlags ) -> Ast {
481
- Ast ( Box :: new ( AstKind :: Flags ( Box :: new ( e) ) ) )
471
+ Ast :: Flags ( Box :: new ( e) )
482
472
}
483
473
484
474
/// Create a "literal" AST item.
485
475
pub fn literal ( e : Literal ) -> Ast {
486
- Ast ( Box :: new ( AstKind :: Literal ( Box :: new ( e) ) ) )
476
+ Ast :: Literal ( Box :: new ( e) )
487
477
}
488
478
489
479
/// Create a "dot" AST item.
490
480
pub fn dot ( span : Span ) -> Ast {
491
- Ast ( Box :: new ( AstKind :: Dot ( Box :: new ( span) ) ) )
481
+ Ast :: Dot ( Box :: new ( span) )
492
482
}
493
483
494
484
/// Create a "assertion" AST item.
495
485
pub fn assertion ( e : Assertion ) -> Ast {
496
- Ast ( Box :: new ( AstKind :: Assertion ( Box :: new ( e) ) ) )
486
+ Ast :: Assertion ( Box :: new ( e) )
497
487
}
498
488
499
489
/// Create a "Unicode class" AST item.
500
490
pub fn class_unicode ( e : ClassUnicode ) -> Ast {
501
- Ast ( Box :: new ( AstKind :: ClassUnicode ( Box :: new ( e) ) ) )
491
+ Ast :: ClassUnicode ( Box :: new ( e) )
502
492
}
503
493
504
494
/// Create a "Perl class" AST item.
505
495
pub fn class_perl ( e : ClassPerl ) -> Ast {
506
- Ast ( Box :: new ( AstKind :: ClassPerl ( Box :: new ( e) ) ) )
496
+ Ast :: ClassPerl ( Box :: new ( e) )
507
497
}
508
498
509
499
/// Create a "bracketed class" AST item.
510
500
pub fn class_bracketed ( e : ClassBracketed ) -> Ast {
511
- Ast ( Box :: new ( AstKind :: ClassBracketed ( Box :: new ( e) ) ) )
501
+ Ast :: ClassBracketed ( Box :: new ( e) )
512
502
}
513
503
514
504
/// Create a "repetition" AST item.
515
505
pub fn repetition ( e : Repetition ) -> Ast {
516
- Ast ( Box :: new ( AstKind :: Repetition ( Box :: new ( e) ) ) )
506
+ Ast :: Repetition ( Box :: new ( e) )
517
507
}
518
508
519
509
/// Create a "group" AST item.
520
510
pub fn group ( e : Group ) -> Ast {
521
- Ast ( Box :: new ( AstKind :: Group ( Box :: new ( e) ) ) )
511
+ Ast :: Group ( Box :: new ( e) )
522
512
}
523
513
524
514
/// Create a "alternation" AST item.
525
515
pub fn alternation ( e : Alternation ) -> Ast {
526
- Ast ( Box :: new ( AstKind :: Alternation ( Box :: new ( e) ) ) )
516
+ Ast :: Alternation ( Box :: new ( e) )
527
517
}
528
518
529
519
/// Create a "concat" AST item.
530
520
pub fn concat ( e : Concat ) -> Ast {
531
- Ast ( Box :: new ( AstKind :: Concat ( Box :: new ( e) ) ) )
521
+ Ast :: Concat ( Box :: new ( e) )
532
522
}
533
523
534
524
/// Return the span of this abstract syntax tree.
535
525
pub fn span ( & self ) -> & Span {
536
- match * self . 0 {
537
- AstKind :: Empty ( ref span) => span,
538
- AstKind :: Flags ( ref x) => & x. span ,
539
- AstKind :: Literal ( ref x) => & x. span ,
540
- AstKind :: Dot ( ref span) => span,
541
- AstKind :: Assertion ( ref x) => & x. span ,
542
- AstKind :: ClassUnicode ( ref x) => & x. span ,
543
- AstKind :: ClassPerl ( ref x) => & x. span ,
544
- AstKind :: ClassBracketed ( ref x) => & x. span ,
545
- AstKind :: Repetition ( ref x) => & x. span ,
546
- AstKind :: Group ( ref x) => & x. span ,
547
- AstKind :: Alternation ( ref x) => & x. span ,
548
- AstKind :: Concat ( ref x) => & x. span ,
526
+ match * self {
527
+ Ast :: Empty ( ref span) => span,
528
+ Ast :: Flags ( ref x) => & x. span ,
529
+ Ast :: Literal ( ref x) => & x. span ,
530
+ Ast :: Dot ( ref span) => span,
531
+ Ast :: Assertion ( ref x) => & x. span ,
532
+ Ast :: ClassUnicode ( ref x) => & x. span ,
533
+ Ast :: ClassPerl ( ref x) => & x. span ,
534
+ Ast :: ClassBracketed ( ref x) => & x. span ,
535
+ Ast :: Repetition ( ref x) => & x. span ,
536
+ Ast :: Group ( ref x) => & x. span ,
537
+ Ast :: Alternation ( ref x) => & x. span ,
538
+ Ast :: Concat ( ref x) => & x. span ,
549
539
}
550
540
}
551
541
552
542
/// Return true if and only if this Ast is empty.
553
543
pub fn is_empty ( & self ) -> bool {
554
- match * self . 0 {
555
- AstKind :: Empty ( _) => true ,
544
+ match * self {
545
+ Ast :: Empty ( _) => true ,
556
546
_ => false ,
557
547
}
558
548
}
559
549
560
550
/// Returns true if and only if this AST has any (including possibly empty)
561
551
/// subexpressions.
562
552
fn has_subexprs ( & self ) -> bool {
563
- match * self . 0 {
564
- AstKind :: Empty ( _)
565
- | AstKind :: Flags ( _)
566
- | AstKind :: Literal ( _)
567
- | AstKind :: Dot ( _)
568
- | AstKind :: Assertion ( _)
569
- | AstKind :: ClassUnicode ( _)
570
- | AstKind :: ClassPerl ( _) => false ,
571
- AstKind :: ClassBracketed ( _)
572
- | AstKind :: Repetition ( _)
573
- | AstKind :: Group ( _)
574
- | AstKind :: Alternation ( _)
575
- | AstKind :: Concat ( _) => true ,
553
+ match * self {
554
+ Ast :: Empty ( _)
555
+ | Ast :: Flags ( _)
556
+ | Ast :: Literal ( _)
557
+ | Ast :: Dot ( _)
558
+ | Ast :: Assertion ( _)
559
+ | Ast :: ClassUnicode ( _)
560
+ | Ast :: ClassPerl ( _) => false ,
561
+ Ast :: ClassBracketed ( _)
562
+ | Ast :: Repetition ( _)
563
+ | Ast :: Group ( _)
564
+ | Ast :: Alternation ( _)
565
+ | Ast :: Concat ( _) => true ,
576
566
}
577
567
}
578
568
}
@@ -1598,48 +1588,48 @@ impl Drop for Ast {
1598
1588
fn drop ( & mut self ) {
1599
1589
use core:: mem;
1600
1590
1601
- match * self . 0 {
1602
- AstKind :: Empty ( _)
1603
- | AstKind :: Flags ( _)
1604
- | AstKind :: Literal ( _)
1605
- | AstKind :: Dot ( _)
1606
- | AstKind :: Assertion ( _)
1607
- | AstKind :: ClassUnicode ( _)
1608
- | AstKind :: ClassPerl ( _)
1591
+ match * self {
1592
+ Ast :: Empty ( _)
1593
+ | Ast :: Flags ( _)
1594
+ | Ast :: Literal ( _)
1595
+ | Ast :: Dot ( _)
1596
+ | Ast :: Assertion ( _)
1597
+ | Ast :: ClassUnicode ( _)
1598
+ | Ast :: ClassPerl ( _)
1609
1599
// Bracketed classes are recursive, they get their own Drop impl.
1610
- | AstKind :: ClassBracketed ( _) => return ,
1611
- AstKind :: Repetition ( ref x) if !x. ast . has_subexprs ( ) => return ,
1612
- AstKind :: Group ( ref x) if !x. ast . has_subexprs ( ) => return ,
1613
- AstKind :: Alternation ( ref x) if x. asts . is_empty ( ) => return ,
1614
- AstKind :: Concat ( ref x) if x. asts . is_empty ( ) => return ,
1600
+ | Ast :: ClassBracketed ( _) => return ,
1601
+ Ast :: Repetition ( ref x) if !x. ast . has_subexprs ( ) => return ,
1602
+ Ast :: Group ( ref x) if !x. ast . has_subexprs ( ) => return ,
1603
+ Ast :: Alternation ( ref x) if x. asts . is_empty ( ) => return ,
1604
+ Ast :: Concat ( ref x) if x. asts . is_empty ( ) => return ,
1615
1605
_ => { }
1616
1606
}
1617
1607
1618
1608
let empty_span = || Span :: splat ( Position :: new ( 0 , 0 , 0 ) ) ;
1619
1609
let empty_ast = || Ast :: empty ( empty_span ( ) ) ;
1620
1610
let mut stack = vec ! [ mem:: replace( self , empty_ast( ) ) ] ;
1621
1611
while let Some ( mut ast) = stack. pop ( ) {
1622
- match * ast. 0 {
1623
- AstKind :: Empty ( _)
1624
- | AstKind :: Flags ( _)
1625
- | AstKind :: Literal ( _)
1626
- | AstKind :: Dot ( _)
1627
- | AstKind :: Assertion ( _)
1628
- | AstKind :: ClassUnicode ( _)
1629
- | AstKind :: ClassPerl ( _)
1612
+ match ast {
1613
+ Ast :: Empty ( _)
1614
+ | Ast :: Flags ( _)
1615
+ | Ast :: Literal ( _)
1616
+ | Ast :: Dot ( _)
1617
+ | Ast :: Assertion ( _)
1618
+ | Ast :: ClassUnicode ( _)
1619
+ | Ast :: ClassPerl ( _)
1630
1620
// Bracketed classes are recursive, so they get their own Drop
1631
1621
// impl.
1632
- | AstKind :: ClassBracketed ( _) => { }
1633
- AstKind :: Repetition ( ref mut x) => {
1622
+ | Ast :: ClassBracketed ( _) => { }
1623
+ Ast :: Repetition ( ref mut x) => {
1634
1624
stack. push ( mem:: replace ( & mut x. ast , empty_ast ( ) ) ) ;
1635
1625
}
1636
- AstKind :: Group ( ref mut x) => {
1626
+ Ast :: Group ( ref mut x) => {
1637
1627
stack. push ( mem:: replace ( & mut x. ast , empty_ast ( ) ) ) ;
1638
1628
}
1639
- AstKind :: Alternation ( ref mut x) => {
1629
+ Ast :: Alternation ( ref mut x) => {
1640
1630
stack. extend ( x. asts . drain ( ..) ) ;
1641
1631
}
1642
- AstKind :: Concat ( ref mut x) => {
1632
+ Ast :: Concat ( ref mut x) => {
1643
1633
stack. extend ( x. asts . drain ( ..) ) ;
1644
1634
}
1645
1635
}
@@ -1760,35 +1750,13 @@ mod tests {
1760
1750
// 64-bit target. Wow.
1761
1751
#[ test]
1762
1752
fn ast_size ( ) {
1763
- std:: dbg!( core:: mem:: size_of:: <Span >( ) ) ;
1764
- std:: dbg!( core:: mem:: size_of:: <SetFlags >( ) ) ;
1765
- std:: dbg!( core:: mem:: size_of:: <Literal >( ) ) ;
1766
- std:: dbg!( core:: mem:: size_of:: <Span >( ) ) ;
1767
- std:: dbg!( core:: mem:: size_of:: <Assertion >( ) ) ;
1768
- std:: dbg!( core:: mem:: size_of:: <ClassUnicode >( ) ) ;
1769
- std:: dbg!( core:: mem:: size_of:: <ClassPerl >( ) ) ;
1770
- std:: dbg!( core:: mem:: size_of:: <ClassBracketed >( ) ) ;
1771
- std:: dbg!( core:: mem:: size_of:: <Repetition >( ) ) ;
1772
- std:: dbg!( core:: mem:: size_of:: <Group >( ) ) ;
1773
- std:: dbg!( core:: mem:: size_of:: <Alternation >( ) ) ;
1774
- std:: dbg!( core:: mem:: size_of:: <Concat >( ) ) ;
1775
-
1776
- let max = core:: mem:: size_of :: < usize > ( ) ;
1753
+ let max = 2 * core:: mem:: size_of :: < usize > ( ) ;
1777
1754
let size = core:: mem:: size_of :: < Ast > ( ) ;
1778
1755
assert ! (
1779
1756
size <= max,
1780
1757
"Ast size of {} bytes is bigger than suggested max {}" ,
1781
1758
size,
1782
1759
max
1783
1760
) ;
1784
-
1785
- let max = 2 * core:: mem:: size_of :: < usize > ( ) ;
1786
- let size = core:: mem:: size_of :: < AstKind > ( ) ;
1787
- assert ! (
1788
- size <= max,
1789
- "AstKind size of {} bytes is bigger than suggested max {}" ,
1790
- size,
1791
- max
1792
- ) ;
1793
1761
}
1794
1762
}
0 commit comments