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
347
347
348
348
// Check the qualifs of the value of `const` items.
349
349
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.
361
363
Const :: Unevaluated ( uv, _) => Some ( uv) ,
364
+ // Already a value: rely on type-based qualifs below.
362
365
Const :: Val ( ..) => None ,
363
366
} ;
364
367
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