From 9a80f1df6c52159a8caa3d1148ee94151f2ca81c Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 3 Oct 2026 15:49:58 +0800 Subject: [PATCH] =?UTF-8?q?fix(generic):=20=E6=B3=9B=E5=9E=8B=E5=87=BD?= =?UTF-8?q?=E6=95=B0=20Call=20=E5=AE=9E=E5=8F=82=E6=8E=A8=E6=96=AD?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E7=B2=BE=E7=A1=AE=E7=B1=BB=E5=9E=8B=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=EF=BC=8C=E7=A7=BB=E9=99=A4=E5=90=8D=E5=AD=97=E5=AD=90?= =?UTF-8?q?=E4=B8=B2=E7=8C=9C=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原实现按被调名子串猜类型实参(含 Int→int、Float→double 等),把 CUInt64T/CInt16T 一律归成 int=i32,静默窄化/扩宽位宽(禁止静默默认原则);CFloat32T 也会被猜成 double。 改为:把被调表达式本身交给注解解析器 resolve_annotation_type,命中**标量**才据其精确位宽经 _infer_scalar_type_name_from_spec(唯一真源)映射;非标量(构造/普通函数调用)或不可解析一律返回 None,由调用方汇总后 fail-fast 提示显式标注。行为变化:CUInt64T(x)/CInt16T(x) 等无等位宽裸名的转换实参不再被静默猜成 int。 --- App/lib/core/Gen/Class/ClassGenGeneric.vp | 34 +++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/App/lib/core/Gen/Class/ClassGenGeneric.vp b/App/lib/core/Gen/Class/ClassGenGeneric.vp index c9881df..593b2b6 100644 --- a/App/lib/core/Gen/Class/ClassGenGeneric.vp +++ b/App/lib/core/Gen/Class/ClassGenGeneric.vp @@ -393,23 +393,23 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if k == ast.ASTKind.Call: cl_f: ast.Call* = ast.Call*(arg_node) if cl_f.func is not None: - fn_id: str = None - if cl_f.func.kind() == ast.ASTKind.Name: - fn_nm: ast.Name* = ast.Name*(cl_f.func) - fn_id = fn_nm.id - elif cl_f.func.kind() == ast.ASTKind.Attribute: - fn_at: ast.Attribute* = ast.Attribute*(cl_f.func) - fn_id = fn_at.attr - if fn_id is not None: - if string.strcmp(fn_id, "float") == 0 or string.strcmp(fn_id, "double") == 0 \ - or string.strstr(fn_id, "Float") is not None or string.strstr(fn_id, "Double") is not None: - return "double" - if string.strcmp(fn_id, "char") == 0 or string.strstr(fn_id, "Char") is not None: - return "char" - if string.strcmp(fn_id, "int") == 0 or string.strstr(fn_id, "Int") is not None \ - or string.strstr(fn_id, "UInt") is not None or string.strstr(fn_id, "Short") is not None \ - or string.strstr(fn_id, "Long") is not None: - return "int" + fk_f: int = cl_f.func.kind() + # 只认「被调名本身可解析为**标量类型**」的转换调用(int(x) / + # t.CDouble(x) / CUInt64T(x) 等):用注解解析器解析被调表达式, + # 命中标量即按**精确位宽**映射(复用 _infer_scalar_type_name_from_spec + # 这一唯一真源);非标量(构造调用/普通函数调用)或不可解析一律 + # None,交由调用方汇总后 fail-fast。 + # 彻底移除原来的**名字子串猜测**(含 "Int" → int 等):它把 + # CUInt64T/CInt16T 一律归成 int=i32,静默窄化/扩宽位宽 + # (现场:GenericOopTest `fxi2(a, b, CUInt64T(178900))` 的 T3=u64 + # 被猜成 i32)。此处不做兜底猜测,宁缺毋错。 + if (fk_f == ast.ASTKind.Name or fk_f == ast.ASTKind.Attribute) and trans is not None: + cty_f: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( + pool, cl_f.func, trans._imported_modules, trans._from_imports, trans, 0) + if cty_f is not None: + arena_c: TSpec.TypeSpecArena* = self.Gen.TypeGenBase.ensure_spec_arena() + if arena_c is not None: + return self._infer_scalar_type_name_from_spec(pool, TSpec.SpecFromLLVMType(arena_c, cty_f)) return None return None