fix(TypeGenResolve): rawptr[T] 下标形漏折叠致两个 list 特化体(修 _list.vp:83 return self 的 CastError)
前一版把 rawptr 从 _is_ptr_marker_text 移除(避免裸 rawptr 参与联合时名说 T*、类型说 T),但下标容器分支复用了同一判据 ⇒ rawptr[T] 完全没折叠,只有 T|t.CPtr 折叠:现场同时存在 list[<sha>.AST*] 与 list[rawptr[<sha>.AST]] 两个结构体,_list.vp:83 return self 的 self(前者)被 coerce 到返回注解(后者)时报 CastError。新增专用判据 _is_ptr_subscript_container_text(rawptr/t.rawptr/c.rawptr/CPtr 一族),下标分支改用它;联合分支仍用 _is_ptr_marker_text 保持与类型域 _is_cptr_marker 同口径。
This commit is contained in:
1 parent
b289e93650
commit
0f6e102e02
1 file changed
+37
-2
@@ -356,7 +356,8 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 刻意**只认 CPtr 一族**:类型域(resolve_annotation_type 的 BinOp 分支)
|
||||
# 判 CPtr 标记用的是 _is_cptr_marker,同样只认 `t.CPtr` / 裸 `CPtr`
|
||||
# ⇒ 名字域若额外把裸 `rawptr` 当标记,会出现"名字说 T*、类型说 T"的不一致。
|
||||
# `rawptr[T]`(下标形)不在此判据内,由 _norm_type_arg_name 的容器归一分支处理。
|
||||
# `rawptr[T]`(下标形)不在此判据内,由 _norm_type_arg_name 的容器归一分支
|
||||
# 用**专用判据** _is_ptr_subscript_container_text 处理。
|
||||
# ============================================================
|
||||
def _is_ptr_marker_text(self, txt: str) -> int:
|
||||
"""txt 是否为裸指针标记(只贡献一层指针),1=是 / 0=否"""
|
||||
@@ -367,6 +368,33 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if string.strcmp(txt, "c.CPtr") == 0: return 1
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
# _is_ptr_subscript_container_text - 文本是否为**指针下标容器名**
|
||||
# (rawptr / t.rawptr / c.rawptr / CPtr 一族)
|
||||
#
|
||||
# 与 _is_ptr_marker_text 刻意分开的两条判据(缺一不可):
|
||||
# · 联合写法 `X | <标记>` 只认 CPtr 一族(_is_ptr_marker_text):类型域
|
||||
# (resolve_annotation_type 的 BinOp 分支)判标记用 _is_cptr_marker,
|
||||
# 同样不认裸 `rawptr` ⇒ 名字域若多认会出现"名说 T*、类型说 T"。
|
||||
# · **下标写法** `rawptr[T]` / `t.rawptr[T]` 则必须认(本判据):类型域对
|
||||
# 下标形走 _ptr_subscript_absorbs_class,`rawptr[T]` ≡ `t.CPtr[T]` ≡ `T*`
|
||||
# 逐字等价。漏认的后果(现场):同名注解两种写法产出两个泛型特化体 ——
|
||||
# `_list.vp:83 return self` 报
|
||||
# 「源 %"….list[<sha>.AST*]"* → 目标 %"….list[rawptr[<sha>.AST]]"*」,
|
||||
# 原因之一是 `_clone_annotation` 会把已归一的 `T*` 经 _parse_type_string
|
||||
# 还原成 `rawptr[T]` 文本回注注解(另一路是源码直接写 rawptr[T])。
|
||||
# ============================================================
|
||||
def _is_ptr_subscript_container_text(self, txt: str) -> int:
|
||||
"""txt 是否为指针下标容器名(rawptr[T]/t.CPtr[T]/CPtr[T] 的容器位),1=是 / 0=否"""
|
||||
if txt is None:
|
||||
return 0
|
||||
if self._is_ptr_marker_text(txt) != 0:
|
||||
return 1
|
||||
if string.strcmp(txt, "rawptr") == 0: return 1
|
||||
if string.strcmp(txt, "t.rawptr") == 0: return 1
|
||||
if string.strcmp(txt, "c.rawptr") == 0: return 1
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
# _ptr_star_text - 把类型名文本追加一层指针(base + "*")
|
||||
#
|
||||
@@ -606,7 +634,14 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# `list[rawptr[<sha>.AST]]` 与 `list[<sha>.AST|t.CPtr]` 两个特化体
|
||||
# ⇒ 调用点被严格指针规则按"不同非基本类型"拒绝(现场
|
||||
# Test/AstTest/App/main.vp:63,假报错)。多实参(异常写法)不拦。
|
||||
if self._is_ptr_marker_text(container_g) != 0 and len(arg_list_g) == 1:
|
||||
# 【判据必须用**下标容器**判据(2026-09-30)】不能复用
|
||||
# _is_ptr_marker_text(它只认 CPtr 一族,用于联合写法):
|
||||
# 复用它会让 `rawptr[T]` 漏折叠 ⇒ 与 `T | t.CPtr` 折叠后的
|
||||
# `T*` 并存两个特化体(现场 _list.vp:83 return self 的
|
||||
# CastError:list[<sha>.AST*] ↔ list[rawptr[<sha>.AST]])。
|
||||
# 详见 _is_ptr_subscript_container_text 的头注释。
|
||||
if self._is_ptr_subscript_container_text(container_g) != 0 \
|
||||
and len(arg_list_g) == 1:
|
||||
_only_arg_g: str = arg_list_g.get(0)
|
||||
_star_cg: str = self._ptr_star_text(pool, _only_arg_g)
|
||||
if _star_cg is not None:
|
||||
|
||||
Reference in new issue
Block a user