@@ -779,8 +779,67 @@ impl<'tcx> Constructor<'tcx> {
779
779
& self ,
780
780
cx : & MatchCheckCtxt < ' a , ' tcx > ,
781
781
ty : Ty < ' tcx > ,
782
- ) -> impl Iterator < Item = Pat < ' tcx > > + DoubleEndedIterator {
783
- constructor_sub_pattern_tys ( cx, self , ty) . into_iter ( ) . map ( Pat :: wildcard_from_ty)
782
+ ) -> Vec < Pat < ' tcx > > {
783
+ debug ! ( "wildcard_subpatterns({:#?}, {:?})" , self , ty) ;
784
+ match ty. kind {
785
+ ty:: Tuple ( ref fs) => {
786
+ fs. into_iter ( ) . map ( |t| t. expect_ty ( ) ) . map ( Pat :: wildcard_from_ty) . collect ( )
787
+ }
788
+ ty:: Slice ( ty) | ty:: Array ( ty, _) => match * self {
789
+ FixedLenSlice ( length) => ( 0 ..length) . map ( |_| Pat :: wildcard_from_ty ( ty) ) . collect ( ) ,
790
+ VarLenSlice ( prefix, suffix) => {
791
+ ( 0 ..prefix + suffix) . map ( |_| Pat :: wildcard_from_ty ( ty) ) . collect ( )
792
+ }
793
+ ConstantValue ( ..) => vec ! [ ] ,
794
+ _ => bug ! ( "bad slice pattern {:?} {:?}" , self , ty) ,
795
+ } ,
796
+ ty:: Ref ( _, rty, _) => vec ! [ Pat :: wildcard_from_ty( rty) ] ,
797
+ ty:: Adt ( adt, substs) => {
798
+ if adt. is_box ( ) {
799
+ // Use T as the sub pattern type of Box<T>.
800
+ vec ! [ Pat :: wildcard_from_ty( substs. type_at( 0 ) ) ]
801
+ } else {
802
+ let variant = & adt. variants [ self . variant_index_for_adt ( cx, adt) ] ;
803
+ let is_non_exhaustive =
804
+ variant. is_field_list_non_exhaustive ( ) && !cx. is_local ( ty) ;
805
+ variant
806
+ . fields
807
+ . iter ( )
808
+ . map ( |field| {
809
+ let is_visible =
810
+ adt. is_enum ( ) || field. vis . is_accessible_from ( cx. module , cx. tcx ) ;
811
+ let is_uninhabited = cx. is_uninhabited ( field. ty ( cx. tcx , substs) ) ;
812
+ match ( is_visible, is_non_exhaustive, is_uninhabited) {
813
+ // Treat all uninhabited types in non-exhaustive variants as `TyErr`.
814
+ ( _, true , true ) => cx. tcx . types . err ,
815
+ // Treat all non-visible fields as `TyErr`. They can't appear in any
816
+ // other pattern from this match (because they are private), so their
817
+ // type does not matter - but we don't want to know they are
818
+ // uninhabited.
819
+ ( false , ..) => cx. tcx . types . err ,
820
+ ( true , ..) => {
821
+ let ty = field. ty ( cx. tcx , substs) ;
822
+ match ty. kind {
823
+ // If the field type returned is an array of an unknown size
824
+ // return an TyErr.
825
+ ty:: Array ( _, len)
826
+ if len
827
+ . try_eval_usize ( cx. tcx , cx. param_env )
828
+ . is_none ( ) =>
829
+ {
830
+ cx. tcx . types . err
831
+ }
832
+ _ => ty,
833
+ }
834
+ }
835
+ }
836
+ } )
837
+ . map ( Pat :: wildcard_from_ty)
838
+ . collect ( )
839
+ }
840
+ }
841
+ _ => vec ! [ ] ,
842
+ }
784
843
}
785
844
786
845
/// This computes the arity of a constructor. The arity of a constructor
@@ -880,7 +939,7 @@ impl<'tcx> Constructor<'tcx> {
880
939
881
940
/// Like `apply`, but where all the subpatterns are wildcards `_`.
882
941
fn apply_wildcards < ' a > ( & self , cx : & MatchCheckCtxt < ' a , ' tcx > , ty : Ty < ' tcx > ) -> Pat < ' tcx > {
883
- let subpatterns = self . wildcard_subpatterns ( cx, ty) . rev ( ) ;
942
+ let subpatterns = self . wildcard_subpatterns ( cx, ty) . into_iter ( ) . rev ( ) ;
884
943
self . apply ( cx, ty, subpatterns)
885
944
}
886
945
}
@@ -1659,7 +1718,7 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
1659
1718
) -> Usefulness < ' tcx > {
1660
1719
debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, lty) ;
1661
1720
1662
- let ctor_wild_subpatterns_owned: Vec < _ > = ctor. wildcard_subpatterns ( cx, lty) . collect ( ) ;
1721
+ let ctor_wild_subpatterns_owned: Vec < _ > = ctor. wildcard_subpatterns ( cx, lty) ;
1663
1722
let ctor_wild_subpatterns: Vec < _ > = ctor_wild_subpatterns_owned. iter ( ) . collect ( ) ;
1664
1723
let matrix = matrix. specialize_constructor ( cx, & ctor, & ctor_wild_subpatterns) ;
1665
1724
v. specialize_constructor ( cx, & ctor, & ctor_wild_subpatterns)
@@ -1709,69 +1768,6 @@ fn pat_constructor<'tcx>(
1709
1768
}
1710
1769
}
1711
1770
1712
- /// This computes the types of the sub patterns that a constructor should be
1713
- /// expanded to.
1714
- ///
1715
- /// For instance, a tuple pattern (43u32, 'a') has sub pattern types [u32, char].
1716
- fn constructor_sub_pattern_tys < ' a , ' tcx > (
1717
- cx : & MatchCheckCtxt < ' a , ' tcx > ,
1718
- ctor : & Constructor < ' tcx > ,
1719
- ty : Ty < ' tcx > ,
1720
- ) -> Vec < Ty < ' tcx > > {
1721
- debug ! ( "constructor_sub_pattern_tys({:#?}, {:?})" , ctor, ty) ;
1722
- match ty. kind {
1723
- ty:: Tuple ( ref fs) => fs. into_iter ( ) . map ( |t| t. expect_ty ( ) ) . collect ( ) ,
1724
- ty:: Slice ( ty) | ty:: Array ( ty, _) => match * ctor {
1725
- FixedLenSlice ( length) => ( 0 ..length) . map ( |_| ty) . collect ( ) ,
1726
- VarLenSlice ( prefix, suffix) => ( 0 ..prefix + suffix) . map ( |_| ty) . collect ( ) ,
1727
- ConstantValue ( ..) => vec ! [ ] ,
1728
- _ => bug ! ( "bad slice pattern {:?} {:?}" , ctor, ty) ,
1729
- } ,
1730
- ty:: Ref ( _, rty, _) => vec ! [ rty] ,
1731
- ty:: Adt ( adt, substs) => {
1732
- if adt. is_box ( ) {
1733
- // Use T as the sub pattern type of Box<T>.
1734
- vec ! [ substs. type_at( 0 ) ]
1735
- } else {
1736
- let variant = & adt. variants [ ctor. variant_index_for_adt ( cx, adt) ] ;
1737
- let is_non_exhaustive = variant. is_field_list_non_exhaustive ( ) && !cx. is_local ( ty) ;
1738
- variant
1739
- . fields
1740
- . iter ( )
1741
- . map ( |field| {
1742
- let is_visible =
1743
- adt. is_enum ( ) || field. vis . is_accessible_from ( cx. module , cx. tcx ) ;
1744
- let is_uninhabited = cx. is_uninhabited ( field. ty ( cx. tcx , substs) ) ;
1745
- match ( is_visible, is_non_exhaustive, is_uninhabited) {
1746
- // Treat all uninhabited types in non-exhaustive variants as `TyErr`.
1747
- ( _, true , true ) => cx. tcx . types . err ,
1748
- // Treat all non-visible fields as `TyErr`. They can't appear in any
1749
- // other pattern from this match (because they are private), so their
1750
- // type does not matter - but we don't want to know they are
1751
- // uninhabited.
1752
- ( false , ..) => cx. tcx . types . err ,
1753
- ( true , ..) => {
1754
- let ty = field. ty ( cx. tcx , substs) ;
1755
- match ty. kind {
1756
- // If the field type returned is an array of an unknown size
1757
- // return an TyErr.
1758
- ty:: Array ( _, len)
1759
- if len. try_eval_usize ( cx. tcx , cx. param_env ) . is_none ( ) =>
1760
- {
1761
- cx. tcx . types . err
1762
- }
1763
- _ => ty,
1764
- }
1765
- }
1766
- }
1767
- } )
1768
- . collect ( )
1769
- }
1770
- }
1771
- _ => vec ! [ ] ,
1772
- }
1773
- }
1774
-
1775
1771
// checks whether a constant is equal to a user-written slice pattern. Only supports byte slices,
1776
1772
// meaning all other types will compare unequal and thus equal patterns often do not cause the
1777
1773
// second pattern to lint about unreachable match arms.
0 commit comments