@@ -409,24 +409,12 @@ fn missing_ctor(cx: &MatchCheckCtxt,
409
409
_ => check_matrix_for_wild ( cx, m) ,
410
410
} ,
411
411
ty:: ty_enum( eid, _) => {
412
- let mut found = Vec :: new ( ) ;
413
- for r in m. iter ( ) {
414
- let r = pat_ctor_id ( cx, * r. get ( 0 ) ) ;
415
- for id in r. move_iter ( ) {
416
- if !found. contains ( & id) {
417
- found. push ( id) ;
418
- }
419
- }
420
- }
412
+ let pat_ctors: Vec < ctor > = m
413
+ . iter ( )
414
+ . filter_map ( |r| pat_ctor_id ( cx, * r. get ( 0 ) ) )
415
+ . collect ( ) ;
421
416
let variants = ty:: enum_variants ( cx. tcx , eid) ;
422
- if found. len ( ) != ( * variants) . len ( ) {
423
- for v in ( * variants) . iter ( ) {
424
- if !found. iter ( ) . any ( |x| x == & ( variant ( v. id ) ) ) {
425
- return Some ( variant ( v. id ) ) ;
426
- }
427
- }
428
- fail ! ( ) ;
429
- } else { None }
417
+ variants. iter ( ) . map ( |v| variant ( v. id ) ) . find ( |c| !pat_ctors. contains ( c) )
430
418
}
431
419
ty:: ty_nil => None ,
432
420
ty:: ty_bool => {
@@ -567,6 +555,21 @@ fn wild_multi() -> @Pat {
567
555
@Pat { id : 0 , node : PatWildMulti , span : DUMMY_SP }
568
556
}
569
557
558
+ fn range_covered_by_constructor ( ctor_id : & ctor , from : & const_val , to : & const_val ) -> Option < bool > {
559
+ let ( c_from, c_to) = match * ctor_id {
560
+ val( ref value) => ( value, value) ,
561
+ range( ref from, ref to) => ( from, to) ,
562
+ single => return Some ( true ) ,
563
+ _ => unreachable ! ( )
564
+ } ;
565
+ let cmp_from = compare_const_vals ( c_from, from) ;
566
+ let cmp_to = compare_const_vals ( c_to, to) ;
567
+ match ( cmp_from, cmp_to) {
568
+ ( Some ( val1) , Some ( val2) ) => Some ( val1 >= 0 && val2 <= 0 ) ,
569
+ _ => None
570
+ }
571
+ }
572
+
570
573
fn specialize ( cx : & MatchCheckCtxt ,
571
574
r : & [ @Pat ] ,
572
575
ctor_id : & ctor ,
@@ -592,41 +595,15 @@ fn specialize(cx: &MatchCheckCtxt,
592
595
}
593
596
}
594
597
Some ( DefStatic ( did, _) ) => {
595
- let const_expr =
596
- lookup_const_by_id ( cx. tcx , did) . unwrap ( ) ;
598
+ let const_expr = lookup_const_by_id ( cx. tcx , did) . unwrap ( ) ;
597
599
let e_v = eval_const_expr ( cx. tcx , const_expr) ;
598
- let match_ = match * ctor_id {
599
- val( ref v) => {
600
- match compare_const_vals ( & e_v, v) {
601
- Some ( val1) => ( val1 == 0 ) ,
602
- None => {
603
- cx. tcx . sess . span_err ( * pat_span,
604
- "mismatched types between arms" ) ;
605
- false
606
- }
607
- }
608
- } ,
609
- range( ref c_lo, ref c_hi) => {
610
- let m1 = compare_const_vals ( c_lo, & e_v) ;
611
- let m2 = compare_const_vals ( c_hi, & e_v) ;
612
- match ( m1, m2) {
613
- ( Some ( val1) , Some ( val2) ) => {
614
- ( val1 >= 0 && val2 <= 0 )
615
- }
616
- _ => {
617
- cx. tcx . sess . span_err ( * pat_span,
618
- "mismatched types between ranges" ) ;
619
- false
620
- }
621
- }
622
- }
623
- single => true ,
624
- _ => fail ! ( "type error" )
625
- } ;
626
- if match_ {
627
- Some ( vec ! ( ) )
628
- } else {
629
- None
600
+ match range_covered_by_constructor ( ctor_id, & e_v, & e_v) {
601
+ Some ( true ) => Some ( vec ! ( ) ) ,
602
+ Some ( false ) => None ,
603
+ None => {
604
+ cx. tcx . sess . span_err ( * pat_span, "mismatched types between arms" ) ;
605
+ None
606
+ }
630
607
}
631
608
}
632
609
_ => {
@@ -638,38 +615,15 @@ fn specialize(cx: &MatchCheckCtxt,
638
615
let def = cx. tcx . def_map . borrow ( ) . get_copy ( pat_id) ;
639
616
match def {
640
617
DefStatic ( did, _) => {
641
- let const_expr =
642
- lookup_const_by_id ( cx. tcx , did) . unwrap ( ) ;
618
+ let const_expr = lookup_const_by_id ( cx. tcx , did) . unwrap ( ) ;
643
619
let e_v = eval_const_expr ( cx. tcx , const_expr) ;
644
- let match_ = match * ctor_id {
645
- val( ref v) =>
646
- match compare_const_vals ( & e_v, v) {
647
- Some ( val1) => ( val1 == 0 ) ,
648
- None => {
649
- cx. tcx . sess . span_err ( * pat_span,
650
- "mismatched types between arms" ) ;
651
- false
652
- }
653
- } ,
654
- range( ref c_lo, ref c_hi) => {
655
- let m1 = compare_const_vals ( c_lo, & e_v) ;
656
- let m2 = compare_const_vals ( c_hi, & e_v) ;
657
- match ( m1, m2) {
658
- ( Some ( val1) , Some ( val2) ) => ( val1 >= 0 && val2 <= 0 ) ,
659
- _ => {
660
- cx. tcx . sess . span_err ( * pat_span,
661
- "mismatched types between ranges" ) ;
662
- false
663
- }
664
- }
665
- }
666
- single => true ,
667
- _ => fail ! ( "type error" )
668
- } ;
669
- if match_ {
670
- Some ( vec ! ( ) )
671
- } else {
672
- None
620
+ match range_covered_by_constructor ( ctor_id, & e_v, & e_v) {
621
+ Some ( true ) => Some ( vec ! ( ) ) ,
622
+ Some ( false ) => None ,
623
+ None => {
624
+ cx. tcx . sess . span_err ( * pat_span, "mismatched types between arms" ) ;
625
+ None
626
+ }
673
627
}
674
628
}
675
629
DefVariant ( _, id, _) if variant ( id) != * ctor_id => None ,
@@ -720,68 +674,33 @@ fn specialize(cx: &MatchCheckCtxt,
720
674
721
675
}
722
676
& PatTup ( ref args) => {
723
- Some ( args. iter ( ) . map ( |x| * x ) . collect ( ) )
677
+ Some ( args. clone ( ) )
724
678
}
725
679
& PatBox ( ref inner) | & PatRegion ( ref inner) => {
726
680
Some ( vec ! ( inner. clone( ) ) )
727
681
}
728
682
& PatLit ( ref expr) => {
729
- let e_v = eval_const_expr ( cx. tcx , * expr) ;
730
- let match_ = match * ctor_id {
731
- val( ref v) => {
732
- match compare_const_vals ( & e_v, v) {
733
- Some ( val1) => val1 == 0 ,
734
- None => {
735
- cx. tcx . sess . span_err ( * pat_span,
736
- "mismatched types between arms" ) ;
737
- false
738
- }
739
- }
740
- } ,
741
- range( ref c_lo, ref c_hi) => {
742
- let m1 = compare_const_vals ( c_lo, & e_v) ;
743
- let m2 = compare_const_vals ( c_hi, & e_v) ;
744
- match ( m1, m2) {
745
- ( Some ( val1) , Some ( val2) ) => ( val1 >= 0 && val2 <= 0 ) ,
746
- _ => {
747
- cx. tcx . sess . span_err ( * pat_span,
748
- "mismatched types between ranges" ) ;
749
- false
750
- }
751
- }
752
- }
753
- single => true ,
754
- _ => fail ! ( "type error" )
755
- } ;
756
- if match_ {
757
- Some ( vec ! ( ) )
758
- } else {
683
+ let expr_value = eval_const_expr ( cx. tcx , * expr) ;
684
+ match range_covered_by_constructor ( ctor_id, & expr_value, & expr_value) {
685
+ Some ( true ) => Some ( vec ! ( ) ) ,
686
+ Some ( false ) => None ,
687
+ None => {
688
+ cx. tcx . sess . span_err ( * pat_span, "mismatched types between arms" ) ;
759
689
None
760
- }
690
+ }
691
+ }
761
692
}
762
- & PatRange ( lo, hi) => {
763
- let ( c_lo, c_hi) = match * ctor_id {
764
- val( ref v) => ( v, v) ,
765
- range( ref lo, ref hi) => ( lo, hi) ,
766
- single => return Some ( vec ! ( ) ) ,
767
- _ => fail ! ( "type error" )
768
- } ;
769
- let v_lo = eval_const_expr ( cx. tcx , lo) ;
770
- let v_hi = eval_const_expr ( cx. tcx , hi) ;
771
-
772
- let m1 = compare_const_vals ( c_lo, & v_lo) ;
773
- let m2 = compare_const_vals ( c_hi, & v_hi) ;
774
- match ( m1, m2) {
775
- ( Some ( val1) , Some ( val2) ) if val1 >= 0 && val2 <= 0 => {
776
- Some ( vec ! ( ) )
777
- } ,
778
- ( Some ( _) , Some ( _) ) => None ,
779
- _ => {
780
- cx. tcx . sess . span_err ( * pat_span,
781
- "mismatched types between ranges" ) ;
782
- None
783
- }
784
- }
693
+ & PatRange ( ref from, ref to) => {
694
+ let from_value = eval_const_expr ( cx. tcx , * from) ;
695
+ let to_value = eval_const_expr ( cx. tcx , * to) ;
696
+ match range_covered_by_constructor ( ctor_id, & from_value, & to_value) {
697
+ Some ( true ) => Some ( vec ! ( ) ) ,
698
+ Some ( false ) => None ,
699
+ None => {
700
+ cx. tcx . sess . span_err ( * pat_span, "mismatched types between arms" ) ;
701
+ None
702
+ }
703
+ }
785
704
}
786
705
& PatVec ( ref before, ref slice, ref after) => {
787
706
match * ctor_id {
0 commit comments