fix(tpc): 收紧「类身份」判据 + REnum 变体载荷解析失败不再被吞

承接 02d89b09:上一版判据"BaseType 是 CVoid ⇒ 类型信息丢失"**误伤 REnum** ——
REnum 类型条目本身 `BaseType=None`,`T | t.CPtr` 合并时 `_MergeAllComponentTypes`
末尾会把空 BaseType 默认填成 CVoid,但 IsRenum/IsStruct/Name 齐备,`_ctype_to_llvm`
仍能解析出 `%<sha1>.T*`。于是合法注解 `Pointee: rawptr[LLVMType]`(REnum 变体载荷)
被打成致命错误,异常又在此处被上层吞掉 ⇒ 变体只剩 __tag。

两处修正:
1) HandlesBase._CheckPtrAnnotationKeepsClass:判据收紧为「BaseType 是 CVoid **且
   没有任何类身份**(IsStruct / IsRenum / IsEnum / Name 全空)」才失败。
2) HandlesImports REnum 变体载荷注册:历史上 `CollectAnnAssignMember` 的异常被上层
   吞掉、`parsed` 为 None 时静默跳过 ⇒ class_members 只剩 __tag、变体循环中断
   (现场同前缀 structs 键只有 LLVMType_Int / LLVMType_Ptr,源顺序其后还有
   Func/Array/Struct/…),进而使变体构造丢载荷、match 捕获绑不上。现改为:
   - 只把 AnnAssign 当载荷声明(pass / docstring 合法跳过,如 `class Void: pass`);
   - 解析抛异常 ⇒ fail-fast 并带上原异常(拒绝留下只有 __tag 的成员表);
   - 解析返回 None ⇒ 同样 fail-fast。
This commit is contained in:
TermiNexus committed 2026-09-29 11:24:57 +08:00
1 parent 53bde9157e
commit dab0823f5c
2 files changed
+37 -6

No files matched your search

+9 -1
View File
@@ -1099,13 +1099,21 @@ class BaseHandle:
只拦"必属类型信息丢失"的组合:内层节点(Name / Attribute)的名字在
`Gen.structs`(本模块已建)或 `Gen._struct_sha1_map`(预扫描的类→模块映射)
中有类定义,而解析出的 `BaseType` 却是 `t.CVoid`。其余一律放行
中有类定义,而解析出的 `BaseType` 是 `t.CVoid` **且没有任何类身份**
(IsStruct / IsRenum / IsEnum / Name 全空)。其余一律放行
(`rawptr[rawptr]` 这类本就 void 基座的多层指针、模块名、泛型特化实参等)。
"""
if Info is None or Info.BaseType is None:
return
if not (Info.BaseType is t.CVoid or isinstance(Info.BaseType, t.CVoid)):
return
# 只要还带着任何"类身份"(IsStruct / IsRenum / IsEnum / Name),就不是信息丢失:
# REnum 类型条目本身 BaseType=None,`T | t.CPtr` 合并后会被默认填成 CVoid,但
# IsRenum/IsStruct/Name 齐备,_ctype_to_llvm 仍能解析出 %<sha1>.T* —— 误判会
# 把合法注解(如 REnum 变体载荷 `Pointee: rawptr[LLVMType]`)打成致命错误。
if (getattr(Info, 'IsStruct', False) or getattr(Info, 'IsRenum', False)
or getattr(Info, 'IsEnum', False) or getattr(Info, 'Name', None)):
return
Inner: ast.AST | None = None
if isinstance(Annotation, ast.Subscript) and IsPtrSubscriptNode(Annotation, self.Trans.SymbolTable):
Inner = Annotation.slice
+28 -5
View File
@@ -1882,11 +1882,34 @@ class ImportHandle(BaseHandle):
Gen.class_members[NestedStructName].append(('__tag', ir.IntType(32)))
Gen.class_member_signeds[NestedStructName]['__tag'] = None
for nested_item in item.body:
parsed = self.CollectAnnAssignMember(nested_item, Gen)
if parsed:
MName, MType, MTypeInfo = parsed
Gen.class_members[NestedStructName].append((MName, MType))
Gen.class_member_signeds[NestedStructName][MName] = None
# 只把 AnnAssign 当载荷声明;变体体里的 pass / docstring 等
# 非声明语句合法跳过(如 `class Void: pass`)。
if not isinstance(nested_item, ast.AnnAssign):
continue
_member_txt: str = ast.unparse(nested_item)
try:
parsed = self.CollectAnnAssignMember(nested_item, Gen)
except Exception as _pe:
# 历史上此处异常被上层吞掉 ⇒ 变体只剩 __tag ⇒ 变体构造静默
# 丢载荷、match 模式捕获绑不上(现场 LLVMType_Ptr / pointee_cs),
# 且循环中断使后续变体(Func/Array/...)整批缺失。改为响亮失败。
from lib.core.LLVMCG.FuncGen import FailFastError as _FFE
raise _FFE(
f"REnum 变体 '{ClassName}.{VariantName}' 的载荷成员 "
f"'{_member_txt}' 解析失败:{type(_pe).__name__}: {_pe} "
f"—— 拒绝留下只有 __tag 的 class_members"
f"(会导致变体构造丢载荷、match 捕获绑定缺失、后续变体整批缺失)"
) from _pe
if not parsed:
from lib.core.LLVMCG.FuncGen import FailFastError as _FFE
raise _FFE(
f"REnum 变体 '{ClassName}.{VariantName}' 的载荷成员 "
f"'{_member_txt}' 未解析出类型(CollectAnnAssignMember 返回 None)"
f"—— 同上,拒绝静默降级为无载荷"
)
MName, MType, MTypeInfo = parsed
Gen.class_members[NestedStructName].append((MName, MType))
Gen.class_member_signeds[NestedStructName][MName] = None
# 当 stub 中没有嵌套变体结构体定义时(_TryLoadStructFromStub 失败),
# 使用主 REnum 结构体的 body (max_variant_struct) 创建嵌套变体结构体,
# 确保跨模块布局一致。否则 _generate_structs() Step 4 会从 class_members