@@ -589,22 +589,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
589
589
// away.)
590
590
let ( match_pair_index, match_pair) =
591
591
candidate. match_pairs . iter ( ) . enumerate ( ) . find ( |& ( _, mp) | mp. place == * test_place) ?;
592
+ let mut fully_matched = false ;
592
593
593
- match ( & test. kind , & match_pair. pattern . kind ) {
594
+ let ret = match ( & test. kind , & match_pair. pattern . kind ) {
594
595
// If we are performing a variant switch, then this
595
596
// informs variant patterns, but nothing else.
596
597
(
597
598
& TestKind :: Switch { adt_def : tested_adt_def, .. } ,
598
- & PatKind :: Variant { adt_def, variant_index, ref subpatterns , .. } ,
599
+ & PatKind :: Variant { adt_def, variant_index, .. } ,
599
600
) => {
600
601
assert_eq ! ( adt_def, tested_adt_def) ;
601
- self . candidate_after_variant_switch (
602
- match_pair_index,
603
- adt_def,
604
- variant_index,
605
- subpatterns,
606
- candidate,
607
- ) ;
602
+ fully_matched = true ;
608
603
Some ( variant_index. as_usize ( ) )
609
604
}
610
605
@@ -618,8 +613,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
618
613
( TestKind :: SwitchInt { switch_ty : _, options } , PatKind :: Constant { value } )
619
614
if is_switch_ty ( match_pair. pattern . ty ) =>
620
615
{
616
+ fully_matched = true ;
621
617
let index = options. get_index_of ( value) . unwrap ( ) ;
622
- self . candidate_without_match_pair ( match_pair_index, candidate) ;
623
618
Some ( index)
624
619
}
625
620
@@ -645,13 +640,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
645
640
( Ordering :: Equal , & None ) => {
646
641
// on true, min_len = len = $actual_length,
647
642
// on false, len != $actual_length
648
- self . candidate_after_slice_test (
649
- match_pair_index,
650
- candidate,
651
- prefix,
652
- slice,
653
- suffix,
654
- ) ;
643
+ fully_matched = true ;
655
644
Some ( 0 )
656
645
}
657
646
( Ordering :: Less , _) => {
@@ -683,13 +672,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
683
672
( Ordering :: Equal , & Some ( _) ) => {
684
673
// $actual_len >= test_len = pat_len,
685
674
// so we can match.
686
- self . candidate_after_slice_test (
687
- match_pair_index,
688
- candidate,
689
- prefix,
690
- slice,
691
- suffix,
692
- ) ;
675
+ fully_matched = true ;
693
676
Some ( 0 )
694
677
}
695
678
( Ordering :: Less , _) | ( Ordering :: Equal , & None ) => {
@@ -713,13 +696,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
713
696
714
697
( TestKind :: Range ( test) , PatKind :: Range ( pat) ) => {
715
698
if test == pat {
716
- self . candidate_without_match_pair ( match_pair_index, candidate) ;
717
- return Some ( 0 ) ;
699
+ fully_matched = true ;
700
+ Some ( 0 )
701
+ } else {
702
+ // If the testing range does not overlap with pattern range,
703
+ // the pattern can be matched only if this test fails.
704
+ if !test. overlaps ( pat, self . tcx , self . param_env ) ? { Some ( 1 ) } else { None }
718
705
}
719
-
720
- // If the testing range does not overlap with pattern range,
721
- // the pattern can be matched only if this test fails.
722
- if !test. overlaps ( pat, self . tcx , self . param_env ) ? { Some ( 1 ) } else { None }
723
706
}
724
707
725
708
( TestKind :: Range ( range) , & PatKind :: Constant { value } ) => {
@@ -751,64 +734,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
751
734
// FIXME(#29623) we can be more clever here
752
735
let pattern_test = self . test ( match_pair) ;
753
736
if pattern_test. kind == test. kind {
754
- self . candidate_without_match_pair ( match_pair_index , candidate ) ;
737
+ fully_matched = true ;
755
738
Some ( 0 )
756
739
} else {
757
740
None
758
741
}
759
742
}
760
- }
761
- }
762
-
763
- fn candidate_without_match_pair (
764
- & mut self ,
765
- match_pair_index : usize ,
766
- candidate : & mut Candidate < ' _ , ' tcx > ,
767
- ) {
768
- candidate. match_pairs . remove ( match_pair_index) ;
769
- }
743
+ } ;
770
744
771
- fn candidate_after_slice_test < ' pat > (
772
- & mut self ,
773
- match_pair_index : usize ,
774
- candidate : & mut Candidate < ' pat , ' tcx > ,
775
- prefix : & ' pat [ Box < Pat < ' tcx > > ] ,
776
- opt_slice : & ' pat Option < Box < Pat < ' tcx > > > ,
777
- suffix : & ' pat [ Box < Pat < ' tcx > > ] ,
778
- ) {
779
- let removed_place = candidate. match_pairs . remove ( match_pair_index) . place ;
780
- self . prefix_slice_suffix (
781
- & mut candidate. match_pairs ,
782
- & removed_place,
783
- prefix,
784
- opt_slice,
785
- suffix,
786
- ) ;
787
- }
745
+ if fully_matched {
746
+ // Replace the match pair by its sub-pairs.
747
+ let match_pair = candidate. match_pairs . remove ( match_pair_index) ;
748
+ candidate. match_pairs . extend ( match_pair. subpairs ) ;
749
+ // Move or-patterns to the end.
750
+ candidate
751
+ . match_pairs
752
+ . sort_by_key ( |pair| matches ! ( pair. pattern. kind, PatKind :: Or { .. } ) ) ;
753
+ }
788
754
789
- fn candidate_after_variant_switch < ' pat > (
790
- & mut self ,
791
- match_pair_index : usize ,
792
- adt_def : ty:: AdtDef < ' tcx > ,
793
- variant_index : VariantIdx ,
794
- subpatterns : & ' pat [ FieldPat < ' tcx > ] ,
795
- candidate : & mut Candidate < ' pat , ' tcx > ,
796
- ) {
797
- let match_pair = candidate. match_pairs . remove ( match_pair_index) ;
798
-
799
- // So, if we have a match-pattern like `x @ Enum::Variant(P1, P2)`,
800
- // we want to create a set of derived match-patterns like
801
- // `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`.
802
- let downcast_place = match_pair. place . downcast ( adt_def, variant_index) ; // `(x as Variant)`
803
- let consequent_match_pairs = subpatterns. iter ( ) . map ( |subpattern| {
804
- // e.g., `(x as Variant).0`
805
- let place = downcast_place
806
- . clone_project ( PlaceElem :: Field ( subpattern. field , subpattern. pattern . ty ) ) ;
807
- // e.g., `(x as Variant).0 @ P1`
808
- MatchPair :: new ( place, & subpattern. pattern , self )
809
- } ) ;
810
-
811
- candidate. match_pairs . extend ( consequent_match_pairs) ;
755
+ ret
812
756
}
813
757
814
758
fn error_simplifiable < ' pat > ( & mut self , match_pair : & MatchPair < ' pat , ' tcx > ) -> ! {
0 commit comments