@@ -1619,12 +1619,17 @@ impl<'tcx> fmt::Debug for MissingConstructors<'tcx> {
1619
1619
/// relation to preceding patterns, it is not reachable) and exhaustiveness
1620
1620
/// checking (if a wildcard pattern is useful in relation to a matrix, the
1621
1621
/// 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.
1622
1626
crate fn is_useful < ' p , ' tcx > (
1623
1627
cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
1624
1628
matrix : & Matrix < ' p , ' tcx > ,
1625
1629
v : & PatStack < ' p , ' tcx > ,
1626
1630
witness_preference : WitnessPreference ,
1627
1631
hir_id : HirId ,
1632
+ is_under_guard : bool ,
1628
1633
is_top_level : bool ,
1629
1634
) -> Usefulness < ' tcx , ' p > {
1630
1635
let & Matrix ( ref rows) = matrix;
@@ -1653,7 +1658,7 @@ crate fn is_useful<'p, 'tcx>(
1653
1658
let mut unreachable_pats = Vec :: new ( ) ;
1654
1659
let mut any_is_useful = false ;
1655
1660
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 ) ;
1657
1662
match res {
1658
1663
Useful ( pats) => {
1659
1664
any_is_useful = true ;
@@ -1664,7 +1669,10 @@ crate fn is_useful<'p, 'tcx>(
1664
1669
bug ! ( "Encountered or-pat in `v` during exhaustiveness checking" )
1665
1670
}
1666
1671
}
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
+ }
1668
1676
}
1669
1677
return if any_is_useful { Useful ( unreachable_pats) } else { NotUseful } ;
1670
1678
}
@@ -1712,7 +1720,18 @@ crate fn is_useful<'p, 'tcx>(
1712
1720
Some ( hir_id) ,
1713
1721
)
1714
1722
. 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
+ } )
1716
1735
. find ( |result| result. is_useful ( ) )
1717
1736
. unwrap_or ( NotUseful )
1718
1737
} else {
@@ -1746,14 +1765,24 @@ crate fn is_useful<'p, 'tcx>(
1746
1765
split_grouped_constructors ( cx. tcx , cx. param_env , pcx, all_ctors, matrix, DUMMY_SP , None )
1747
1766
. into_iter ( )
1748
1767
. 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
+ )
1750
1778
} )
1751
1779
. find ( |result| result. is_useful ( ) )
1752
1780
. unwrap_or ( NotUseful )
1753
1781
} else {
1754
1782
let matrix = matrix. specialize_wildcard ( ) ;
1755
1783
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 ) ;
1757
1786
1758
1787
// In this case, there's at least one "free"
1759
1788
// constructor that is only matched against by
@@ -1810,14 +1839,15 @@ fn is_useful_specialized<'p, 'tcx>(
1810
1839
lty : Ty < ' tcx > ,
1811
1840
witness_preference : WitnessPreference ,
1812
1841
hir_id : HirId ,
1842
+ is_under_guard : bool ,
1813
1843
) -> Usefulness < ' tcx , ' p > {
1814
1844
debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, lty) ;
1815
1845
1816
1846
let ctor_wild_subpatterns =
1817
1847
cx. pattern_arena . alloc_from_iter ( ctor. wildcard_subpatterns ( cx, lty) ) ;
1818
1848
let matrix = matrix. specialize_constructor ( cx, & ctor, ctor_wild_subpatterns) ;
1819
1849
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 ) )
1821
1851
. map ( |u| u. apply_constructor ( cx, & ctor, lty) )
1822
1852
. unwrap_or ( NotUseful )
1823
1853
}
0 commit comments