@@ -416,7 +416,7 @@ impl<'tcx> Pat<'tcx> {
416
416
417
417
/// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
418
418
/// works well.
419
- #[ derive( Debug , Clone ) ]
419
+ #[ derive( Debug , Clone , PartialEq ) ]
420
420
crate struct PatStack < ' p , ' tcx > ( SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ) ;
421
421
422
422
impl < ' p , ' tcx > PatStack < ' p , ' tcx > {
@@ -506,7 +506,7 @@ impl<'p, 'tcx> FromIterator<&'p Pat<'tcx>> for PatStack<'p, 'tcx> {
506
506
507
507
/// Depending on the match patterns, the specialization process might be able to use a fast path.
508
508
/// Tracks whether we can use the fast path and the lookup table needed in those cases.
509
- #[ derive( Clone , Debug ) ]
509
+ #[ derive( Clone , Debug , PartialEq ) ]
510
510
enum SpecializationCache {
511
511
/// Patterns consist of only enum variants.
512
512
/// Variant patterns does not intersect with each other (in contrast to range patterns),
@@ -523,7 +523,7 @@ enum SpecializationCache {
523
523
}
524
524
525
525
/// A 2D matrix.
526
- #[ derive( Clone ) ]
526
+ #[ derive( Clone , PartialEq ) ]
527
527
crate struct Matrix < ' p , ' tcx > {
528
528
patterns : Vec < PatStack < ' p , ' tcx > > ,
529
529
cache : SpecializationCache ,
@@ -622,7 +622,19 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
622
622
fn specialize_wildcard ( & self ) -> Self {
623
623
match & self . cache {
624
624
SpecializationCache :: Variants { wilds, .. } => {
625
- wilds. iter ( ) . filter_map ( |& i| self . patterns [ i] . specialize_wildcard ( ) ) . collect ( )
625
+ let result =
626
+ wilds. iter ( ) . filter_map ( |& i| self . patterns [ i] . specialize_wildcard ( ) ) . collect ( ) ;
627
+ // When debug assertions are enabled, check the results against the "slow path"
628
+ // result.
629
+ debug_assert_eq ! (
630
+ result,
631
+ Self {
632
+ patterns: self . patterns. clone( ) ,
633
+ cache: SpecializationCache :: Incompatible
634
+ }
635
+ . specialize_wildcard( )
636
+ ) ;
637
+ result
626
638
}
627
639
SpecializationCache :: Incompatible => {
628
640
self . patterns . iter ( ) . filter_map ( |r| r. specialize_wildcard ( ) ) . collect ( )
@@ -639,7 +651,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
639
651
) -> Matrix < ' p , ' tcx > {
640
652
match & self . cache {
641
653
SpecializationCache :: Variants { lookup, wilds } => {
642
- if let Constructor :: Variant ( id) = constructor {
654
+ let result : Self = if let Constructor :: Variant ( id) = constructor {
643
655
lookup
644
656
. get ( id)
645
657
// Default to `wilds` for absent keys. See `update_cache` for an explanation.
@@ -655,7 +667,22 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
655
667
. collect ( )
656
668
} else {
657
669
unreachable ! ( )
658
- }
670
+ } ;
671
+ // When debug assertions are enabled, check the results against the "slow path"
672
+ // result.
673
+ debug_assert_eq ! (
674
+ result,
675
+ Matrix {
676
+ patterns: self . patterns. clone( ) ,
677
+ cache: SpecializationCache :: Incompatible
678
+ }
679
+ . specialize_constructor(
680
+ cx,
681
+ constructor,
682
+ ctor_wild_subpatterns
683
+ )
684
+ ) ;
685
+ result
659
686
}
660
687
SpecializationCache :: Incompatible => self
661
688
. patterns
0 commit comments