feat(gen): 同名全局 + 注解冲突优先报重复定义
- translate_annassign: 函数内(无 global/nonlocal、非模块级)再次注解同名变量时,若注解类型与模块级变量类型内容不一致 ⇒ TypeError 重复定义 fail-fast,不再延后到 RHS 的 coerce_to_type 报无关的「指针隐式转整数」(PointerTest/App/main.vp:46 _g_ptr: int = None,全局已是 t.CUInt32T | t.CPtr) - 注解与全局一致时仍按 Python 语义遮蔽为独立局部变量(既有行为不变) - 该检查走 _stg_ty_equal 内容比较(TypePrint),非地址比较,避免 Int32()/Ptr() 新实例造成误判
This commit is contained in:
1 parent
f0309e4904
commit
78fc7313fb
1 file changed
+30
@@ -2127,6 +2127,36 @@ novirtual class AssignGenMixin:
|
||||
f"AnnAssign 缺少类型注解,变量名: {nm.id}",
|
||||
"SyntaxError")
|
||||
|
||||
# 重复定义检测(优先于一切下游转换,fail-fast):
|
||||
# 模块级已有同名变量,而当前作用域既无 global/nonlocal 声明(有则被下方
|
||||
# global/nonlocal 分支接管)、又不在模块级(模块级由 handle_module_level_var
|
||||
# 登记,本就不构成"重复"),此处却用**与全局不一致的注解**再次声明同名变量
|
||||
# ⇒ 报重复定义。若无此检查,会先建局部 alloca 再由 RHS 走 coerce_to_type,
|
||||
# 把根因暴露成无关的 CastError(如 PointerTest/App/main.vp:46
|
||||
# `_g_ptr: int = None`:全局已是 t.CUInt32T | t.CPtr,报"指针隐式转整数")。
|
||||
# 注解与全局**一致**时不报错:保持 Python 语义,遮蔽为独立局部变量
|
||||
# (如全局 `_g_val: t.CInt` 与局部 `_g_val: int` 解析后同为 i32)。
|
||||
if nm.id is not None and trans is not None and var_ty is not None \
|
||||
and GenApi.is_global_name(trans, nm.id) == 0 \
|
||||
and GenApi.is_nonlocal_name(trans, nm.id) == 0 \
|
||||
and self.Gen.VarGen.is_module_scope(trans.SymTab) == 0:
|
||||
dup_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id)
|
||||
if dup_alloca is not None and dup_alloca.Ty is not None:
|
||||
dup_g_ty: llvmlite.LLVMType* = dup_alloca.Ty.Pointee
|
||||
if dup_g_ty is not None and self._stg_ty_equal(pool, dup_g_ty, var_ty) == 0:
|
||||
# 类型内容不等(_stg_ty_equal 走 TypePrint 内容比较,非地址比较:
|
||||
# llvmlite 的 Int32()/Ptr() 每次构造都是新实例)。
|
||||
dup_g_buf: str = pool.alloc(256)
|
||||
dup_l_buf: str = pool.alloc(256)
|
||||
if dup_g_buf is not None and dup_l_buf is not None:
|
||||
llvmlite.TypePrint(dup_g_buf, 256, dup_g_ty, pool)
|
||||
llvmlite.TypePrint(dup_l_buf, 256, var_ty, pool)
|
||||
self.Gen.TypeGenErr.fatal_error(aa,
|
||||
f"重复定义:'{nm.id}' 已是模块级变量(类型 {dup_g_buf}),"
|
||||
f"此处又注解为 {dup_l_buf}。函数内同名注解必须与全局一致;"
|
||||
f"如需独立局部变量请换名,如需修改全局请在函数内加 global 声明",
|
||||
"TypeError")
|
||||
|
||||
# t.Callable 函数指针:注册返回类型签名(供函数指针间接调用精确返回类型)
|
||||
callable_ret: llvmlite.LLVMType* = self.Gen.TypeGenErr.try_extract_callable_ret(pool, annot, trans._imported_modules, trans._from_imports, trans)
|
||||
if callable_ret is not None:
|
||||
|
||||
Reference in new issue
Block a user