@@ -7,10 +7,11 @@ use hir_def::{
7
7
path:: Path ,
8
8
resolver:: { Resolver , ValueNs } ,
9
9
type_ref:: ConstRef ,
10
- DefWithBodyId , EnumVariantId ,
10
+ EnumVariantId , GeneralConstId , StaticId ,
11
11
} ;
12
12
use la_arena:: { Idx , RawIdx } ;
13
13
use stdx:: never;
14
+ use triomphe:: Arc ;
14
15
15
16
use crate :: {
16
17
db:: HirDatabase , infer:: InferenceContext , layout:: layout_of_ty, lower:: ParamLoweringMode ,
@@ -158,13 +159,17 @@ pub fn usize_const(db: &dyn HirDatabase, value: Option<u128>, krate: CrateId) ->
158
159
)
159
160
}
160
161
161
- pub fn try_const_usize ( c : & Const ) -> Option < u128 > {
162
+ pub fn try_const_usize ( db : & dyn HirDatabase , c : & Const ) -> Option < u128 > {
162
163
match & c. data ( Interner ) . value {
163
164
chalk_ir:: ConstValue :: BoundVar ( _) => None ,
164
165
chalk_ir:: ConstValue :: InferenceVar ( _) => None ,
165
166
chalk_ir:: ConstValue :: Placeholder ( _) => None ,
166
167
chalk_ir:: ConstValue :: Concrete ( c) => match & c. interned {
167
168
ConstScalar :: Bytes ( x, _) => Some ( u128:: from_le_bytes ( pad16 ( & x, false ) ) ) ,
169
+ ConstScalar :: UnevaluatedConst ( c, subst) => {
170
+ let ec = db. const_eval ( * c, subst. clone ( ) ) . ok ( ) ?;
171
+ try_const_usize ( db, & ec)
172
+ }
168
173
_ => None ,
169
174
} ,
170
175
}
@@ -173,12 +178,20 @@ pub fn try_const_usize(c: &Const) -> Option<u128> {
173
178
pub ( crate ) fn const_eval_recover (
174
179
_: & dyn HirDatabase ,
175
180
_: & [ String ] ,
176
- _: & DefWithBodyId ,
181
+ _: & GeneralConstId ,
177
182
_: & Substitution ,
178
183
) -> Result < Const , ConstEvalError > {
179
184
Err ( ConstEvalError :: MirLowerError ( MirLowerError :: Loop ) )
180
185
}
181
186
187
+ pub ( crate ) fn const_eval_static_recover (
188
+ _: & dyn HirDatabase ,
189
+ _: & [ String ] ,
190
+ _: & StaticId ,
191
+ ) -> Result < Const , ConstEvalError > {
192
+ Err ( ConstEvalError :: MirLowerError ( MirLowerError :: Loop ) )
193
+ }
194
+
182
195
pub ( crate ) fn const_eval_discriminant_recover (
183
196
_: & dyn HirDatabase ,
184
197
_: & [ String ] ,
@@ -189,11 +202,28 @@ pub(crate) fn const_eval_discriminant_recover(
189
202
190
203
pub ( crate ) fn const_eval_query (
191
204
db : & dyn HirDatabase ,
192
- def : DefWithBodyId ,
205
+ def : GeneralConstId ,
193
206
subst : Substitution ,
194
207
) -> Result < Const , ConstEvalError > {
195
- let body = db. mir_body ( def) ?;
196
- let c = interpret_mir ( db, & body, subst, false ) ?;
208
+ let body = match def {
209
+ GeneralConstId :: ConstId ( c) => db. mir_body ( c. into ( ) ) ?,
210
+ GeneralConstId :: AnonymousConstId ( c) => {
211
+ let ( def, root) = db. lookup_intern_anonymous_const ( c) ;
212
+ let body = db. body ( def) ;
213
+ let infer = db. infer ( def) ;
214
+ Arc :: new ( lower_to_mir ( db, def, & body, & infer, root) ?)
215
+ }
216
+ } ;
217
+ let c = interpret_mir ( db, & body, subst, false ) . 0 ?;
218
+ Ok ( c)
219
+ }
220
+
221
+ pub ( crate ) fn const_eval_static_query (
222
+ db : & dyn HirDatabase ,
223
+ def : StaticId ,
224
+ ) -> Result < Const , ConstEvalError > {
225
+ let body = db. mir_body ( def. into ( ) ) ?;
226
+ let c = interpret_mir ( db, & body, Substitution :: empty ( Interner ) , false ) . 0 ?;
197
227
Ok ( c)
198
228
}
199
229
@@ -216,8 +246,8 @@ pub(crate) fn const_eval_discriminant_variant(
216
246
return Ok ( value) ;
217
247
}
218
248
let mir_body = db. mir_body ( def) ?;
219
- let c = interpret_mir ( db, & mir_body, Substitution :: empty ( Interner ) , false ) ?;
220
- let c = try_const_usize ( & c) . unwrap ( ) as i128 ;
249
+ let c = interpret_mir ( db, & mir_body, Substitution :: empty ( Interner ) , false ) . 0 ?;
250
+ let c = try_const_usize ( db , & c) . unwrap ( ) as i128 ;
221
251
Ok ( c)
222
252
}
223
253
@@ -241,7 +271,7 @@ pub(crate) fn eval_to_const(
241
271
}
242
272
let infer = ctx. clone ( ) . resolve_all ( ) ;
243
273
if let Ok ( mir_body) = lower_to_mir ( ctx. db , ctx. owner , & ctx. body , & infer, expr) {
244
- if let Ok ( result) = interpret_mir ( db, & mir_body, Substitution :: empty ( Interner ) , true ) {
274
+ if let Ok ( result) = interpret_mir ( db, & mir_body, Substitution :: empty ( Interner ) , true ) . 0 {
245
275
return result;
246
276
}
247
277
}
0 commit comments