fix(generic): 泛型函数 Call 实参推断改为精确类型解析,移除名字子串猜测

原实现按被调名子串猜类型实参(含 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。
This commit is contained in:
TermiNexus committed 2026-10-03 15:49:58 +08:00
1 parent e196d6a28a
commit 9a80f1df6c
1 file changed
+17 -17
+17 -17
View File
@@ -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