diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index fcb3445a54..7e69971fee 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -15,7 +15,7 @@ use stdx::never; use crate::{ db::HirDatabase, infer::InferenceContext, layout::layout_of_ty, lower::ParamLoweringMode, to_placeholder_idx, utils::Generics, Const, ConstData, ConstScalar, ConstValue, GenericArg, - Interner, MemoryMap, Ty, TyBuilder, + Interner, MemoryMap, Substitution, Ty, TyBuilder, }; use super::mir::{interpret_mir, lower_to_mir, pad16, MirEvalError, MirLowerError}; @@ -169,6 +169,7 @@ pub(crate) fn const_eval_recover( _: &dyn HirDatabase, _: &[String], _: &ConstId, + _: &Substitution, ) -> Result { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) } @@ -184,10 +185,11 @@ pub(crate) fn const_eval_discriminant_recover( pub(crate) fn const_eval_query( db: &dyn HirDatabase, const_id: ConstId, + subst: Substitution, ) -> Result { let def = const_id.into(); let body = db.mir_body(def)?; - let c = interpret_mir(db, &body, false)?; + let c = interpret_mir(db, &body, subst, false)?; Ok(c) } @@ -210,7 +212,7 @@ pub(crate) fn const_eval_discriminant_variant( return Ok(value); } let mir_body = db.mir_body(def)?; - let c = interpret_mir(db, &mir_body, false)?; + let c = interpret_mir(db, &mir_body, Substitution::empty(Interner), false)?; let c = try_const_usize(&c).unwrap() as i128; Ok(c) } @@ -234,7 +236,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, true) { + if let Ok(result) = interpret_mir(db, &mir_body, Substitution::empty(Interner), true) { return result; } } diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs index 47ef26fc58..a0efc7541e 100644 --- a/crates/hir-ty/src/consteval/tests.rs +++ b/crates/hir-ty/src/consteval/tests.rs @@ -1,4 +1,5 @@ use base_db::fixture::WithFixture; +use chalk_ir::Substitution; use hir_def::db::DefDatabase; use crate::{ @@ -64,7 +65,7 @@ fn eval_goal(ra_fixture: &str) -> Result { _ => None, }) .unwrap(); - db.const_eval(const_id) + db.const_eval(const_id, Substitution::empty(Interner)) } #[test] @@ -1519,8 +1520,7 @@ fn const_generic_subst_fn() { #[test] fn const_generic_subst_assoc_const_impl() { - // FIXME: this should evaluate to 5 - check_fail( + check_number( r#" struct Adder; impl Adder { @@ -1528,7 +1528,7 @@ fn const_generic_subst_assoc_const_impl() { } const GOAL: usize = Adder::<2, 3>::VAL; "#, - ConstEvalError::MirEvalError(MirEvalError::TypeError("missing generic arg")), + 5, ); } diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index 8f1af4c2f8..000944e0b5 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -57,7 +57,7 @@ pub trait HirDatabase: DefDatabase + Upcast { #[salsa::invoke(crate::consteval::const_eval_query)] #[salsa::cycle(crate::consteval::const_eval_recover)] - fn const_eval(&self, def: ConstId) -> Result; + fn const_eval(&self, def: ConstId, subst: Substitution) -> Result; #[salsa::invoke(crate::consteval::const_eval_discriminant_variant)] #[salsa::cycle(crate::consteval::const_eval_discriminant_recover)] diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index d14b3f7140..d52188bb28 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -612,21 +612,6 @@ impl<'a> InferenceContext<'a> { let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); self.resolve_associated_type(inner_ty, self.resolve_future_future_output()) } - // Expr::Try { expr } => { - // let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); - // if let Some(trait_) = self.resolve_lang_trait(LangItem::Try) { - // if let Some(func) = self.db.trait_data(trait_).method_by_name(&name!(branch)) { - // let subst = TyBuilder::subst_for_def(self.db, trait_, None) - // .push(inner_ty.clone()) - // .build(); - // self.write_method_resolution(tgt_expr, func, subst.clone()); - // } - // let try_output = self.resolve_output_on(trait_); - // self.resolve_associated_type(inner_ty, try_output) - // } else { - // self.err_ty() - // } - // } Expr::Cast { expr, type_ref } => { let cast_ty = self.make_ty(type_ref); // FIXME: propagate the "castable to" expectation diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 26bf877cf0..7b83645fae 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -282,6 +282,7 @@ struct Locals<'a> { pub fn interpret_mir( db: &dyn HirDatabase, body: &MirBody, + subst: Substitution, // FIXME: This is workaround. Ideally, const generics should have a separate body (issue #7434), but now // they share their body with their parent, so in MIR lowering we have locals of the parent body, which // might have placeholders. With this argument, we (wrongly) assume that every placeholder type has @@ -291,11 +292,11 @@ pub fn interpret_mir( ) -> Result { let ty = body.locals[return_slot()].ty.clone(); let mut evaluator = Evaluator::new(db, body, assert_placeholder_ty_is_unused); - let bytes = evaluator.interpret_mir_with_no_arg(&body)?; + let bytes = evaluator.interpret_mir(&body, None.into_iter(), subst.clone())?; let memory_map = evaluator.create_memory_map( &bytes, &ty, - &Locals { ptr: &ArenaMap::new(), body: &body, subst: &Substitution::empty(Interner) }, + &Locals { ptr: &ArenaMap::new(), body: &body, subst: &subst }, )?; return Ok(intern_const_scalar(ConstScalar::Bytes(bytes, memory_map), ty)); } diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 65e3348b21..1821796be3 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -231,13 +231,13 @@ impl MirLowerCtx<'_> { let pr = match pr { ResolveValueResult::ValueNs(v) => v, ResolveValueResult::Partial(..) => { - if let Some(assoc) = self + if let Some((assoc, subst)) = self .infer .assoc_resolutions_for_expr(expr_id) { - match assoc.0 { + match assoc { hir_def::AssocItemId::ConstId(c) => { - self.lower_const(c, current, place, expr_id.into())?; + self.lower_const(c, current, place, subst, expr_id.into())?; return Ok(Some(current)) }, hir_def::AssocItemId::FunctionId(_) => { @@ -274,7 +274,7 @@ impl MirLowerCtx<'_> { Ok(Some(current)) } ValueNs::ConstId(const_id) => { - self.lower_const(const_id, current, place, expr_id.into())?; + self.lower_const(const_id, current, place, Substitution::empty(Interner), expr_id.into())?; Ok(Some(current)) } ValueNs::EnumVariantId(variant_id) => { @@ -951,9 +951,10 @@ impl MirLowerCtx<'_> { const_id: hir_def::ConstId, prev_block: BasicBlockId, place: Place, + subst: Substitution, span: MirSpan, ) -> Result<()> { - let c = self.db.const_eval(const_id)?; + let c = self.db.const_eval(const_id, subst)?; self.write_const_to_place(c, prev_block, place, span) } diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 35424feec8..dbf618afa6 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1801,7 +1801,7 @@ impl Function { let body = db .mir_body(self.id.into()) .map_err(|e| MirEvalError::MirLowerError(self.id.into(), e))?; - interpret_mir(db, &body, false)?; + interpret_mir(db, &body, Substitution::empty(Interner), false)?; Ok(()) } } @@ -1947,7 +1947,7 @@ impl Const { } pub fn render_eval(self, db: &dyn HirDatabase) -> Result { - let c = db.const_eval(self.id)?; + let c = db.const_eval(self.id, Substitution::empty(Interner))?; let r = format!("{}", HexifiedConst(c).display(db)); // We want to see things like `` and `` as they are probably bug in our // implementation, but there is no need to show things like `` or `` to