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 | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index 0348680e5d..9792d945eb 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -1,9 +1,10 @@ //! Constant evaluation details -use base_db::CrateId; +use base_db::{salsa::Cycle, CrateId}; use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex}; use hir_def::{ - hir::Expr, + body::Body, + hir::{Expr, ExprId}, path::Path, resolver::{Resolver, ValueNs}, type_ref::LiteralConstRef, @@ -136,7 +137,7 @@ pub fn intern_const_ref( ty: Ty, krate: CrateId, ) -> Const { - let layout = db.layout_of_ty(ty.clone(), Arc::new(TraitEnvironment::empty(krate))); + let layout = db.layout_of_ty(ty.clone(), TraitEnvironment::empty(krate)); let bytes = match value { LiteralConstRef::Int(i) => { // FIXME: We should handle failure of layout better. @@ -184,7 +185,7 @@ pub fn try_const_usize(db: &dyn HirDatabase, c: &Const) -> Option<u128> { pub(crate) fn const_eval_recover( _: &dyn HirDatabase, - _: &[String], + _: &Cycle, _: &GeneralConstId, _: &Substitution, _: &Option<Arc<TraitEnvironment>>, @@ -194,7 +195,7 @@ pub(crate) fn const_eval_recover( pub(crate) fn const_eval_static_recover( _: &dyn HirDatabase, - _: &[String], + _: &Cycle, _: &StaticId, ) -> Result<Const, ConstEvalError> { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) @@ -202,7 +203,7 @@ pub(crate) fn const_eval_static_recover( pub(crate) fn const_eval_discriminant_recover( _: &dyn HirDatabase, - _: &[String], + _: &Cycle, _: &EnumVariantId, ) -> Result<i128, ConstEvalError> { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) @@ -280,7 +281,7 @@ pub(crate) fn const_eval_discriminant_variant( // get an `InferenceResult` instead of an `InferenceContext`. And we should remove `ctx.clone().resolve_all()` here // and make this function private. See the fixme comment on `InferenceContext::resolve_all`. pub(crate) fn eval_to_const( - expr: Idx<Expr>, + expr: ExprId, mode: ParamLoweringMode, ctx: &mut InferenceContext<'_>, args: impl FnOnce() -> Generics, @@ -288,13 +289,24 @@ pub(crate) fn eval_to_const( ) -> Const { let db = ctx.db; let infer = ctx.clone().resolve_all(); + fn has_closure(body: &Body, expr: ExprId) -> bool { + if matches!(body[expr], Expr::Closure { .. }) { + return true; + } + let mut r = false; + body[expr].walk_child_exprs(|idx| r |= has_closure(body, idx)); + r + } + if has_closure(&ctx.body, expr) { + // Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic. + return unknown_const(infer[expr].clone()); + } if let Expr::Path(p) = &ctx.body.exprs[expr] { let resolver = &ctx.resolver; if let Some(c) = path_to_const(db, resolver, p, mode, args, debruijn, infer[expr].clone()) { return c; } } - 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, Arc::new(mir_body), true, None).0 { return result; |