@@ -1619,12 +1619,17 @@ impl<'tcx> fmt::Debug for MissingConstructors<'tcx> {
16191619/// relation to preceding patterns, it is not reachable) and exhaustiveness
16201620/// checking (if a wildcard pattern is useful in relation to a matrix, the
16211621/// matrix isn't exhaustive).
1622+ ///
1623+ /// `is_under_guard` is used to inform if the pattern has a guard. If it
1624+ /// has one it must not be inserted into the matrix. This shouldn't be
1625+ /// relied on for soundness.
16221626crate fn is_useful < ' p , ' tcx > (
16231627 cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
16241628 matrix : & Matrix < ' p , ' tcx > ,
16251629 v : & PatStack < ' p , ' tcx > ,
16261630 witness_preference : WitnessPreference ,
16271631 hir_id : HirId ,
1632+ is_under_guard : bool ,
16281633 is_top_level : bool ,
16291634) -> Usefulness < ' tcx , ' p > {
16301635 let & Matrix ( ref rows) = matrix;
@@ -1653,7 +1658,7 @@ crate fn is_useful<'p, 'tcx>(
16531658 let mut unreachable_pats = Vec :: new ( ) ;
16541659 let mut any_is_useful = false ;
16551660 for v in vs {
1656- let res = is_useful ( cx, & matrix, & v, witness_preference, hir_id, false ) ;
1661+ let res = is_useful ( cx, & matrix, & v, witness_preference, hir_id, is_under_guard , false ) ;
16571662 match res {
16581663 Useful ( pats) => {
16591664 any_is_useful = true ;
@@ -1664,7 +1669,10 @@ crate fn is_useful<'p, 'tcx>(
16641669 bug ! ( "Encountered or-pat in `v` during exhaustiveness checking" )
16651670 }
16661671 }
1667- matrix. push ( v) ;
1672+ // If pattern has a guard don't add it to the matrix
1673+ if !is_under_guard {
1674+ matrix. push ( v) ;
1675+ }
16681676 }
16691677 return if any_is_useful { Useful ( unreachable_pats) } else { NotUseful } ;
16701678 }
@@ -1712,7 +1720,18 @@ crate fn is_useful<'p, 'tcx>(
17121720 Some ( hir_id) ,
17131721 )
17141722 . into_iter ( )
1715- . map ( |c| is_useful_specialized ( cx, matrix, v, c, pcx. ty , witness_preference, hir_id) )
1723+ . map ( |c| {
1724+ is_useful_specialized (
1725+ cx,
1726+ matrix,
1727+ v,
1728+ c,
1729+ pcx. ty ,
1730+ witness_preference,
1731+ hir_id,
1732+ is_under_guard,
1733+ )
1734+ } )
17161735 . find ( |result| result. is_useful ( ) )
17171736 . unwrap_or ( NotUseful )
17181737 } else {
@@ -1746,14 +1765,24 @@ crate fn is_useful<'p, 'tcx>(
17461765 split_grouped_constructors ( cx. tcx , cx. param_env , pcx, all_ctors, matrix, DUMMY_SP , None )
17471766 . into_iter ( )
17481767 . map ( |c| {
1749- is_useful_specialized ( cx, matrix, v, c, pcx. ty , witness_preference, hir_id)
1768+ is_useful_specialized (
1769+ cx,
1770+ matrix,
1771+ v,
1772+ c,
1773+ pcx. ty ,
1774+ witness_preference,
1775+ hir_id,
1776+ is_under_guard,
1777+ )
17501778 } )
17511779 . find ( |result| result. is_useful ( ) )
17521780 . unwrap_or ( NotUseful )
17531781 } else {
17541782 let matrix = matrix. specialize_wildcard ( ) ;
17551783 let v = v. to_tail ( ) ;
1756- let usefulness = is_useful ( cx, & matrix, & v, witness_preference, hir_id, false ) ;
1784+ let usefulness =
1785+ is_useful ( cx, & matrix, & v, witness_preference, hir_id, is_under_guard, false ) ;
17571786
17581787 // In this case, there's at least one "free"
17591788 // constructor that is only matched against by
@@ -1810,14 +1839,15 @@ fn is_useful_specialized<'p, 'tcx>(
18101839 lty : Ty < ' tcx > ,
18111840 witness_preference : WitnessPreference ,
18121841 hir_id : HirId ,
1842+ is_under_guard : bool ,
18131843) -> Usefulness < ' tcx , ' p > {
18141844 debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, lty) ;
18151845
18161846 let ctor_wild_subpatterns =
18171847 cx. pattern_arena . alloc_from_iter ( ctor. wildcard_subpatterns ( cx, lty) ) ;
18181848 let matrix = matrix. specialize_constructor ( cx, & ctor, ctor_wild_subpatterns) ;
18191849 v. specialize_constructor ( cx, & ctor, ctor_wild_subpatterns)
1820- . map ( |v| is_useful ( cx, & matrix, & v, witness_preference, hir_id, false ) )
1850+ . map ( |v| is_useful ( cx, & matrix, & v, witness_preference, hir_id, is_under_guard , false ) )
18211851 . map ( |u| u. apply_constructor ( cx, & ctor, lty) )
18221852 . unwrap_or ( NotUseful )
18231853}
0 commit comments