fix(call): 缺参 fail-fast 误杀参数匹配的构造调用 + 行号修复
- _call_method_on_ptr 的 elif found_func 分支原无条件 fatal,即使实参与形参匹配(如 JsonValue(pool) 构造 __new__(self, pool))也误报;改为数 found_func 形参数量,仅 total_count < fp_count 时缺参报错。 - 构造路径(_translate_struct_ctor/_translate_struct_ctor_kw)的 _call_method_on_ptr 调用补传诊断节点(取首个实参 AST),fatal_error 不再显示 line 0。
This commit is contained in:
1 parent
e796e7fc2b
commit
0c94f52f21
1 file changed
+28
-8
@@ -2023,6 +2023,11 @@ class CallGenMixin:
|
||||
tmp: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, struct_ty)
|
||||
if tmp is None:
|
||||
return llvmlite.ConstZero(pool, struct_ty)
|
||||
# 诊断节点:取第一个构造实参(有行号),供 _call_method_on_ptr 的
|
||||
# fatal_error 显示构造调用行号(本函数无 cl 参数,实参节点最接近调用点)
|
||||
diag_node_ct: ast.AST | t.CPtr = None
|
||||
if cargs is not None and len(cargs) > 0:
|
||||
diag_node_ct = cargs.get(0)
|
||||
|
||||
# 检查是否为 OOP 结构体(用类型指针定位 entry,规避跨模块同名 find_struct 找错)
|
||||
ctor_entry: HandlesStruct.StructEntry | t.CPtr = HandlesStruct.find_struct_by_type(struct_ty)
|
||||
@@ -2081,7 +2086,7 @@ class CallGenMixin:
|
||||
|
||||
new_ptr: llvmlite.Value | t.CPtr = self._call_method_on_ptr(
|
||||
pool, builder, mod, class_name,
|
||||
"__new__", tmp, new_arg_vals, new_arg_count, trans)
|
||||
"__new__", tmp, new_arg_vals, new_arg_count, trans, diag_node_ct)
|
||||
if new_ptr is not None:
|
||||
storage_ptr = new_ptr
|
||||
# __new__ 只保证返回"实例存储指针",声明类型通常是
|
||||
@@ -2099,7 +2104,7 @@ class CallGenMixin:
|
||||
|
||||
# OOP 结构体:调用 __before_init__ 进行零值填充和默认值赋值
|
||||
self._call_method_on_ptr(pool, builder, mod, class_name,
|
||||
"__before_init__", storage_ptr, None, 0, trans)
|
||||
"__before_init__", storage_ptr, None, 0, trans, diag_node_ct)
|
||||
|
||||
# 如果有 __init__,调用 __init__(ptr, args...)
|
||||
# 注意: 仅依据 ctor_entry.HasInit 判断,不强制推断
|
||||
@@ -2125,7 +2130,7 @@ class CallGenMixin:
|
||||
real_arg_count += 1
|
||||
|
||||
self._call_method_on_ptr(pool, builder, mod, class_name,
|
||||
"__init__", storage_ptr, arg_vals, real_arg_count, trans)
|
||||
"__init__", storage_ptr, arg_vals, real_arg_count, trans, diag_node_ct)
|
||||
elif has_new_flag == 0:
|
||||
# 无 __init__ 且无 __new__:逐字段 store 参数值
|
||||
# (有 __new__ 时参数已由 __new__ 消费,不应存入字段)
|
||||
@@ -2709,9 +2714,19 @@ class CallGenMixin:
|
||||
node, f"调用 '{lookup_name}' 缺少参数(无默认值)", "TypeError")
|
||||
mdf_pi += 1
|
||||
elif found_func is not None:
|
||||
# 无默认参数信息但有 found_func:剩余形参即调用缺参(无默认值),fail-fast
|
||||
HandlesType.fatal_error(
|
||||
node, f"调用 '{lookup_name}' 缺少参数(无默认值)", "TypeError")
|
||||
# 无函数表默认参数信息但有 found_func:数形参数量判断是否真的缺参。
|
||||
# 注意:不能无条件 fail-fast——mdf 缺失时 extra_count 可能正好等于
|
||||
# 形参数量(如 JsonValue(pool) 构造 __new__(self, pool)),
|
||||
# 参数匹配是合法调用,误报会阻断正常构造。
|
||||
fp_count: int = 0
|
||||
fpn_c: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
while fpn_c is not None:
|
||||
fp_count += 1
|
||||
fpn_c = llvmlite.param_get_next(fpn_c)
|
||||
if total_count < fp_count:
|
||||
# 调用实参(含 self)少于形参(含 self)且无默认值:缺参错误
|
||||
HandlesType.fatal_error(
|
||||
node, f"调用 '{lookup_name}' 缺少参数(无默认值)", "TypeError")
|
||||
|
||||
# 参数类型强制转换:按 found_func 的形参类型 coerce 每个实参(跳过 self/cls 参数 0)
|
||||
# 修复: 构造器调用 __init__(ptr, base, 4096) 时 size 形参是 i64 (t.CSizeT),
|
||||
@@ -4268,6 +4283,11 @@ class CallGenMixin:
|
||||
tmp: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, struct_ty)
|
||||
if tmp is None:
|
||||
return llvmlite.ConstZero(pool, struct_ty)
|
||||
# 诊断节点:取第一个构造实参(有行号),供 _call_method_on_ptr 的
|
||||
# fatal_error 显示构造调用行号(本函数无 cl 参数,实参节点最接近调用点)
|
||||
diag_node_ct: ast.AST | t.CPtr = None
|
||||
if cargs is not None and len(cargs) > 0:
|
||||
diag_node_ct = cargs.get(0)
|
||||
|
||||
# OOP 结构体:调用 __before_init__ 进行零值填充和默认值赋值
|
||||
# 用 find_struct_by_type 规避跨模块同名 find_struct 找错
|
||||
@@ -4356,7 +4376,7 @@ class CallGenMixin:
|
||||
new_arg_count += 1
|
||||
new_ptr: llvmlite.Value | t.CPtr = self._call_method_on_ptr(
|
||||
pool, builder, mod, class_name,
|
||||
"__new__", tmp, new_arg_vals, new_arg_count, trans)
|
||||
"__new__", tmp, new_arg_vals, new_arg_count, trans, diag_node_ct)
|
||||
if new_ptr is not None:
|
||||
storage_ptr = new_ptr
|
||||
# __new__ 只保证返回"实例存储指针",声明类型通常是
|
||||
@@ -4402,7 +4422,7 @@ class CallGenMixin:
|
||||
|
||||
# 调用 __init__(storage_ptr, *args)
|
||||
self._call_method_on_ptr(pool, builder, mod, class_name,
|
||||
"__init__", storage_ptr, init_arg_vals, init_arg_count, trans)
|
||||
"__init__", storage_ptr, init_arg_vals, init_arg_count, trans, diag_node_ct)
|
||||
|
||||
# 返回指针
|
||||
return storage_ptr
|
||||
|
||||
Reference in new issue
Block a user