@@ -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