Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/consteval.rs')
| -rw-r--r-- | crates/hir-ty/src/consteval.rs | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index c3726905b6..0df2b39bbd 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -7,10 +7,11 @@ use hir_def::{ path::Path, resolver::{Resolver, ValueNs}, type_ref::ConstRef, - DefWithBodyId, EnumVariantId, + EnumVariantId, GeneralConstId, StaticId, }; use la_arena::{Idx, RawIdx}; use stdx::never; +use triomphe::Arc; use crate::{ 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) -> ) } -pub fn try_const_usize(c: &Const) -> Option<u128> { +pub fn try_const_usize(db: &dyn HirDatabase, c: &Const) -> Option<u128> { match &c.data(Interner).value { chalk_ir::ConstValue::BoundVar(_) => None, chalk_ir::ConstValue::InferenceVar(_) => None, chalk_ir::ConstValue::Placeholder(_) => None, chalk_ir::ConstValue::Concrete(c) => match &c.interned { ConstScalar::Bytes(x, _) => Some(u128::from_le_bytes(pad16(&x, false))), + ConstScalar::UnevaluatedConst(c, subst) => { + let ec = db.const_eval(*c, subst.clone()).ok()?; + try_const_usize(db, &ec) + } _ => None, }, } @@ -173,12 +178,20 @@ pub fn try_const_usize(c: &Const) -> Option<u128> { pub(crate) fn const_eval_recover( _: &dyn HirDatabase, _: &[String], - _: &DefWithBodyId, + _: &GeneralConstId, _: &Substitution, ) -> Result<Const, ConstEvalError> { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) } +pub(crate) fn const_eval_static_recover( + _: &dyn HirDatabase, + _: &[String], + _: &StaticId, +) -> Result<Const, ConstEvalError> { + Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) +} + pub(crate) fn const_eval_discriminant_recover( _: &dyn HirDatabase, _: &[String], @@ -189,11 +202,28 @@ pub(crate) fn const_eval_discriminant_recover( pub(crate) fn const_eval_query( db: &dyn HirDatabase, - def: DefWithBodyId, + def: GeneralConstId, subst: Substitution, ) -> Result<Const, ConstEvalError> { - let body = db.mir_body(def)?; - let c = interpret_mir(db, &body, subst, false)?; + let body = match def { + GeneralConstId::ConstId(c) => db.mir_body(c.into())?, + GeneralConstId::AnonymousConstId(c) => { + let (def, root) = db.lookup_intern_anonymous_const(c); + let body = db.body(def); + let infer = db.infer(def); + Arc::new(lower_to_mir(db, def, &body, &infer, root)?) + } + }; + let c = interpret_mir(db, &body, subst, false).0?; + Ok(c) +} + +pub(crate) fn const_eval_static_query( + db: &dyn HirDatabase, + def: StaticId, +) -> Result<Const, ConstEvalError> { + let body = db.mir_body(def.into())?; + let c = interpret_mir(db, &body, Substitution::empty(Interner), false).0?; Ok(c) } @@ -216,8 +246,8 @@ pub(crate) fn const_eval_discriminant_variant( return Ok(value); } let mir_body = db.mir_body(def)?; - let c = interpret_mir(db, &mir_body, Substitution::empty(Interner), false)?; - let c = try_const_usize(&c).unwrap() as i128; + let c = interpret_mir(db, &mir_body, Substitution::empty(Interner), false).0?; + let c = try_const_usize(db, &c).unwrap() as i128; Ok(c) } @@ -241,7 +271,7 @@ pub(crate) fn eval_to_const( } let infer = ctx.clone().resolve_all(); if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, &ctx.body, &infer, expr) { - if let Ok(result) = interpret_mir(db, &mir_body, Substitution::empty(Interner), true) { + if let Ok(result) = interpret_mir(db, &mir_body, Substitution::empty(Interner), true).0 { return result; } } |