diff --git a/App/lib/core/Gen/Call/CallGenCtor.vp b/App/lib/core/Gen/Call/CallGenCtor.vp index cbdc395..b04946c 100644 --- a/App/lib/core/Gen/Call/CallGenCtor.vp +++ b/App/lib/core/Gen/Call/CallGenCtor.vp @@ -847,35 +847,22 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): if k == ast.ASTKind.Call: cl_f: ast.Call* = ast.Call*(arg_node) if cl_f.func is not None: - if cl_f.func.kind() == ast.ASTKind.Name: - fn_nm: ast.Name* = ast.Name*(cl_f.func) - if fn_nm.id is not None: - # 与下方 Attribute 分支的 strstr 匹配一致:from t import CInt - # 后 `CInt(0)` 的 func 是 Name("CInt"),仅精确匹配 int/float - # 会漏判 → fail-fast 误杀(VectorGenericTest 隐式泛型推断)。 - if string.strcmp(fn_nm.id, "float") == 0 or string.strcmp(fn_nm.id, "double") == 0 or string.strstr(fn_nm.id, "Float") is not None or string.strstr(fn_nm.id, "Double") is not None: - return "double" - # char 内置类型(char(x) 或含 "Char" 的 t/c 类名:CChar/UChar 等) - # → "char",与 float/double 并列(此前归 int 组丢失 i8 语义) - if string.strcmp(fn_nm.id, "char") == 0 or string.strstr(fn_nm.id, "Char") is not None: - return "char" - if string.strcmp(fn_nm.id, "int") == 0 \ - or string.strstr(fn_nm.id, "Int") is not None or string.strstr(fn_nm.id, "UInt") is not None \ - or string.strstr(fn_nm.id, "Short") is not None \ - or string.strstr(fn_nm.id, "Long") is not None: - return "int" - elif cl_f.func.kind() == ast.ASTKind.Attribute: - fn_at: ast.Attribute* = ast.Attribute*(cl_f.func) - if fn_at.attr is not None: - if string.strstr(fn_at.attr, "Float") is not None or string.strstr(fn_at.attr, "Double") is not None: - return "double" - # char 内置类型(char(x) 等含 "Char" 的类名)→ "char" - if string.strstr(fn_at.attr, "Char") is not None: - return "char" - if string.strstr(fn_at.attr, "Int") is not None or string.strstr(fn_at.attr, "UInt") is not None or string.strstr(fn_at.attr, "Short") is not None or string.strstr(fn_at.attr, "Long") is not None: - return "int" - # 类型转换调用(Call)但函数名无法识别:明确的类型意图却无法解析, - # fail-fast(返回 None ⇒ 调用方 fail-fast)。 + # 只认「被调名本身可解析为**标量类型**」的转换调用:把被调表达式交给 + # 注解解析器解析,命中标量即据其**精确位宽**经 + # ClassGenGeneric.infer_scalar_type_arg_from_llvm_ty(唯一真源)映射。 + # 彻底移除原按名字子串猜测(含 Int→int 等):它把 CUInt64T/CInt16T + # 一律归成 int=i32(静默窄化/扩宽),CFloat32T 猜成 double。 + # 与泛型函数路径 ClassGenGeneric._infer_generic_func_type_arg 同口径。 + fk_c: int = cl_f.func.kind() + if (fk_c == ast.ASTKind.Name or fk_c == ast.ASTKind.Attribute) and trans is not None: + cty_c: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( + pool, cl_f.func, trans._imported_modules, trans._from_imports, trans, 0) + if cty_c is not None: + ta_c: str = self.Gen.ClassGenGeneric.infer_scalar_type_arg_from_llvm_ty(pool, cty_c) + if ta_c is not None: + return ta_c + # 类型转换调用(Call)但被调名无法解析为标量类型:明确的类型意图却无法 + # 解析,fail-fast(返回 None ⇒ 调用方 fail-fast)。 self.Gen.TypeGenErr.fatal_error(arg_node, f"无法从实参推断泛型类 '{class_name}' 的类型实参,请显式标注如 {class_name}[类型](...)", "TypeError") return None # 普通变量(Name)实参:取变量条目的注解类名(与形参定义/AnnAssign 经 diff --git a/App/lib/core/Gen/Class/ClassGenGeneric.vp b/App/lib/core/Gen/Class/ClassGenGeneric.vp index 593b2b6..3f05b17 100644 --- a/App/lib/core/Gen/Class/ClassGenGeneric.vp +++ b/App/lib/core/Gen/Class/ClassGenGeneric.vp @@ -407,9 +407,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): 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 self.infer_scalar_type_arg_from_llvm_ty(pool, cty_f) return None return None @@ -446,6 +444,23 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if string.strcmp(buf, "i32") == 0: return "int" return None + def infer_scalar_type_arg_from_llvm_ty(self, pool: memhub.MemBuddy*, + ty: llvmlite.LLVMType*) -> str: + """LLVM **标量**类型 → 泛型类型实参票名(精确位宽;非标量返回 None) + + 泛型函数(ClassGenGeneric._infer_generic_func_type_arg)与泛型类构造 + (CallGenCtor._infer_generic_ctor_type_arg)的 Call 实参推断共用,保证 + "转换调用实参 → 类型实参" 两处同口径(唯一真源 + _infer_scalar_type_name_from_spec)。非标量(结构体/指针/数组/函数)返回 + None ⇒ 调用方不据此推断(宁缺毋错,不按名字子串猜)。 + """ + if pool is None or ty is None: + return None + arena: TSpec.TypeSpecArena* = self.Gen.TypeGenBase.ensure_spec_arena() + if arena is None: + return None + return self._infer_scalar_type_name_from_spec(pool, TSpec.SpecFromLLVMType(arena, ty)) + def _clone_funcdef_for_spec(self, pool: memhub.MemBuddy*, fd: ast.FunctionDef*, spec_base: str,