@@ -289,42 +289,6 @@ fn opt_eq(tcx: &ty::ctxt, a: &Opt, b: &Opt) -> bool {
289
289
}
290
290
}
291
291
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
-
328
292
pub enum opt_result < ' a > {
329
293
single_result( Result < ' a > ) ,
330
294
lower_bound( Result < ' a > ) ,
@@ -634,30 +598,16 @@ fn enter_opt<'a, 'b>(
634
598
let tcx = bcx. tcx ( ) ;
635
599
let dummy = @ast:: Pat { id : 0 , node : ast:: PatWild , span : DUMMY_SP } ;
636
600
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 ;
650
601
enter_match ( bcx, & tcx. def_map , m, col, val, |p| {
651
602
let answer = match p. node {
652
603
ast:: PatEnum ( ..) |
653
604
ast:: PatIdent ( _, _, None ) if pat_is_const ( & tcx. def_map , p) => {
654
605
let const_def = tcx. def_map . borrow ( ) . get_copy ( & p. id ) ;
655
606
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
661
611
}
662
612
}
663
613
ast:: PatEnum ( _, ref subpats) => {
@@ -682,20 +632,12 @@ fn enter_opt<'a, 'b>(
682
632
}
683
633
}
684
634
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 }
691
637
}
692
638
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 }
699
641
}
700
642
ast:: PatStruct ( _, ref field_pats, _) => {
701
643
if opt_eq ( tcx, & variant_opt ( bcx, p. id ) , opt) {
0 commit comments