File tree Expand file tree Collapse file tree 2 files changed +50
-11
lines changed
compiler/rustc_const_eval/src/check_consts
tests/ui/const-generics/generic_const_exprs Expand file tree Collapse file tree 2 files changed +50
-11
lines changed Original file line number Diff line number Diff line change @@ -347,18 +347,21 @@ where
347347
348348 // Check the qualifs of the value of `const` items.
349349 let uneval = match constant. const_ {
350- Const :: Ty ( _, ct)
351- if matches ! (
352- ct. kind( ) ,
353- ty:: ConstKind :: Param ( _) | ty:: ConstKind :: Error ( _) | ty:: ConstKind :: Value ( _)
354- ) =>
355- {
356- None
357- }
358- Const :: Ty ( _, c) => {
359- bug ! ( "expected ConstKind::Param or ConstKind::Value here, found {:?}" , c)
360- }
350+ // Type-level constants that are already concrete or are params/errors: fall back to
351+ // type-based qualifs below.
352+ Const :: Ty ( _, ct) => match ct. kind ( ) {
353+ ty:: ConstKind :: Param ( _) | ty:: ConstKind :: Error ( _) | ty:: ConstKind :: Value ( _) => None ,
354+ // A type-level unevaluated const (e.g., from generic const exprs). Treat like a
355+ // MIR unevaluated const so we can look up qualifs on the referenced def.
356+ ty:: ConstKind :: Unevaluated ( uv) => Some ( mir:: UnevaluatedConst :: new ( uv. def , uv. args ) ) ,
357+ // Any other kind should not reach this path in MIR const-checking.
358+ other => {
359+ bug ! ( "expected ConstKind::Param or ConstKind::Value here, found {:?}" , other)
360+ }
361+ } ,
362+ // A MIR unevaluated const: inspect its definition's qualifs below.
361363 Const :: Unevaluated ( uv, _) => Some ( uv) ,
364+ // Already a value: rely on type-based qualifs below.
362365 Const :: Val ( ..) => None ,
363366 } ;
364367
Original file line number Diff line number Diff line change 1+ // check-pass
2+ // This is a regression test for an ICE in const qualifs where
3+ // `Const::Ty` containing `ty::ConstKind::Unevaluated` was not handled.
4+ // The pattern arises with `generic_const_exprs` and const fn using
5+ // array lengths like `LEN * LEN` and repeat expressions.
6+
7+ #![ cfg_attr( full, feature( generic_const_exprs) ) ]
8+ #![ cfg_attr( full, allow( incomplete_features) ) ]
9+
10+ trait One : Sized + Copy {
11+ const ONE : Self ;
12+ }
13+
14+ const fn noop < T : One > ( a : & mut T , b : & mut T ) {
15+ let _ = ( a, b) ;
16+ }
17+
18+ struct Test < T : One , const LEN : usize > ( [ T ; LEN * LEN ] )
19+ where
20+ [ u8 ; LEN * LEN ] : ;
21+
22+ impl < T : One , const LEN : usize > Test < T , LEN >
23+ where
24+ [ u8 ; LEN * LEN ] : ,
25+ {
26+ const fn test ( ) -> Self {
27+ let mut a = Self ( [ T :: ONE ; LEN * LEN ] ) ;
28+ let mut i = 0 ;
29+ while i < LEN {
30+ let mut one = T :: ONE ;
31+ noop ( & mut one, & mut a. 0 [ i * i + 1 ] ) ;
32+ i += 1 ;
33+ }
34+ a
35+ }
36+ }
You can’t perform that action at this time.
0 commit comments