File tree Expand file tree Collapse file tree 2 files changed +53
-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 +53
-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+ //@ revisions: full
3+ // This is a regression test for an ICE in const qualifs where
4+ // `Const::Ty` containing `ty::ConstKind::Unevaluated` was not handled.
5+ // The pattern arises with `generic_const_exprs` and const fn using
6+ // array lengths like `LEN * LEN` and repeat expressions.
7+
8+ #![ cfg_attr( full, feature( generic_const_exprs) ) ]
9+ #![ cfg_attr( full, allow( incomplete_features) ) ]
10+
11+ trait One : Sized + Copy {
12+ const ONE : Self ;
13+ }
14+
15+ const fn noop < T : One > ( a : & mut T , b : & mut T ) {
16+ let _ = ( a, b) ;
17+ }
18+
19+ struct Test < T : One , const LEN : usize > ( [ T ; LEN * LEN ] )
20+ where
21+ [ u8 ; LEN * LEN ] : ;
22+
23+ impl < T : One , const LEN : usize > Test < T , LEN >
24+ where
25+ [ u8 ; LEN * LEN ] : ,
26+ {
27+ const fn test ( ) -> Self {
28+ let mut a = Self ( [ T :: ONE ; LEN * LEN ] ) ;
29+ let mut i = 0 ;
30+ while i < LEN {
31+ let mut one = T :: ONE ;
32+ noop ( & mut one, & mut a. 0 [ i * i + 1 ] ) ;
33+ i += 1 ;
34+ }
35+ a
36+ }
37+ }
38+
39+ fn main ( ) { }
You can’t perform that action at this time.
0 commit comments