@@ -779,8 +779,67 @@ impl<'tcx> Constructor<'tcx> {
779779 & self ,
780780 cx : & MatchCheckCtxt < ' a , ' tcx > ,
781781 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+ }
784843 }
785844
786845 /// This computes the arity of a constructor. The arity of a constructor
@@ -880,7 +939,7 @@ impl<'tcx> Constructor<'tcx> {
880939
881940 /// Like `apply`, but where all the subpatterns are wildcards `_`.
882941 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 ( ) ;
884943 self . apply ( cx, ty, subpatterns)
885944 }
886945}
@@ -1659,7 +1718,7 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
16591718) -> Usefulness < ' tcx > {
16601719 debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, lty) ;
16611720
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) ;
16631722 let ctor_wild_subpatterns: Vec < _ > = ctor_wild_subpatterns_owned. iter ( ) . collect ( ) ;
16641723 let matrix = matrix. specialize_constructor ( cx, & ctor, & ctor_wild_subpatterns) ;
16651724 v. specialize_constructor ( cx, & ctor, & ctor_wild_subpatterns)
@@ -1709,69 +1768,6 @@ fn pat_constructor<'tcx>(
17091768 }
17101769}
17111770
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-
17751771// checks whether a constant is equal to a user-written slice pattern. Only supports byte slices,
17761772// meaning all other types will compare unequal and thus equal patterns often do not cause the
17771773// second pattern to lint about unreachable match arms.
0 commit comments