@@ -239,6 +239,7 @@ use rustc::ty::{self, Const, Ty, TyCtxt, TypeFoldable};
239239use rustc:: lint;
240240use rustc:: mir:: interpret:: { truncate, AllocId , ConstValue , Pointer , Scalar } ;
241241use rustc:: mir:: Field ;
242+ use rustc:: util:: captures:: Captures ;
242243use rustc:: util:: common:: ErrorReported ;
243244
244245use syntax:: attr:: { SignedInt , UnsignedInt } ;
@@ -427,6 +428,11 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
427428 self . 0 . push ( row)
428429 }
429430
431+ /// Iterate over the first component of each row
432+ fn heads < ' a > ( & ' a self ) -> impl Iterator < Item = & ' a Pat < ' tcx > > + Captures < ' p > {
433+ self . 0 . iter ( ) . map ( |r| r. head ( ) )
434+ }
435+
430436 /// This computes `D(self)`. See top of the file for explanations.
431437 fn specialize_wildcard ( & self ) -> Self {
432438 self . 0 . iter ( ) . filter_map ( |r| r. specialize_wildcard ( ) ) . collect ( )
@@ -635,6 +641,39 @@ impl<'tcx> Constructor<'tcx> {
635641 _ => bug ! ( "bad constructor being displayed: `{:?}" , self ) ,
636642 }
637643 }
644+
645+ fn wildcard_subpatterns < ' a > (
646+ & self ,
647+ cx : & MatchCheckCtxt < ' a , ' tcx > ,
648+ ty : Ty < ' tcx > ,
649+ ) -> Vec < Pat < ' tcx > > {
650+ constructor_sub_pattern_tys ( cx, self , ty)
651+ . into_iter ( )
652+ . map ( |ty| Pat { ty, span : DUMMY_SP , kind : box PatKind :: Wild } )
653+ . collect ( )
654+ }
655+
656+ /// This computes the arity of a constructor. The arity of a constructor
657+ /// is how many subpattern patterns of that constructor should be expanded to.
658+ ///
659+ /// For instance, a tuple pattern `(_, 42, Some([]))` has the arity of 3.
660+ /// A struct pattern's arity is the number of fields it contains, etc.
661+ fn arity < ' a > ( & self , cx : & MatchCheckCtxt < ' a , ' tcx > , ty : Ty < ' tcx > ) -> u64 {
662+ debug ! ( "Constructor::arity({:#?}, {:?})" , self , ty) ;
663+ match ty. kind {
664+ ty:: Tuple ( ref fs) => fs. len ( ) as u64 ,
665+ ty:: Slice ( ..) | ty:: Array ( ..) => match * self {
666+ Slice ( length) => length,
667+ ConstantValue ( ..) => 0 ,
668+ _ => bug ! ( "bad slice pattern {:?} {:?}" , self , ty) ,
669+ } ,
670+ ty:: Ref ( ..) => 1 ,
671+ ty:: Adt ( adt, _) => {
672+ adt. variants [ self . variant_index_for_adt ( cx, adt) ] . fields . len ( ) as u64
673+ }
674+ _ => 0 ,
675+ }
676+ }
638677}
639678
640679#[ derive( Clone , Debug ) ]
@@ -713,12 +752,7 @@ impl<'tcx> Witness<'tcx> {
713752 ctor : & Constructor < ' tcx > ,
714753 ty : Ty < ' tcx > ,
715754 ) -> Self {
716- let sub_pattern_tys = constructor_sub_pattern_tys ( cx, ctor, ty) ;
717- self . 0 . extend ( sub_pattern_tys. into_iter ( ) . map ( |ty| Pat {
718- ty,
719- span : DUMMY_SP ,
720- kind : box PatKind :: Wild ,
721- } ) ) ;
755+ self . 0 . extend ( ctor. wildcard_subpatterns ( cx, ty) ) ;
722756 self . apply_constructor ( cx, ctor, ty)
723757 }
724758
@@ -741,7 +775,7 @@ impl<'tcx> Witness<'tcx> {
741775 ctor : & Constructor < ' tcx > ,
742776 ty : Ty < ' tcx > ,
743777 ) -> Self {
744- let arity = constructor_arity ( cx, ctor , ty) ;
778+ let arity = ctor . arity ( cx, ty) ;
745779 let pat = {
746780 let len = self . 0 . len ( ) as u64 ;
747781 let mut pats = self . 0 . drain ( ( len - arity) as usize ..) . rev ( ) ;
@@ -1347,9 +1381,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
13471381
13481382 assert ! ( rows. iter( ) . all( |r| r. len( ) == v. len( ) ) ) ;
13491383
1350- let ( ty, span) = rows
1351- . iter ( )
1352- . map ( |r| ( r. head ( ) . ty , r. head ( ) . span ) )
1384+ let ( ty, span) = matrix
1385+ . heads ( )
1386+ . map ( |r| ( r. ty , r. span ) )
13531387 . find ( |( ty, _) | !ty. references_error ( ) )
13541388 . unwrap_or ( ( v. head ( ) . ty , v. head ( ) . span ) ) ;
13551389 let pcx = PatCtxt {
@@ -1373,7 +1407,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
13731407 // introducing uninhabited patterns for inaccessible fields. We
13741408 // need to figure out how to model that.
13751409 ty,
1376- max_slice_length : max_slice_length ( cx, rows . iter ( ) . map ( |r| r . head ( ) ) . chain ( Some ( v. head ( ) ) ) ) ,
1410+ max_slice_length : max_slice_length ( cx, matrix . heads ( ) . chain ( Some ( v. head ( ) ) ) ) ,
13771411 span,
13781412 } ;
13791413
@@ -1397,10 +1431,8 @@ pub fn is_useful<'p, 'a, 'tcx>(
13971431 } else {
13981432 debug ! ( "is_useful - expanding wildcard" ) ;
13991433
1400- let used_ctors: Vec < Constructor < ' _ > > = rows
1401- . iter ( )
1402- . flat_map ( |row| pat_constructors ( cx, row. head ( ) , pcx) . unwrap_or ( vec ! [ ] ) )
1403- . collect ( ) ;
1434+ let used_ctors: Vec < Constructor < ' _ > > =
1435+ matrix. heads ( ) . flat_map ( |p| pat_constructors ( cx, p, pcx) . unwrap_or ( vec ! [ ] ) ) . collect ( ) ;
14041436 debug ! ( "used_ctors = {:#?}" , used_ctors) ;
14051437 // `all_ctors` are all the constructors for the given type, which
14061438 // should all be represented (or caught with the wild pattern `_`).
@@ -1572,9 +1604,8 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
15721604 hir_id : HirId ,
15731605) -> Usefulness < ' tcx > {
15741606 debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, lty) ;
1575- let sub_pat_tys = constructor_sub_pattern_tys ( cx, & ctor, lty) ;
1576- let wild_patterns_owned: Vec < _ > =
1577- sub_pat_tys. iter ( ) . map ( |ty| Pat { ty, span : DUMMY_SP , kind : box PatKind :: Wild } ) . collect ( ) ;
1607+
1608+ let wild_patterns_owned = ctor. wildcard_subpatterns ( cx, lty) ;
15781609 let wild_patterns: Vec < _ > = wild_patterns_owned. iter ( ) . collect ( ) ;
15791610 let matrix = matrix. specialize_constructor ( cx, & ctor, & wild_patterns) ;
15801611 match v. specialize_constructor ( cx, & ctor, & wild_patterns) {
@@ -1637,26 +1668,6 @@ fn pat_constructors<'tcx>(
16371668 }
16381669}
16391670
1640- /// This computes the arity of a constructor. The arity of a constructor
1641- /// is how many subpattern patterns of that constructor should be expanded to.
1642- ///
1643- /// For instance, a tuple pattern `(_, 42, Some([]))` has the arity of 3.
1644- /// A struct pattern's arity is the number of fields it contains, etc.
1645- fn constructor_arity ( cx : & MatchCheckCtxt < ' a , ' tcx > , ctor : & Constructor < ' tcx > , ty : Ty < ' tcx > ) -> u64 {
1646- debug ! ( "constructor_arity({:#?}, {:?})" , ctor, ty) ;
1647- match ty. kind {
1648- ty:: Tuple ( ref fs) => fs. len ( ) as u64 ,
1649- ty:: Slice ( ..) | ty:: Array ( ..) => match * ctor {
1650- Slice ( length) => length,
1651- ConstantValue ( ..) => 0 ,
1652- _ => bug ! ( "bad slice pattern {:?} {:?}" , ctor, ty) ,
1653- } ,
1654- ty:: Ref ( ..) => 1 ,
1655- ty:: Adt ( adt, _) => adt. variants [ ctor. variant_index_for_adt ( cx, adt) ] . fields . len ( ) as u64 ,
1656- _ => 0 ,
1657- }
1658- }
1659-
16601671/// This computes the types of the sub patterns that a constructor should be
16611672/// expanded to.
16621673///
@@ -1833,7 +1844,7 @@ fn split_grouped_constructors<'p, 'tcx>(
18331844 tcx : TyCtxt < ' tcx > ,
18341845 param_env : ty:: ParamEnv < ' tcx > ,
18351846 ctors : Vec < Constructor < ' tcx > > ,
1836- & Matrix ( ref m ) : & Matrix < ' p , ' tcx > ,
1847+ matrix : & Matrix < ' p , ' tcx > ,
18371848 ty : Ty < ' tcx > ,
18381849 span : Span ,
18391850 hir_id : Option < HirId > ,
@@ -1875,7 +1886,8 @@ fn split_grouped_constructors<'p, 'tcx>(
18751886 let mut overlaps = vec ! [ ] ;
18761887 // `borders` is the set of borders between equivalence classes: each equivalence
18771888 // class lies between 2 borders.
1878- let row_borders = m
1889+ let row_borders = matrix
1890+ . 0
18791891 . iter ( )
18801892 . flat_map ( |row| {
18811893 IntRange :: from_pat ( tcx, param_env, row. head ( ) ) . map ( |r| ( r, row. len ( ) ) )
0 commit comments