@@ -706,9 +706,12 @@ fn is_useful<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>,
706
706
debug ! ( "is_useful - pat_constructors = {:?} left_ty = {:?}" , constructors,
707
707
left_ty) ;
708
708
if constructors. is_empty ( ) {
709
+ // v[0] is a wildcard pattern - `pat_constructors` should really be returning
710
+ // an Option.
709
711
let constructors = missing_constructors ( cx, matrix, left_ty, max_slice_length) ;
710
712
debug ! ( "is_useful - missing_constructors = {:?}" , constructors) ;
711
713
if constructors. is_empty ( ) {
714
+ // all constructors are covered - must check them all.
712
715
all_constructors ( cx, left_ty, max_slice_length) . into_iter ( ) . map ( |c| {
713
716
match is_useful_specialized ( cx, matrix, v, c. clone ( ) , left_ty, witness) {
714
717
UsefulWithWitness ( pats) => UsefulWithWitness ( {
@@ -727,6 +730,7 @@ fn is_useful<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>,
727
730
}
728
731
} ) . find ( |result| result != & NotUseful ) . unwrap_or ( NotUseful )
729
732
} else {
733
+ // some constructor is only covered by wildcards - pick it.
730
734
let matrix = rows. iter ( ) . filter_map ( |r| {
731
735
match raw_pat ( r[ 0 ] . 0 ) . node {
732
736
PatKind :: Binding ( ..) | PatKind :: Wild => Some ( r[ 1 ..] . to_vec ( ) ) ,
@@ -747,12 +751,41 @@ fn is_useful<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>,
747
751
}
748
752
}
749
753
} else {
754
+ // `v` is not a wildcard
750
755
constructors. into_iter ( ) . map ( |c|
751
756
is_useful_specialized ( cx, matrix, v, c. clone ( ) , left_ty, witness)
752
757
) . find ( |result| result != & NotUseful ) . unwrap_or ( NotUseful )
753
758
}
754
759
}
755
760
761
+ fn check_for_ref_splitting < ' s , ' a , ' tcx , I > ( cx : & MatchCheckCtxt < ' a , ' tcx > , data : I )
762
+ where I : Iterator < Item =( & ' s Pat , Option < Ty < ' tcx > > ) >
763
+ {
764
+ let mut ref_pattern = None ;
765
+ let mut lit_pattern = None ;
766
+
767
+ for ( pat, _ty) in data {
768
+ match pat. node {
769
+ PatKind :: Lit ( ..) => {
770
+ lit_pattern = Some ( pat) ;
771
+ }
772
+ PatKind :: Ref ( ..) => {
773
+ ref_pattern = Some ( pat) ;
774
+ }
775
+ _ => { }
776
+ } ;
777
+ if let ( Some ( lit_pattern) , Some ( ref_pattern) ) = ( lit_pattern, ref_pattern) {
778
+ cx. tcx . sess . struct_span_err (
779
+ ref_pattern. span ,
780
+ & format ! ( "as a temporary restriction, literal patterns can't be split \
781
+ - see issue #35044")
782
+ ) . span_note ( lit_pattern. span , & format ! ( "split literal here" ) )
783
+ . emit ( ) ;
784
+ cx. tcx . sess . abort_if_errors ( ) ;
785
+ }
786
+ }
787
+ }
788
+
756
789
fn is_useful_specialized < ' a , ' tcx > (
757
790
cx : & MatchCheckCtxt < ' a , ' tcx > ,
758
791
& Matrix ( ref m) : & Matrix < ' a , ' tcx > ,
@@ -762,6 +795,10 @@ fn is_useful_specialized<'a, 'tcx>(
762
795
witness : WitnessPreference ) -> Usefulness
763
796
{
764
797
let arity = constructor_arity ( cx, & ctor, lty) ;
798
+ check_for_ref_splitting (
799
+ cx,
800
+ m. iter ( ) . map ( |r| r[ 0 ] ) . chain ( Some ( v[ 0 ] ) )
801
+ ) ;
765
802
let matrix = Matrix ( m. iter ( ) . filter_map ( |r| {
766
803
specialize ( cx, & r[ ..] , & ctor, 0 , arity)
767
804
} ) . collect ( ) ) ;
@@ -781,7 +818,8 @@ fn is_useful_specialized<'a, 'tcx>(
781
818
/// On the other hand, a wild pattern and an identifier pattern cannot be
782
819
/// specialized in any way.
783
820
fn pat_constructors ( cx : & MatchCheckCtxt , p : & Pat ,
784
- left_ty : Ty , max_slice_length : usize ) -> Vec < Constructor > {
821
+ left_ty : Ty , max_slice_length : usize )
822
+ -> Vec < Constructor > {
785
823
let pat = raw_pat ( p) ;
786
824
match pat. node {
787
825
PatKind :: Struct ( ..) | PatKind :: TupleStruct ( ..) | PatKind :: Path ( ..) =>
0 commit comments