@@ -364,8 +364,8 @@ impl<'a, 'p, 'tcx> fmt::Debug for PatCtxt<'a, 'p, 'tcx> {
364364/// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
365365/// works well.
366366#[ derive( Clone ) ]
367- struct PatStack < ' p , ' tcx > {
368- pats : SmallVec < [ & ' p DeconstructedPat < ' p , ' tcx > ; 2 ] > ,
367+ pub ( crate ) struct PatStack < ' p , ' tcx > {
368+ pub ( crate ) pats : SmallVec < [ & ' p DeconstructedPat < ' p , ' tcx > ; 2 ] > ,
369369}
370370
371371impl < ' p , ' tcx > PatStack < ' p , ' tcx > {
@@ -403,6 +403,21 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
403403 } )
404404 }
405405
406+ // Recursively expand all patterns into their subpatterns and push each `PatStack` to matrix.
407+ fn expand_and_extend < ' a > ( & ' a self , matrix : & mut Matrix < ' p , ' tcx > ) {
408+ if !self . is_empty ( ) && self . head ( ) . is_or_pat ( ) {
409+ for pat in self . head ( ) . iter_fields ( ) {
410+ let mut new_patstack = PatStack :: from_pattern ( pat) ;
411+ new_patstack. pats . extend_from_slice ( & self . pats [ 1 ..] ) ;
412+ if !new_patstack. is_empty ( ) && new_patstack. head ( ) . is_or_pat ( ) {
413+ new_patstack. expand_and_extend ( matrix) ;
414+ } else if !new_patstack. is_empty ( ) {
415+ matrix. push ( new_patstack) ;
416+ }
417+ }
418+ }
419+ }
420+
406421 /// This computes `S(self.head().ctor(), self)`. See top of the file for explanations.
407422 ///
408423 /// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
@@ -436,7 +451,7 @@ impl<'p, 'tcx> fmt::Debug for PatStack<'p, 'tcx> {
436451/// A 2D matrix.
437452#[ derive( Clone ) ]
438453pub ( super ) struct Matrix < ' p , ' tcx > {
439- patterns : Vec < PatStack < ' p , ' tcx > > ,
454+ pub patterns : Vec < PatStack < ' p , ' tcx > > ,
440455}
441456
442457impl < ' p , ' tcx > Matrix < ' p , ' tcx > {
@@ -453,17 +468,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
453468 /// expands it.
454469 fn push ( & mut self , row : PatStack < ' p , ' tcx > ) {
455470 if !row. is_empty ( ) && row. head ( ) . is_or_pat ( ) {
456- let pats = row. expand_or_pat ( ) ;
457- let mut no_inner_or = true ;
458- for pat in pats {
459- if !pat. is_empty ( ) && pat. head ( ) . is_or_pat ( ) {
460- self . patterns . extend ( pat. expand_or_pat ( ) ) ;
461- no_inner_or = false ;
462- }
463- }
464- if no_inner_or {
465- self . patterns . extend ( row. expand_or_pat ( ) ) ;
466- }
471+ row. expand_and_extend ( self ) ;
467472 } else {
468473 self . patterns . push ( row) ;
469474 }
0 commit comments