@@ -20,6 +20,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
20
20
use syntax:: ast:: Name ;
21
21
use syntax_pos:: Span ;
22
22
23
+ use std:: mem;
24
+
23
25
// helper functions, broken out by category:
24
26
mod simplify;
25
27
mod test;
@@ -665,7 +667,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
665
667
}
666
668
}
667
669
668
- #[ derive( Debug ) ]
670
+ #[ derive( Clone , Debug ) ]
669
671
pub struct Candidate < ' pat , ' tcx > {
670
672
// span of the original pattern that gave rise to this candidate
671
673
span : Span ,
@@ -883,7 +885,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
883
885
}
884
886
885
887
// Test for the remaining candidates.
886
- self . test_candidates (
888
+ self . test_candidates_with_or (
887
889
span,
888
890
unmatched_candidates,
889
891
block,
@@ -1026,6 +1028,41 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1026
1028
}
1027
1029
}
1028
1030
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
+
1029
1066
/// This is the most subtle part of the matching algorithm. At
1030
1067
/// this point, the input candidates have been fully simplified,
1031
1068
/// and so we know that all remaining match-pairs require some
0 commit comments