fix(transpyv): 泛型实参里的「本模块裸类名」也加定义模块 SHA1,特化名不再分裂

类别:a(编译器缺陷 —— 同一类型在本模块与被引用模块得到两个特化名)

现场:includes/ast/stmts.vp:60
    _set_parent_list(targets, self)
CastError:非基本类型指针不可隐式转换
  源   %"7e2b6dda6e423bfb.list[rawptr[d1ed020479454541.AST]]"*
  目标 %"7e2b6dda6e423bfb.list[rawptr[AST]]"*
外层特化前缀相同,只有类型实参里的类名一个带 SHA1、一个裸名 ⇒ 同一个
list[rawptr[AST]] 变成两个结构体 ⇒ 被"非基本类型指针不能隐式转换"拦下。

根因:_norm_type_arg_name 的第 5 步只查 from_imports(可见性表);**本模块自己
声明的类**不在表内 ⇒ 落到第 6 步原样返回裸名,而被引用模块解析同一类型时第 5 步
命中(from-import 归属模块)带 SHA1 ⇒ 两侧对同一类型产出两个名字。

改动(_norm_type_arg_name 新增 5.5 步):
- 简单裸名(不含 '[' / '.')先经结构体表 find_struct(name) 取该类的
  **定义模块 SHA1**(StructEntry.ModuleSha1)加前缀 —— 与"当前模块"无关,
  故本模块内与跨模块得到同一票名;仅当登记项存在且 ModuleSha1 非 None 时生效。
- 文档串规则表同步补 5.5;第 6 步措辞改为"内置类型名等"。

与第 5 步同口径(都只处理简单裸名):泛型特化名 list[...] 与模块限定名
mod.Class 各有自己的分支,不在 5.5 重复加工。

注:TPC 侧同名规则源(SymbolUtils.ResolveTypeArgStr)是否需要同步,待该现场
回归通过后再核。
This commit is contained in:
TermiNexus committed 2026-09-29 18:31:52 +08:00
1 parent 8e7d7feb57
commit 65d7f7cc31
1 file changed
+26 -2
+26 -2
View File
@@ -278,7 +278,13 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
4. "mod.Class"(Attribute):mod 是 import 别名时先经 from_imports 反查
完整模块名 → SHA1;再尝试 mod 直接查 SHA1(无别名 import 的完整路径)
5. 裸名 "Class":经 from_imports 查所属模块 SHA1
6. 均查不到:返回原串(当前模块自身类 / 内置类型名,保持原样)
5.5 裸名 "Class" 是**本模块/已注册类**但不在 from_imports 里(典型:本模块
自己声明的类):经结构体表的登记项取其**定义模块 SHA1**(StructEntry.
ModuleSha1)加前缀。缺这一步会让同一类型"本模块内是裸名、被引用模块里
带前缀"分裂成两个特化名(现场:includes/ast/stmts.vp:60
`_set_parent_list(targets, self)`:源 %"…list[rawptr[d1ed020479454541.AST]]"*
vs 目标 %"…list[rawptr[AST]]"*,被"非基本类型指针不可隐式转换"拦下)
6. 仍查不到:返回原串(内置类型名等,保持原样)
返回 None 表示 type_name 为 None。
"""
@@ -484,7 +490,25 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
res_c: str = self._concat_sha1_class(pool, sha1c, type_name)
if res_c is not None:
return res_c
# ---- 6. 查不到:保持原样 ----
# ---- 5.5 裸名且是已注册类:加**定义模块 SHA1** 前缀 ----
# 规则 5 只查 from_imports(可见性表):**本模块自己声明的类**不在表内 ⇒
# 原样返回裸名 ⇒ 同一类型"本模块内是 list[rawptr[AST]]、被引用模块里是
# list[rawptr<定义模块SHA1>.AST]"⇒ 同一特化分裂成两个结构体名(现场:
# includes/ast/stmts.vp:60 `_set_parent_list(targets, self)` 源
# %"…list[rawptr[d1ed020479454541.AST]]"* vs 目标 %"…list[rawptr[AST]]"*,
# 被"非基本类型指针不可隐式转换"拦下)。取结构体表登记的定义模块 SHA1
# (与当前模块无关)⇒ 各模块得到同一票名。
# 仅处理**简单裸名**(不含 '[' / '.'):泛型特化名(list[...])与限定名
# 各有自己的分支,不在此重复加工。
if string.strchr(type_name, '[') is None and string.strchr(type_name, '.') is None:
_bare_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(type_name)
if _bare_entry is not None:
_def_sha1: str = _bare_entry.ModuleSha1
if _def_sha1 is not None:
res_d: str = self._concat_sha1_class(pool, _def_sha1, type_name)
if res_d is not None:
return res_d
# ---- 6. 查不到:保持原样(内置类型名等)----
return type_name
def _str_contains_ident(self, s: str, ident: str) -> int: