@@ -41,36 +41,30 @@ impl ConstantCx {
41
41
pub ( crate ) fn check_constants ( fx : & mut FunctionCx < ' _ , ' _ , ' _ > ) -> bool {
42
42
let mut all_constants_ok = true ;
43
43
for constant in & fx. mir . required_consts {
44
- let const_ = match fx. monomorphize ( constant. literal ) {
45
- ConstantKind :: Ty ( ct) => ct,
44
+ let unevaluated = match fx. monomorphize ( constant. literal ) {
45
+ ConstantKind :: Ty ( ct) => match ct. kind ( ) {
46
+ ConstKind :: Unevaluated ( uv) => uv. expand ( ) ,
47
+ ConstKind :: Value ( _) => continue ,
48
+ ConstKind :: Param ( _)
49
+ | ConstKind :: Infer ( _)
50
+ | ConstKind :: Bound ( _, _)
51
+ | ConstKind :: Placeholder ( _)
52
+ | ConstKind :: Error ( _) => unreachable ! ( "{:?}" , ct) ,
53
+ } ,
54
+ ConstantKind :: Unevaluated ( uv, _) => uv,
46
55
ConstantKind :: Val ( ..) => continue ,
47
56
} ;
48
- match const_. kind ( ) {
49
- ConstKind :: Value ( _) => { }
50
- ConstKind :: Unevaluated ( unevaluated) => {
51
- if let Err ( err) =
52
- fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , unevaluated, None )
53
- {
54
- all_constants_ok = false ;
55
- match err {
56
- ErrorHandled :: Reported ( _) | ErrorHandled :: Linted => {
57
- fx. tcx . sess . span_err ( constant. span , "erroneous constant encountered" ) ;
58
- }
59
- ErrorHandled :: TooGeneric => {
60
- span_bug ! (
61
- constant. span,
62
- "codegen encountered polymorphic constant: {:?}" ,
63
- err
64
- ) ;
65
- }
66
- }
57
+
58
+ if let Err ( err) = fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , unevaluated, None ) {
59
+ all_constants_ok = false ;
60
+ match err {
61
+ ErrorHandled :: Reported ( _) | ErrorHandled :: Linted => {
62
+ fx. tcx . sess . span_err ( constant. span , "erroneous constant encountered" ) ;
63
+ }
64
+ ErrorHandled :: TooGeneric => {
65
+ span_bug ! ( constant. span, "codegen encountered polymorphic constant: {:?}" , err) ;
67
66
}
68
67
}
69
- ConstKind :: Param ( _)
70
- | ConstKind :: Infer ( _)
71
- | ConstKind :: Bound ( _, _)
72
- | ConstKind :: Placeholder ( _)
73
- | ConstKind :: Error ( _) => unreachable ! ( "{:?}" , const_) ,
74
68
}
75
69
}
76
70
all_constants_ok
@@ -122,43 +116,56 @@ pub(crate) fn codegen_constant<'tcx>(
122
116
fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
123
117
constant : & Constant < ' tcx > ,
124
118
) -> CValue < ' tcx > {
125
- let const_ = match fx. monomorphize ( constant. literal ) {
126
- ConstantKind :: Ty ( ct) => ct,
127
- ConstantKind :: Unevaluated ( mir:: Unevaluated { def, substs, promoted } )
119
+ let ( const_val, ty) = match fx. monomorphize ( constant. literal ) {
120
+ ConstantKind :: Ty ( const_) => match const_. kind ( ) {
121
+ ConstKind :: Value ( valtree) => {
122
+ ( fx. tcx . valtree_to_const_val ( ( const_. ty ( ) , valtree) ) , const_. ty ( ) )
123
+ }
124
+ ConstKind :: Unevaluated ( ty:: Unevaluated { def, substs, promoted } )
125
+ if fx. tcx . is_static ( def. did ) =>
126
+ {
127
+ assert ! ( substs. is_empty( ) ) ;
128
+ assert_eq ! ( promoted, ( ) ) ;
129
+ return codegen_static_ref ( fx, def. did , fx. layout_of ( const_. ty ( ) ) ) . to_cvalue ( fx) ;
130
+ }
131
+ ConstKind :: Unevaluated ( unevaluated) => {
132
+ match fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , unevaluated. expand ( ) , None )
133
+ {
134
+ Ok ( const_val) => ( const_val, const_. ty ( ) ) ,
135
+ Err ( _) => {
136
+ span_bug ! (
137
+ constant. span,
138
+ "erroneous constant not captured by required_consts"
139
+ ) ;
140
+ }
141
+ }
142
+ }
143
+ ConstKind :: Param ( _)
144
+ | ConstKind :: Infer ( _)
145
+ | ConstKind :: Bound ( _, _)
146
+ | ConstKind :: Placeholder ( _)
147
+ | ConstKind :: Error ( _) => unreachable ! ( "{:?}" , const_) ,
148
+ } ,
149
+ ConstantKind :: Unevaluated ( ty:: Unevaluated { def, substs, promoted } , ty)
128
150
if fx. tcx . is_static ( def. did ) =>
129
151
{
130
152
assert ! ( substs. is_empty( ) ) ;
131
153
assert ! ( promoted. is_none( ) ) ;
132
154
133
- return codegen_static_ref ( fx, def. did , fx. layout_of ( const_ . ty ( ) ) ) . to_cvalue ( fx) ;
155
+ return codegen_static_ref ( fx, def. did , fx. layout_of ( ty ) ) . to_cvalue ( fx) ;
134
156
}
135
- ConstantKind :: Unevaluated ( unevaluated) => {
157
+ ConstantKind :: Unevaluated ( unevaluated, ty ) => {
136
158
match fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , unevaluated, None ) {
137
- Ok ( const_val) => const_val,
159
+ Ok ( const_val) => ( const_val, ty ) ,
138
160
Err ( _) => {
139
161
span_bug ! ( constant. span, "erroneous constant not captured by required_consts" ) ;
140
162
}
141
163
}
142
164
}
143
- ConstantKind :: Val ( val, ty) => return codegen_const_value ( fx, val, ty) ,
144
- } ;
145
- let const_val = match const_. kind ( ) {
146
- ConstKind :: Value ( valtree) => fx. tcx . valtree_to_const_val ( ( const_. ty ( ) , valtree) ) ,
147
- ConstKind :: Unevaluated ( ty:: Unevaluated { def, substs, promoted } )
148
- if fx. tcx . is_static ( def. did ) =>
149
- {
150
- assert ! ( substs. is_empty( ) ) ;
151
- assert ! ( promoted. is_none( ) ) ;
152
- return codegen_static_ref ( fx, def. did , fx. layout_of ( const_. ty ( ) ) ) . to_cvalue ( fx) ;
153
- }
154
- ConstKind :: Param ( _)
155
- | ConstKind :: Infer ( _)
156
- | ConstKind :: Bound ( _, _)
157
- | ConstKind :: Placeholder ( _)
158
- | ConstKind :: Error ( _) => unreachable ! ( "{:?}" , const_) ,
165
+ ConstantKind :: Val ( val, ty) => ( val, ty) ,
159
166
} ;
160
167
161
- codegen_const_value ( fx, const_val, const_ . ty ( ) )
168
+ codegen_const_value ( fx, const_val, ty )
162
169
}
163
170
164
171
pub ( crate ) fn codegen_const_value < ' tcx > (
@@ -503,6 +510,9 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
503
510
. eval_for_mir ( fx. tcx , ParamEnv :: reveal_all ( ) )
504
511
. try_to_value ( fx. tcx ) ,
505
512
ConstantKind :: Val ( val, _) => Some ( val) ,
513
+ ConstantKind :: Unevaluated ( uv, _) => {
514
+ fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , uv, None ) . ok ( )
515
+ }
506
516
} ,
507
517
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
508
518
// inside a temporary before being passed to the intrinsic requiring the const argument.
0 commit comments