@@ -589,22 +589,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
589589 // away.)
590590 let ( match_pair_index, match_pair) =
591591 candidate. match_pairs . iter ( ) . enumerate ( ) . find ( |& ( _, mp) | mp. place == * test_place) ?;
592+ let mut fully_matched = false ;
592593
593- match ( & test. kind , & match_pair. pattern . kind ) {
594+ let ret = match ( & test. kind , & match_pair. pattern . kind ) {
594595 // If we are performing a variant switch, then this
595596 // informs variant patterns, but nothing else.
596597 (
597598 & TestKind :: Switch { adt_def : tested_adt_def, .. } ,
598- & PatKind :: Variant { adt_def, variant_index, ref subpatterns , .. } ,
599+ & PatKind :: Variant { adt_def, variant_index, .. } ,
599600 ) => {
600601 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 ;
608603 Some ( variant_index. as_usize ( ) )
609604 }
610605
@@ -618,8 +613,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
618613 ( TestKind :: SwitchInt { switch_ty : _, options } , PatKind :: Constant { value } )
619614 if is_switch_ty ( match_pair. pattern . ty ) =>
620615 {
616+ fully_matched = true ;
621617 let index = options. get_index_of ( value) . unwrap ( ) ;
622- self . candidate_without_match_pair ( match_pair_index, candidate) ;
623618 Some ( index)
624619 }
625620
@@ -645,13 +640,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
645640 ( Ordering :: Equal , & None ) => {
646641 // on true, min_len = len = $actual_length,
647642 // 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 ;
655644 Some ( 0 )
656645 }
657646 ( Ordering :: Less , _) => {
@@ -683,13 +672,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
683672 ( Ordering :: Equal , & Some ( _) ) => {
684673 // $actual_len >= test_len = pat_len,
685674 // 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 ;
693676 Some ( 0 )
694677 }
695678 ( Ordering :: Less , _) | ( Ordering :: Equal , & None ) => {
@@ -713,13 +696,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
713696
714697 ( TestKind :: Range ( test) , PatKind :: Range ( pat) ) => {
715698 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 }
718705 }
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 }
723706 }
724707
725708 ( TestKind :: Range ( range) , & PatKind :: Constant { value } ) => {
@@ -751,64 +734,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
751734 // FIXME(#29623) we can be more clever here
752735 let pattern_test = self . test ( match_pair) ;
753736 if pattern_test. kind == test. kind {
754- self . candidate_without_match_pair ( match_pair_index , candidate ) ;
737+ fully_matched = true ;
755738 Some ( 0 )
756739 } else {
757740 None
758741 }
759742 }
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+ } ;
770744
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+ }
788754
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
812756 }
813757
814758 fn error_simplifiable < ' pat > ( & mut self , match_pair : & MatchPair < ' pat , ' tcx > ) -> ! {
0 commit comments