@@ -289,42 +289,6 @@ fn opt_eq(tcx: &ty::ctxt, a: &Opt, b: &Opt) -> bool {
289289 }
290290}
291291
292- fn opt_overlap ( tcx : & ty:: ctxt , a : & Opt , b : & Opt ) -> bool {
293- match ( a, b) {
294- ( & lit( a) , & lit( b) ) => {
295- let a_expr = lit_to_expr ( tcx, & a) ;
296- let b_expr = lit_to_expr ( tcx, & b) ;
297- match const_eval:: compare_lit_exprs ( tcx, a_expr, b_expr) {
298- Some ( val1) => val1 == 0 ,
299- None => fail ! ( "opt_overlap: type mismatch" ) ,
300- }
301- }
302-
303- ( & range( a1, a2) , & range( b1, b2) ) => {
304- let m1 = const_eval:: compare_lit_exprs ( tcx, a1, b2) ;
305- let m2 = const_eval:: compare_lit_exprs ( tcx, b1, a2) ;
306- match ( m1, m2) {
307- // two ranges [a1, a2] and [b1, b2] overlap iff:
308- // a1 <= b2 && b1 <= a2
309- ( Some ( val1) , Some ( val2) ) => ( val1 <= 0 && val2 <= 0 ) ,
310- _ => fail ! ( "opt_overlap: type mismatch" ) ,
311- }
312- }
313-
314- ( & range( a1, a2) , & lit( b) ) | ( & lit( b) , & range( a1, a2) ) => {
315- let b_expr = lit_to_expr ( tcx, & b) ;
316- let m1 = const_eval:: compare_lit_exprs ( tcx, a1, b_expr) ;
317- let m2 = const_eval:: compare_lit_exprs ( tcx, a2, b_expr) ;
318- match ( m1, m2) {
319- // b is in range [a1, a2] iff a1 <= b and b <= a2
320- ( Some ( val1) , Some ( val2) ) => ( val1 <= 0 && 0 <= val2) ,
321- _ => fail ! ( "opt_overlap: type mismatch" ) ,
322- }
323- }
324- _ => fail ! ( "opt_overlap: expect lit or range" )
325- }
326- }
327-
328292pub enum opt_result < ' a > {
329293 single_result( Result < ' a > ) ,
330294 lower_bound( Result < ' a > ) ,
@@ -634,30 +598,16 @@ fn enter_opt<'a, 'b>(
634598 let tcx = bcx. tcx ( ) ;
635599 let dummy = @ast:: Pat { id : 0 , node : ast:: PatWild , span : DUMMY_SP } ;
636600 let mut i = 0 ;
637- // By the virtue of fact that we are in `trans` already, `enter_opt` is able
638- // to prune sub-match tree aggressively based on exact equality. But when it
639- // comes to literal or range, that strategy may lead to wrong result if there
640- // are guard function or multiple patterns inside tuple; in that case, pruning
641- // based on the overlap of patterns is required.
642- //
643- // Ideally, when constructing the sub-match tree for certain arm, only those
644- // arms beneath it matter. But that isn't how algorithm works right now and
645- // all other arms are taken into consideration when computing `guarded` below.
646- // That is ok since each round of `compile_submatch` guarantees to trim one
647- // "column" of arm patterns and the algorithm will converge.
648- let guarded = m. iter ( ) . any ( |x| x. data . arm . guard . is_some ( ) ) ;
649- let multi_pats = m. len ( ) > 0 && m[ 0 ] . pats . len ( ) > 1 ;
650601 enter_match ( bcx, & tcx. def_map , m, col, val, |p| {
651602 let answer = match p. node {
652603 ast:: PatEnum ( ..) |
653604 ast:: PatIdent ( _, _, None ) if pat_is_const ( & tcx. def_map , p) => {
654605 let const_def = tcx. def_map . borrow ( ) . get_copy ( & p. id ) ;
655606 let const_def_id = ast_util:: def_id_of_def ( const_def) ;
656- let konst = lit ( ConstLit ( const_def_id) ) ;
657- match guarded || multi_pats {
658- false if opt_eq ( tcx, & konst, opt) => Some ( Vec :: new ( ) ) ,
659- true if opt_overlap ( tcx, & konst, opt) => Some ( Vec :: new ( ) ) ,
660- _ => None ,
607+ if opt_eq ( tcx, & lit ( ConstLit ( const_def_id) ) , opt) {
608+ Some ( Vec :: new ( ) )
609+ } else {
610+ None
661611 }
662612 }
663613 ast:: PatEnum ( _, ref subpats) => {
@@ -682,20 +632,12 @@ fn enter_opt<'a, 'b>(
682632 }
683633 }
684634 ast:: PatLit ( l) => {
685- let lit_expr = lit ( ExprLit ( l) ) ;
686- match guarded || multi_pats {
687- false if opt_eq ( tcx, & lit_expr, opt) => Some ( Vec :: new ( ) ) ,
688- true if opt_overlap ( tcx, & lit_expr, opt) => Some ( Vec :: new ( ) ) ,
689- _ => None ,
690- }
635+ if opt_eq ( tcx, & lit ( ExprLit ( l) ) , opt) { Some ( Vec :: new ( ) ) }
636+ else { None }
691637 }
692638 ast:: PatRange ( l1, l2) => {
693- let rng = range ( l1, l2) ;
694- match guarded || multi_pats {
695- false if opt_eq ( tcx, & rng, opt) => Some ( Vec :: new ( ) ) ,
696- true if opt_overlap ( tcx, & rng, opt) => Some ( Vec :: new ( ) ) ,
697- _ => None ,
698- }
639+ if opt_eq ( tcx, & range ( l1, l2) , opt) { Some ( Vec :: new ( ) ) }
640+ else { None }
699641 }
700642 ast:: PatStruct ( _, ref field_pats, _) => {
701643 if opt_eq ( tcx, & variant_opt ( bcx, p. id ) , opt) {
0 commit comments