@@ -153,7 +153,7 @@ fn is_valid(scalar: &Scalar, value: i128) -> bool {
153153 }
154154}
155155
156- fn get_name ( variant : EnumVariantId , ctx : & mut ConstEvalCtx < ' _ > ) -> String {
156+ fn get_name ( ctx : & mut ConstEvalCtx < ' _ > , variant : EnumVariantId ) -> String {
157157 let loc = variant. parent . lookup ( ctx. db . upcast ( ) ) ;
158158 let children = variant. parent . child_source ( ctx. db . upcast ( ) ) ;
159159 let item_tree = loc. id . item_tree ( ctx. db . upcast ( ) ) ;
@@ -167,20 +167,24 @@ pub fn eval_const(
167167 expr_id : ExprId ,
168168 ctx : & mut ConstEvalCtx < ' _ > ,
169169) -> 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+
170174 let expr = & ctx. exprs [ expr_id] ;
171175 match expr {
172176 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
173179 DefWithBodyId :: VariantId ( variant) => {
174180 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 ) ;
176182 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 } ;
179185 1 + match ctx. db . const_eval_variant ( prev_variant) ? {
180186 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) ?,
184188 _ => {
185189 return Err ( ConstEvalError :: NotSupported (
186190 "Enum can't contain this kind of value" ,
@@ -206,9 +210,7 @@ pub fn eval_const(
206210 return Ok ( ComputedExpr :: Literal ( Literal :: Bool ( !b) ) )
207211 }
208212 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) ?,
212214 _ => return Err ( ConstEvalError :: NotSupported ( "this kind of operator" ) ) ,
213215 } ;
214216 let r = match ty. kind ( Interner ) {
@@ -237,9 +239,7 @@ pub fn eval_const(
237239 hir_def:: expr:: UnaryOp :: Neg => {
238240 let v = match ev {
239241 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) ?,
243243 _ => return Err ( ConstEvalError :: NotSupported ( "this kind of operator" ) ) ,
244244 } ;
245245 Ok ( ComputedExpr :: Literal ( Literal :: Int (
@@ -258,16 +258,12 @@ pub fn eval_const(
258258 let op = op. ok_or ( ConstEvalError :: IncompleteExpr ) ?;
259259 let v1 = match lhs {
260260 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) ?,
264262 _ => return Err ( ConstEvalError :: NotSupported ( "this kind of operator" ) ) ,
265263 } ;
266264 let v2 = match rhs {
267265 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) ?,
271267 _ => return Err ( ConstEvalError :: NotSupported ( "this kind of operator" ) ) ,
272268 } ;
273269 match op {
@@ -380,7 +376,7 @@ pub fn eval_const(
380376 }
381377 ValueNs :: EnumVariantId ( id) => match ctx. db . const_eval_variant ( id) ? {
382378 ComputedExpr :: Literal ( lit) => {
383- Ok ( ComputedExpr :: Enum ( get_name ( id , ctx ) , id, lit) )
379+ Ok ( ComputedExpr :: Enum ( get_name ( ctx , id ) , id, lit) )
384380 }
385381 _ => Err ( ConstEvalError :: NotSupported (
386382 "Enums can't evalute to anything but numbers" ,
@@ -389,6 +385,7 @@ pub fn eval_const(
389385 _ => Err ( ConstEvalError :: NotSupported ( "path that are not const or local" ) ) ,
390386 }
391387 }
388+ // FIXME: Handle the cast target
392389 & Expr :: Cast { expr, .. } => match eval_const ( expr, ctx) ? {
393390 ComputedExpr :: Enum ( _, _, lit) => Ok ( ComputedExpr :: Literal ( lit) ) ,
394391 _ => Err ( ConstEvalError :: NotSupported ( "Can't cast these types" ) ) ,
@@ -463,15 +460,15 @@ pub(crate) fn const_eval_recover(
463460 Err ( ConstEvalError :: Loop )
464461}
465462
466- pub ( crate ) fn const_eval_recover_variant (
463+ pub ( crate ) fn const_eval_variant_recover (
467464 _: & dyn HirDatabase ,
468465 _: & [ String ] ,
469466 _: & EnumVariantId ,
470467) -> Result < ComputedExpr , ConstEvalError > {
471468 Err ( ConstEvalError :: Loop )
472469}
473470
474- pub ( crate ) fn const_eval_query (
471+ pub ( crate ) fn const_eval_variant_query (
475472 db : & dyn HirDatabase ,
476473 const_id : ConstId ,
477474) -> Result < ComputedExpr , ConstEvalError > {
0 commit comments