@@ -153,7 +153,7 @@ fn is_valid(scalar: &Scalar, value: i128) -> bool {
153
153
}
154
154
}
155
155
156
- fn get_name ( variant : EnumVariantId , ctx : & mut ConstEvalCtx < ' _ > ) -> String {
156
+ fn get_name ( ctx : & mut ConstEvalCtx < ' _ > , variant : EnumVariantId ) -> String {
157
157
let loc = variant. parent . lookup ( ctx. db . upcast ( ) ) ;
158
158
let children = variant. parent . child_source ( ctx. db . upcast ( ) ) ;
159
159
let item_tree = loc. id . item_tree ( ctx. db . upcast ( ) ) ;
@@ -167,20 +167,24 @@ pub fn eval_const(
167
167
expr_id : ExprId ,
168
168
ctx : & mut ConstEvalCtx < ' _ > ,
169
169
) -> Result < ComputedExpr , ConstEvalError > {
170
+ let u128_to_i128 = |it : u128 | -> Result < i128 , ConstEvalError > {
171
+ it. try_into ( ) . map_err ( |_| ConstEvalError :: NotSupported ( "u128 is too big" ) )
172
+ } ;
173
+
170
174
let expr = & ctx. exprs [ expr_id] ;
171
175
match expr {
172
176
Expr :: Missing => match ctx. owner {
177
+ // evaluate the implicit variant index of an enum variant without expression
178
+ // FIXME: This should return the type of the enum representation
173
179
DefWithBodyId :: VariantId ( variant) => {
174
180
let prev_idx: u32 = variant. local_id . into_raw ( ) . into ( ) ;
175
- let prev_idx = prev_idx. checked_sub ( 1 ) . map ( |idx| Idx :: from_raw ( RawIdx :: from ( idx ) ) ) ;
181
+ let prev_idx = prev_idx. checked_sub ( 1 ) . map ( RawIdx :: from) . map ( Idx :: from_raw ) ;
176
182
let value = match prev_idx {
177
- Some ( prev ) => {
178
- let prev_variant = EnumVariantId { local_id : prev , .. variant } ;
183
+ Some ( local_id ) => {
184
+ let prev_variant = EnumVariantId { local_id, parent : variant. parent } ;
179
185
1 + match ctx. db . const_eval_variant ( prev_variant) ? {
180
186
ComputedExpr :: Literal ( Literal :: Int ( v, _) ) => v,
181
- ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => v
182
- . try_into ( )
183
- . map_err ( |_| ConstEvalError :: NotSupported ( "too big u128" ) ) ?,
187
+ ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => u128_to_i128 ( v) ?,
184
188
_ => {
185
189
return Err ( ConstEvalError :: NotSupported (
186
190
"Enum can't contain this kind of value" ,
@@ -206,9 +210,7 @@ pub fn eval_const(
206
210
return Ok ( ComputedExpr :: Literal ( Literal :: Bool ( !b) ) )
207
211
}
208
212
ComputedExpr :: Literal ( Literal :: Int ( v, _) ) => v,
209
- ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => v
210
- . try_into ( )
211
- . map_err ( |_| ConstEvalError :: NotSupported ( "too big u128" ) ) ?,
213
+ ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => u128_to_i128 ( v) ?,
212
214
_ => return Err ( ConstEvalError :: NotSupported ( "this kind of operator" ) ) ,
213
215
} ;
214
216
let r = match ty. kind ( Interner ) {
@@ -237,9 +239,7 @@ pub fn eval_const(
237
239
hir_def:: expr:: UnaryOp :: Neg => {
238
240
let v = match ev {
239
241
ComputedExpr :: Literal ( Literal :: Int ( v, _) ) => v,
240
- ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => v
241
- . try_into ( )
242
- . map_err ( |_| ConstEvalError :: NotSupported ( "too big u128" ) ) ?,
242
+ ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => u128_to_i128 ( v) ?,
243
243
_ => return Err ( ConstEvalError :: NotSupported ( "this kind of operator" ) ) ,
244
244
} ;
245
245
Ok ( ComputedExpr :: Literal ( Literal :: Int (
@@ -258,16 +258,12 @@ pub fn eval_const(
258
258
let op = op. ok_or ( ConstEvalError :: IncompleteExpr ) ?;
259
259
let v1 = match lhs {
260
260
ComputedExpr :: Literal ( Literal :: Int ( v, _) ) => v,
261
- ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => {
262
- v. try_into ( ) . map_err ( |_| ConstEvalError :: NotSupported ( "too big u128" ) ) ?
263
- }
261
+ ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => u128_to_i128 ( v) ?,
264
262
_ => return Err ( ConstEvalError :: NotSupported ( "this kind of operator" ) ) ,
265
263
} ;
266
264
let v2 = match rhs {
267
265
ComputedExpr :: Literal ( Literal :: Int ( v, _) ) => v,
268
- ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => {
269
- v. try_into ( ) . map_err ( |_| ConstEvalError :: NotSupported ( "too big u128" ) ) ?
270
- }
266
+ ComputedExpr :: Literal ( Literal :: Uint ( v, _) ) => u128_to_i128 ( v) ?,
271
267
_ => return Err ( ConstEvalError :: NotSupported ( "this kind of operator" ) ) ,
272
268
} ;
273
269
match op {
@@ -380,7 +376,7 @@ pub fn eval_const(
380
376
}
381
377
ValueNs :: EnumVariantId ( id) => match ctx. db . const_eval_variant ( id) ? {
382
378
ComputedExpr :: Literal ( lit) => {
383
- Ok ( ComputedExpr :: Enum ( get_name ( id , ctx ) , id, lit) )
379
+ Ok ( ComputedExpr :: Enum ( get_name ( ctx , id ) , id, lit) )
384
380
}
385
381
_ => Err ( ConstEvalError :: NotSupported (
386
382
"Enums can't evalute to anything but numbers" ,
@@ -389,6 +385,7 @@ pub fn eval_const(
389
385
_ => Err ( ConstEvalError :: NotSupported ( "path that are not const or local" ) ) ,
390
386
}
391
387
}
388
+ // FIXME: Handle the cast target
392
389
& Expr :: Cast { expr, .. } => match eval_const ( expr, ctx) ? {
393
390
ComputedExpr :: Enum ( _, _, lit) => Ok ( ComputedExpr :: Literal ( lit) ) ,
394
391
_ => Err ( ConstEvalError :: NotSupported ( "Can't cast these types" ) ) ,
@@ -463,15 +460,15 @@ pub(crate) fn const_eval_recover(
463
460
Err ( ConstEvalError :: Loop )
464
461
}
465
462
466
- pub ( crate ) fn const_eval_recover_variant (
463
+ pub ( crate ) fn const_eval_variant_recover (
467
464
_: & dyn HirDatabase ,
468
465
_: & [ String ] ,
469
466
_: & EnumVariantId ,
470
467
) -> Result < ComputedExpr , ConstEvalError > {
471
468
Err ( ConstEvalError :: Loop )
472
469
}
473
470
474
- pub ( crate ) fn const_eval_query (
471
+ pub ( crate ) fn const_eval_variant_query (
475
472
db : & dyn HirDatabase ,
476
473
const_id : ConstId ,
477
474
) -> Result < ComputedExpr , ConstEvalError > {
0 commit comments