@@ -606,6 +606,67 @@ impl<'tcx> Constructor<'tcx> {
606606 }
607607 }
608608
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+
609670 /// Some constructors (namely `Wildcard`, `IntRange` and `Slice`) actually stand for a set of actual
610671 /// constructors (like variants, integers or fixed-sized slices). When specializing for these
611672 /// constructors, we want to be specialising for the actual underlying constructors.
@@ -756,67 +817,6 @@ impl<'tcx> Constructor<'tcx> {
756817 }
757818}
758819
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-
820820/// This determines the set of all possible constructors of a pattern matching
821821/// values of type `left_ty`. For vectors, this would normally be an infinite set
822822/// but is instead bounded by the maximum fixed length of slice patterns in
0 commit comments