fix(transpyv): vpi 注入期登记「本模块声明的类」,裸类名实参不再冻结成裸名

类别 a(编译器缺陷):_norm_type_arg_name 规则 5.5 的入口闸门是
`_def_sha1 is None and _def_mod is not None`(_def_mod = CurDefModuleSha1),而
VpiReader._inject_class_struct_declare 是在**注入期**解析字段注解的——此刻既没有
"类定义窗口"(CurDefModuleSha1=None ⇒ 闸门整条关闭、四条证据一条都不查),被注入的类
也尚未 register_struct ⇒ 注解里的裸类名实参取不到定义模块 SHA1 ⇒ 特化名被冻结成
**裸名版本**,与该类在自身翻译期(类已注册)解析出的带前缀形式分裂成两个特化名,
最终以"非基本类型指针不可隐式转换"报出。现场:includes/ast/base.vp:359
  _append_child(self.children, node, self.pool)
  源 %"…list[rawptr[AST]]"* vs 目标 %"…list[rawptr<定义模块SHA1>.AST]"*
这也解释了前两轮修复为何无效:③(自引用判据)依赖 CurDefClassName、④(entry.Ty 取
前缀)依赖 struct 条目,而注入期两者都不可用,且此时连日志条件(entry 命中)都不成立。

- GenApi:新增 mark_module_class 委托(与 add_visible_struct / find_struct_by_module 同款)。
- VpiReader._inject_class_struct_declare:在解析字段注解之前调用
  GenApi.mark_module_class(pool, src_sha1, cls_name) —— 一次调用同时完成
  ① 登记"{src_sha1}.{cls_name}"(名字归属,与 struct 注册状态无关);
  ② 把 CurDefModuleSha1/CurDefClassName 指向本次注入的模块与类(打开规则 5.5 的闸门)。
This commit is contained in:
TermiNexus committed 2026-09-29 22:29:48 +08:00
1 parent df1244d6f4
commit 31f341cf6f
2 files changed
+24

No files matched your search

+14
View File
@@ -2643,6 +2643,20 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
# 该行为显式化,避免将来 REnum 带直接字段时被误注册为普通 struct。
if _vpi_class_is_renum(class_cd) != 0:
return 0
# 规则 5.5 的证据前置(**必须早于**下方字段注解解析):
# 本函数在**注入期**解析字段注解(GenApi.resolve_annotation_type →
# _norm_type_arg_name),此刻被注入的类尚未 register_struct,且注入期**没有
# "类定义窗口"**(CurDefModuleSha1=None)⇒ 规则 5.5 的入口闸门
# (`_def_sha1 is None and _def_mod is not None`)整条关闭、四条证据一条都查不到
# ⇒ 注解里的裸类名实参取不到定义模块 SHA1(如 `children: list[rawptr[AST]]`
# 里的 AST)⇒ 特化名被冻结成**裸名版本**,与该类在自身翻译期(类已注册)解析出的
# 带前缀形式分裂成两个特化名,最终以"非基本类型指针不可隐式转换"报出。现场:
# includes/ast/base.vp:359 `_append_child(self.children, node, self.pool)`
# 源 %"…list[rawptr[AST]]"* vs 目标 %"…list[rawptr<定义模块SHA1>.AST]"*。
# mark_module_class 一次调用同时完成两件事:
# ① 登记"{src_sha1}.{cls_name}"(名字归属,与 struct 注册状态无关);
# ② 把 CurDefModuleSha1/CurDefClassName 指向本次注入的模块与类(规则 5.5 的闸门)。
GenApi.mark_module_class(pool, src_sha1, cls_name)
# 2. 收集字段类型(AnnAssign 子节点,仿 ClassGenDef.translate_class_def)
field_names_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX)
field_types_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX)