diff --git a/App/lib/core/Gen/Class/ClassGenEnum.vp b/App/lib/core/Gen/Class/ClassGenEnum.vp index 0bd8050..eb438f0 100644 --- a/App/lib/core/Gen/Class/ClassGenEnum.vp +++ b/App/lib/core/Gen/Class/ClassGenEnum.vp @@ -49,7 +49,10 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if k == ast.ASTKind.Attribute: at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(ann_node) if at.attr is None: - return llvmlite.Int32(pool) + # [S4 fail-fast] Attribute 缺失成员名(AST 损坏),不再静默回退 i32 + self.Gen.TypeGenErr.fatal_error( + ann_node, "枚举成员类型注解 Attribute 缺失成员名", "TypeError") + return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) # t.State → 默认 i32 if string.strcmp(at.attr, "State") == 0: return llvmlite.Int32(pool) @@ -58,20 +61,29 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): pool, at.attr, imported_modules, from_imports) if ty is not None: return ty - return llvmlite.Int32(pool) + # [S4 fail-fast] 有注解但解析失败 → 不再静默回退 i32 + self.Gen.TypeGenErr.fatal_error( + ann_node, f"枚举成员类型注解解析失败: t.{at.attr}", "NameError") + return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) # Name 节点: from-import 形式(State / CInt) if k == ast.ASTKind.Name: nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(ann_node) if nm.id is None: - return llvmlite.Int32(pool) + # [S4 fail-fast] Name 缺失标识符(AST 损坏),不再静默回退 i32 + self.Gen.TypeGenErr.fatal_error( + ann_node, "枚举成员类型注解 Name 缺失标识符", "TypeError") + return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) if string.strcmp(nm.id, "State") == 0: return llvmlite.Int32(pool) ty2: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_typedef_or_map( pool, nm.id, imported_modules, from_imports) if ty2 is not None: return ty2 - return llvmlite.Int32(pool) + # [S4 fail-fast] 有注解但解析失败 → 不再静默回退 i32 + self.Gen.TypeGenErr.fatal_error( + ann_node, f"枚举成员类型注解解析失败: {nm.id}", "NameError") + return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) # BinOp 节点: t.State | int8(递归查找实际类型) if k == ast.ASTKind.BinOp: diff --git a/App/lib/core/Gen/Class/ClassGenVTable.vp b/App/lib/core/Gen/Class/ClassGenVTable.vp index 454fa46..14b9c1d 100644 --- a/App/lib/core/Gen/Class/ClassGenVTable.vp +++ b/App/lib/core/Gen/Class/ClassGenVTable.vp @@ -674,8 +674,19 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type( pool, fd.returns, imported_modules, from_imports, trans, 0) if ret_ty is None and fd.returns is not None: - if self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State", 0) != 0: + # 存储类标记(t.State / t.CExport / t.CExtern)语义为 Void:这类注解 + # 不携带真实返回类型(extern/export 语法写成 "<原类型> | t.<标记>", + # 原类型已解析成功时不会走到这里,此处只处理标记本身/解析后仍为 None)。 + if self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State", 0) != 0 \ + or self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "CExport", 0) != 0 \ + or self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "CExtern", 0) != 0: ret_ty = llvmlite.Void(pool) + else: + # [S4 fail-fast] 有返回注解但解析失败 → 不再退回 infer_return_type() + # (推断可能给出与真实注解不符的类型,静默错到运行期才暴露) + self.Gen.TypeGenErr.fatal_error( + fd, f"方法 '{class_name}.{method_name}' 返回类型注解解析失败", "NameError") + return 0 if ret_ty is None: # __init__ 和 __before_init__ 返回 void if string.strcmp(method_name, "__init__") == 0: diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index 97c70bb..ee9f81e 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -731,6 +731,13 @@ class TranslatorGenMixin: resolved_stg_ty = pointee_uv resolved_stg_entry = gv_entry_u var_ty = resolved + else: + # [S4 fail-fast] 模块级变量有注解但解析失败 → 不再静默用 i32 + # (类型错 → 全局存储尺寸/字段访问/ABI 全错,静默错到运行期)。 + # 若此处因「前向引用未注册类」触发,应收敛为多遍注册而非回退 i32。 + self.Gen.TypeGenErr.fatal_error( + aa.annotation, f"模块级变量 '{var_name}' 类型注解解析失败", "NameError") + return 0 # 解析初始值(支持整数、负数字面量、列表字面量、字符串字面量) if aa.value is not None: val_kind: int = aa.value.kind()