From ea579863122d4e5a004b2458ca9066a2ffb20f7f Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 10 Oct 2026 10:44:07 +0800 Subject: [PATCH] =?UTF-8?q?fix(gen):=20lambda=20=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=8C=89=20body=20=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=BF=94=E5=9B=9E=E7=B1=BB=E5=9E=8B=EF=BC=88?= =?UTF-8?q?=E5=8E=9F=E5=85=88=E6=81=92=20i32=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit translate_lambda 第 4 步创建提升函数时只能先写 i32(body 尚未翻译);第 11 步原来把 body 值一律 coerce_to_type 到 i32,于是: - body 返回指针 → 撞 CastError(implicit pointer-to-integer conversion is forbidden); - body 返回浮点 → fptosi 成 i32(静默有损)。 现按 body 的实际类型修正 func.RetTy(mlirlite 公开字段;本步之后才发 ret,期间无人读 RetTy;调用点读到的已是修正后的签名): - 指针 → RetTy = body 类型,直接 ret(不再强转); - 浮点 → 同上(不再 fptosi); - 整数/其它 → 保持既有 i32 语义(与"无注解嵌套 def 保持 i32"同口径,避免改动既有行为)。 与嵌套 def 的返回类型缺口同类(见上一提交)。 --- App/lib/core/Gen/Func/FuncGenMixin.vp | 37 +++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/App/lib/core/Gen/Func/FuncGenMixin.vp b/App/lib/core/Gen/Func/FuncGenMixin.vp index 344125f..7f161f3 100644 --- a/App/lib/core/Gen/Func/FuncGenMixin.vp +++ b/App/lib/core/Gen/Func/FuncGenMixin.vp @@ -1034,19 +1034,36 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): mlirlite.build_store(func_builder, param_ref, arg_alloca) self.Gen.VarGen.define_var(trans.SymTab, param_names + pi3 * 32, arg_alloca) - # 11. Translate the body expression, coerce to i32 and return + # 11. Translate the body expression and return it. + # 返回类型:提升函数创建时(第 4 步)只能先写 i32——那时 body 还没翻译、拿不到类型。 + # 这里按 body 的**实际类型**修正 `func.RetTy`(mlirlite 公开字段;函数体只在本步发一条 ret, + # 期间没有任何人读 RetTy;调用点取签名时读到的已是修正后的类型)。 + # 修的是两类 i32 **无法表达**的情形(与嵌套 def 那条缺口同类): + # · 指针 → 原路径 coerce_to_type(ptr → i32) 直接 CastError(pointer→integer 禁止); + # · 浮点 → 原路径 fptosi 成 i32(静默有损)。 + # 整数/其它**保持既有 i32 语义**(与"无注解的嵌套 def 保持 i32"同口径,避免改动既有行为)。 body_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(func_builder, pool, mod, lam.body, None, 0, trans) - if body_val is not None and body_val.Ty is not None: - if self.Gen.ExprGenBase.get_llvm_type_bits(body_val.Ty) == 32 and self.Gen.ExprGenBase.is_ptr_type(body_val.Ty) == 0: mlirlite.build_ret(func_builder, body_val) - else: - ret_val: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(func_builder, body_val, i32_ty, lam.body) - if ret_val is not None: mlirlite.build_ret(func_builder, ret_val) - else: - # fail-fast: lambda body coercion failed; do not silently return 0 - self.Gen.TypeGenErr.fatal_error(lam.body, "lambda body expression translation failed", "TypeError") - else: + if body_val is None or body_val.Ty is None: # fail-fast: lambda body translation failed; do not silently return 0 self.Gen.TypeGenErr.fatal_error(lam.body, "lambda body expression translation failed", "TypeError") + else: + lam_ret_fixed: int = 0 + if self.Gen.ExprGenBase.is_ptr_type(body_val.Ty) != 0: + func.RetTy = body_val.Ty + mlirlite.build_ret(func_builder, body_val) + lam_ret_fixed = 1 + elif self.Gen.ExprGenBase.get_llvm_float_bits(body_val.Ty) != 0: + func.RetTy = body_val.Ty + mlirlite.build_ret(func_builder, body_val) + lam_ret_fixed = 1 + if lam_ret_fixed == 0: + if self.Gen.ExprGenBase.get_llvm_type_bits(body_val.Ty) == 32 and self.Gen.ExprGenBase.is_ptr_type(body_val.Ty) == 0: mlirlite.build_ret(func_builder, body_val) + else: + ret_val: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(func_builder, body_val, i32_ty, lam.body) + if ret_val is not None: mlirlite.build_ret(func_builder, ret_val) + else: + # fail-fast: lambda body coercion failed; do not silently return 0 + self.Gen.TypeGenErr.fatal_error(lam.body, "lambda body expression translation failed", "TypeError") # 12. Leave the lambda scope and restore the parent state self.Gen.VarGen.exit_scope(trans.SymTab)