@@ -20,6 +20,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2020use syntax:: ast:: Name ;
2121use syntax_pos:: Span ;
2222
23+ use std:: mem;
24+
2325// helper functions, broken out by category:
2426mod simplify;
2527mod test;
@@ -665,7 +667,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
665667 }
666668}
667669
668- #[ derive( Debug ) ]
670+ #[ derive( Clone , Debug ) ]
669671pub struct Candidate < ' pat , ' tcx > {
670672 // span of the original pattern that gave rise to this candidate
671673 span : Span ,
@@ -883,7 +885,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
883885 }
884886
885887 // Test for the remaining candidates.
886- self . test_candidates (
888+ self . test_candidates_with_or (
887889 span,
888890 unmatched_candidates,
889891 block,
@@ -1026,6 +1028,41 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
10261028 }
10271029 }
10281030
1031+ fn test_candidates_with_or < ' pat , ' b , ' c > (
1032+ & mut self ,
1033+ span : Span ,
1034+ candidates : & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] ,
1035+ block : BasicBlock ,
1036+ otherwise_block : Option < BasicBlock > ,
1037+ fake_borrows : & mut Option < FxHashSet < Place < ' tcx > > > ,
1038+ ) {
1039+ let match_pair = & candidates. first ( ) . unwrap ( ) . match_pairs [ 0 ] ;
1040+ // FIXME(dlrobertson): This could use some cleaning up.
1041+ if let PatKind :: Or { ref pats } = * match_pair. pattern . kind {
1042+ let match_pairs = mem:: take ( & mut candidates. first_mut ( ) . unwrap ( ) . match_pairs ) ;
1043+ let mut new_candidates = pats. iter ( ) . map ( |pat| {
1044+ let mut candidate = ( * candidates. first ( ) . unwrap ( ) ) . clone ( ) ;
1045+ candidate. match_pairs = match_pairs. clone ( ) ;
1046+ candidate. match_pairs [ 0 ] . pattern = pat;
1047+ candidate
1048+ } ) . collect :: < Vec < _ > > ( ) ;
1049+ let mut new_candidate_refs = new_candidates. iter_mut ( ) . collect :: < Vec < _ > > ( ) ;
1050+ for candidate in candidates. iter_mut ( ) . skip ( 1 ) {
1051+ new_candidate_refs. push ( candidate) ;
1052+ }
1053+ self . test_candidates ( span, & mut * new_candidate_refs, block,
1054+ otherwise_block, fake_borrows) ;
1055+ for candidate in new_candidates. iter_mut ( ) {
1056+ if !candidate. match_pairs . is_empty ( ) {
1057+ candidate. match_pairs . remove ( 0 ) ;
1058+ }
1059+ }
1060+ } else {
1061+ self . test_candidates ( span, candidates, block,
1062+ otherwise_block, fake_borrows)
1063+ }
1064+ }
1065+
10291066 /// This is the most subtle part of the matching algorithm. At
10301067 /// this point, the input candidates have been fully simplified,
10311068 /// and so we know that all remaining match-pairs require some
0 commit comments