@@ -606,6 +606,67 @@ impl<'tcx> Constructor<'tcx> {
606
606
}
607
607
}
608
608
609
+ /// Determines the constructor that the given pattern can be specialized to.
610
+ pub ( super ) fn from_pat < ' p > ( cx : & MatchCheckCtxt < ' p , ' tcx > , pat : & ' p Pat < ' tcx > ) -> Self {
611
+ match pat. kind . as_ref ( ) {
612
+ PatKind :: AscribeUserType { .. } => bug ! ( ) , // Handled by `expand_pattern`
613
+ PatKind :: Binding { .. } | PatKind :: Wild => Wildcard ,
614
+ PatKind :: Leaf { .. } | PatKind :: Deref { .. } => Single ,
615
+ & PatKind :: Variant { adt_def, variant_index, .. } => {
616
+ Variant ( adt_def. variants [ variant_index] . def_id )
617
+ }
618
+ PatKind :: Constant { value } => {
619
+ if let Some ( int_range) = IntRange :: from_const ( cx. tcx , cx. param_env , value, pat. span )
620
+ {
621
+ IntRange ( int_range)
622
+ } else {
623
+ match pat. ty . kind ( ) {
624
+ ty:: Float ( _) => FloatRange ( value, value, RangeEnd :: Included ) ,
625
+ // In `expand_pattern`, we convert string literals to `&CONST` patterns with
626
+ // `CONST` a pattern of type `str`. In truth this contains a constant of type
627
+ // `&str`.
628
+ ty:: Str => Str ( value) ,
629
+ // All constants that can be structurally matched have already been expanded
630
+ // into the corresponding `Pat`s by `const_to_pat`. Constants that remain are
631
+ // opaque.
632
+ _ => Opaque ,
633
+ }
634
+ }
635
+ }
636
+ & PatKind :: Range ( PatRange { lo, hi, end } ) => {
637
+ let ty = lo. ty ;
638
+ if let Some ( int_range) = IntRange :: from_range (
639
+ cx. tcx ,
640
+ lo. eval_bits ( cx. tcx , cx. param_env , lo. ty ) ,
641
+ hi. eval_bits ( cx. tcx , cx. param_env , hi. ty ) ,
642
+ ty,
643
+ & end,
644
+ pat. span ,
645
+ ) {
646
+ IntRange ( int_range)
647
+ } else {
648
+ FloatRange ( lo, hi, end)
649
+ }
650
+ }
651
+ PatKind :: Array { prefix, slice, suffix } | PatKind :: Slice { prefix, slice, suffix } => {
652
+ let array_len = match pat. ty . kind ( ) {
653
+ ty:: Array ( _, length) => Some ( length. eval_usize ( cx. tcx , cx. param_env ) ) ,
654
+ ty:: Slice ( _) => None ,
655
+ _ => span_bug ! ( pat. span, "bad ty {:?} for slice pattern" , pat. ty) ,
656
+ } ;
657
+ let prefix = prefix. len ( ) as u64 ;
658
+ let suffix = suffix. len ( ) as u64 ;
659
+ let kind = if slice. is_some ( ) {
660
+ VarLen ( prefix, suffix)
661
+ } else {
662
+ FixedLen ( prefix + suffix)
663
+ } ;
664
+ Slice ( Slice :: new ( array_len, kind) )
665
+ }
666
+ PatKind :: Or { .. } => bug ! ( "Or-pattern should have been expanded earlier on." ) ,
667
+ }
668
+ }
669
+
609
670
/// Some constructors (namely `Wildcard`, `IntRange` and `Slice`) actually stand for a set of actual
610
671
/// constructors (like variants, integers or fixed-sized slices). When specializing for these
611
672
/// constructors, we want to be specialising for the actual underlying constructors.
@@ -756,67 +817,6 @@ impl<'tcx> Constructor<'tcx> {
756
817
}
757
818
}
758
819
759
- /// Determines the constructor that the given pattern can be specialized to.
760
- /// Returns `None` in case of a catch-all, which can't be specialized.
761
- pub ( super ) fn pat_constructor < ' p , ' tcx > (
762
- cx : & MatchCheckCtxt < ' p , ' tcx > ,
763
- pat : & ' p Pat < ' tcx > ,
764
- ) -> Constructor < ' tcx > {
765
- match pat. kind . as_ref ( ) {
766
- PatKind :: AscribeUserType { .. } => bug ! ( ) , // Handled by `expand_pattern`
767
- PatKind :: Binding { .. } | PatKind :: Wild => Wildcard ,
768
- PatKind :: Leaf { .. } | PatKind :: Deref { .. } => Single ,
769
- & PatKind :: Variant { adt_def, variant_index, .. } => {
770
- Variant ( adt_def. variants [ variant_index] . def_id )
771
- }
772
- PatKind :: Constant { value } => {
773
- if let Some ( int_range) = IntRange :: from_const ( cx. tcx , cx. param_env , value, pat. span ) {
774
- IntRange ( int_range)
775
- } else {
776
- match pat. ty . kind ( ) {
777
- ty:: Float ( _) => FloatRange ( value, value, RangeEnd :: Included ) ,
778
- // In `expand_pattern`, we convert string literals to `&CONST` patterns with
779
- // `CONST` a pattern of type `str`. In truth this contains a constant of type
780
- // `&str`.
781
- ty:: Str => Str ( value) ,
782
- // All constants that can be structurally matched have already been expanded
783
- // into the corresponding `Pat`s by `const_to_pat`. Constants that remain are
784
- // opaque.
785
- _ => Opaque ,
786
- }
787
- }
788
- }
789
- & PatKind :: Range ( PatRange { lo, hi, end } ) => {
790
- let ty = lo. ty ;
791
- if let Some ( int_range) = IntRange :: from_range (
792
- cx. tcx ,
793
- lo. eval_bits ( cx. tcx , cx. param_env , lo. ty ) ,
794
- hi. eval_bits ( cx. tcx , cx. param_env , hi. ty ) ,
795
- ty,
796
- & end,
797
- pat. span ,
798
- ) {
799
- IntRange ( int_range)
800
- } else {
801
- FloatRange ( lo, hi, end)
802
- }
803
- }
804
- PatKind :: Array { prefix, slice, suffix } | PatKind :: Slice { prefix, slice, suffix } => {
805
- let array_len = match pat. ty . kind ( ) {
806
- ty:: Array ( _, length) => Some ( length. eval_usize ( cx. tcx , cx. param_env ) ) ,
807
- ty:: Slice ( _) => None ,
808
- _ => span_bug ! ( pat. span, "bad ty {:?} for slice pattern" , pat. ty) ,
809
- } ;
810
- let prefix = prefix. len ( ) as u64 ;
811
- let suffix = suffix. len ( ) as u64 ;
812
- let kind =
813
- if slice. is_some ( ) { VarLen ( prefix, suffix) } else { FixedLen ( prefix + suffix) } ;
814
- Slice ( Slice :: new ( array_len, kind) )
815
- }
816
- PatKind :: Or { .. } => bug ! ( "Or-pattern should have been expanded earlier on." ) ,
817
- }
818
- }
819
-
820
820
/// This determines the set of all possible constructors of a pattern matching
821
821
/// values of type `left_ty`. For vectors, this would normally be an infinite set
822
822
/// but is instead bounded by the maximum fixed length of slice patterns in
0 commit comments