@@ -379,6 +379,25 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
379379 fn iter ( & self ) -> impl Iterator < Item = & Pat < ' tcx > > {
380380 self . 0 . iter ( ) . map ( |p| * p)
381381 }
382+
383+ /// This computes `D(self)`. See top of the file for explanations.
384+ fn specialize_wildcard ( & self ) -> Option < Self > {
385+ if self . head ( ) . is_wildcard ( ) { Some ( self . to_tail ( ) ) } else { None }
386+ }
387+
388+ /// This computes `S(constructor, self)`. See top of the file for explanations.
389+ fn specialize_constructor < ' a , ' q > (
390+ & self ,
391+ cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
392+ constructor : & Constructor < ' tcx > ,
393+ wild_patterns : & [ & ' q Pat < ' tcx > ] ,
394+ ) -> Option < PatStack < ' q , ' tcx > >
395+ where
396+ ' a : ' q ,
397+ ' p : ' q ,
398+ {
399+ specialize ( cx, self , constructor, wild_patterns)
400+ }
382401}
383402
384403impl < ' p , ' tcx > Default for PatStack < ' p , ' tcx > {
@@ -407,6 +426,30 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
407426 pub fn push ( & mut self , row : PatStack < ' p , ' tcx > ) {
408427 self . 0 . push ( row)
409428 }
429+
430+ /// This computes `D(self)`. See top of the file for explanations.
431+ fn specialize_wildcard ( & self ) -> Self {
432+ self . 0 . iter ( ) . filter_map ( |r| r. specialize_wildcard ( ) ) . collect ( )
433+ }
434+
435+ /// This computes `S(constructor, self)`. See top of the file for explanations.
436+ fn specialize_constructor < ' a , ' q > (
437+ & self ,
438+ cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
439+ constructor : & Constructor < ' tcx > ,
440+ wild_patterns : & [ & ' q Pat < ' tcx > ] ,
441+ ) -> Matrix < ' q , ' tcx >
442+ where
443+ ' a : ' q ,
444+ ' p : ' q ,
445+ {
446+ Matrix (
447+ self . 0
448+ . iter ( )
449+ . filter_map ( |r| r. specialize_constructor ( cx, constructor, wild_patterns) )
450+ . collect ( ) ,
451+ )
452+ }
410453}
411454
412455/// Pretty-printer for matrices of patterns, example:
@@ -1423,11 +1466,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
14231466 . find ( |result| result. is_useful ( ) )
14241467 . unwrap_or ( NotUseful )
14251468 } else {
1426- let matrix = rows
1427- . iter ( )
1428- . filter_map ( |r| if r. head ( ) . is_wildcard ( ) { Some ( r. to_tail ( ) ) } else { None } )
1429- . collect ( ) ;
1430- match is_useful ( cx, & matrix, & v. to_tail ( ) , witness, hir_id) {
1469+ let matrix = matrix. specialize_wildcard ( ) ;
1470+ let v = v. to_tail ( ) ;
1471+ match is_useful ( cx, & matrix, & v, witness, hir_id) {
14311472 UsefulWithWitness ( pats) => {
14321473 let cx = & * cx;
14331474 // In this case, there's at least one "free"
@@ -1523,7 +1564,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
15231564/// to the specialised version of both the pattern matrix `P` and the new pattern `q`.
15241565fn is_useful_specialized < ' p , ' a , ' tcx > (
15251566 cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
1526- & Matrix ( ref m ) : & Matrix < ' p , ' tcx > ,
1567+ matrix : & Matrix < ' p , ' tcx > ,
15271568 v : & PatStack < ' _ , ' tcx > ,
15281569 ctor : Constructor < ' tcx > ,
15291570 lty : Ty < ' tcx > ,
@@ -1535,9 +1576,8 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
15351576 let wild_patterns_owned: Vec < _ > =
15361577 sub_pat_tys. iter ( ) . map ( |ty| Pat { ty, span : DUMMY_SP , kind : box PatKind :: Wild } ) . collect ( ) ;
15371578 let wild_patterns: Vec < _ > = wild_patterns_owned. iter ( ) . collect ( ) ;
1538- let matrix =
1539- Matrix ( m. iter ( ) . filter_map ( |r| specialize ( cx, & r, & ctor, & wild_patterns) ) . collect ( ) ) ;
1540- match specialize ( cx, v, & ctor, & wild_patterns) {
1579+ let matrix = matrix. specialize_constructor ( cx, & ctor, & wild_patterns) ;
1580+ match v. specialize_constructor ( cx, & ctor, & wild_patterns) {
15411581 Some ( v) => match is_useful ( cx, & matrix, & v, witness, hir_id) {
15421582 UsefulWithWitness ( witnesses) => UsefulWithWitness (
15431583 witnesses
@@ -2013,7 +2053,7 @@ fn specialize<'p, 'a: 'p, 'q: 'p, 'tcx>(
20132053) -> Option < PatStack < ' p , ' tcx > > {
20142054 let pat = r. head ( ) ;
20152055
2016- let head = match * pat. kind {
2056+ let new_head = match * pat. kind {
20172057 PatKind :: AscribeUserType { ref subpattern, .. } => {
20182058 specialize ( cx, & PatStack :: from_pattern ( subpattern) , constructor, wild_patterns)
20192059 }
@@ -2167,9 +2207,9 @@ fn specialize<'p, 'a: 'p, 'q: 'p, 'tcx>(
21672207 bug ! ( "support for or-patterns has not been fully implemented yet." ) ;
21682208 }
21692209 } ;
2170- debug ! ( "specialize({:#?}, {:#?}) = {:#?}" , r. head( ) , wild_patterns, head ) ;
2210+ debug ! ( "specialize({:#?}, {:#?}) = {:#?}" , r. head( ) , wild_patterns, new_head ) ;
21712211
2172- head . map ( |head| {
2212+ new_head . map ( |head| {
21732213 let mut head = head. 0 ;
21742214 head. extend_from_slice ( & r. 0 [ 1 ..] ) ;
21752215 PatStack :: from_vec ( head)
0 commit comments