@@ -31,7 +31,7 @@ use rustc_infer::traits::WellFormedLoc;
3131use rustc_infer:: traits:: query:: NoSolution ;
3232use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase } ;
3333use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
34- use rustc_middle:: ty:: { self , AdtKind , GenericArgs , Ty , TypeVisitableExt , Unnormalized } ;
34+ use rustc_middle:: ty:: { self , AdtKind , ConstKind , GenericArgs , Ty , TypeVisitableExt , Unnormalized } ;
3535use rustc_session:: diagnostics:: feature_err;
3636use rustc_span:: edit_distance:: find_best_match_for_name;
3737use rustc_span:: hygiene:: DesugaringKind ;
@@ -1774,17 +1774,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17741774 ) ,
17751775 ) ;
17761776
1777- let count_is_zero = {
1778- if let Ok ( count) = tcx. try_normalize_erasing_regions (
1779- self . typing_env ( self . param_env ) ,
1780- Unnormalized :: new_wip ( count) ,
1781- ) {
1782- count. try_to_value ( ) . and_then ( |c| c. try_to_target_usize ( tcx) ) == Some ( 0 )
1783- } else {
1784- false
1785- }
1786- } ;
1787-
17881777 let uty = match expected {
17891778 ExpectHasType ( uty) => uty. builtin_index ( ) ,
17901779 _ => None ,
@@ -1811,6 +1800,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18111800 // This is a problem, because it means if `CONST` is `const { panic!() }`, the side effect
18121801 // of panic / failing compilation never happens. In such cases we need to ignore divergence
18131802 // from the `CONST`, as otherwise we can end up executing code that was assumed unreachable.
1803+ let count_is_zero = match count. kind ( ) {
1804+ // This is the exact check that mir building does
1805+ ConstKind :: Value ( v) => v. try_to_target_usize ( tcx) == Some ( 0 ) ,
1806+
1807+ // An infer const can get inferred to 0.
1808+ //
1809+ // We could check the expectation here to do ad-hoc inference, but that feels quite
1810+ // error prone and annoying.
1811+ ConstKind :: Infer ( _) => true ,
1812+
1813+ // While const generic params can be substituted with 0, mir building specifically
1814+ // checks for value 0 before monomorphization, so they (alongside aliases, etc) cannot
1815+ // trigger the bug.
1816+ ConstKind :: Param ( _)
1817+ | ConstKind :: Placeholder ( _)
1818+ | ConstKind :: Alias ( ..)
1819+ | ConstKind :: Error ( _)
1820+ | ConstKind :: Expr ( _) => false ,
1821+
1822+ ConstKind :: Bound ( ..) => bug ! ( ) ,
1823+ } ;
1824+
18141825 if count_is_zero && element. is_constant_for_zero_repeat ( ) {
18151826 self . diverges . set ( old_diverges) ;
18161827 }
0 commit comments