From 7fbf69ae63c53cdb6b8e56f5b251da636c8b74cf Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 12 Sep 2026 10:21:27 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpv):=20InternSpec=20=E8=A1=A8=E6=BB=A1?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20fatal=EF=BC=88=E4=B8=8D=E5=86=8D=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=20None=20=E9=9D=99=E9=BB=98=E4=B8=A2=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E4=BF=A1=E6=81=AF=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 表容量超限原实现只是 return None,但注释声称 fail-fast:None 会沿调用链传到 entry.Spec,条目静默失去类型信息(_entry_spec_unsigned 恒返回 0 ⇒ zext/sext 方向取错),属静默数据损坏。 改为 GenApi.fatal_error(InternalCompilerError);TypeSpec 与 GenApi 互为依赖(GenApi→GenTypes→TypeSpec),故函数内懒 import 破环(同 CallGenLib.vp:220 既有模式)。仅当 fatal_error 无 gen 通道时退化为不驻留返回完整实例,守住不返回 None 的底线。SPEC_INTERN_MAX 仍为 8192(当前未触发)。 --- App/lib/core/Gen/Type/TypeSpec.vp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/App/lib/core/Gen/Type/TypeSpec.vp b/App/lib/core/Gen/Type/TypeSpec.vp index 3dd6262..3151b48 100644 --- a/App/lib/core/Gen/Type/TypeSpec.vp +++ b/App/lib/core/Gen/Type/TypeSpec.vp @@ -810,8 +810,9 @@ def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr: # ============================================================ # InternSpec - 规范化驻留:同键只保留一份,返回驻留后的实例 -# 键 = SpecToText;**表容量**超限 → 返回 None(fail-fast,绝不静默丢弃); -# **键文本**装不下 SPEC_TEXT_MAX → 保留实例但放弃去重(绝不写入截断键)。 +# 键 = SpecToText;**表容量**超限 → fatal_error(绝不返回 None:那会让调用方条目 +# 静默丢失类型信息);**键文本**装不下 SPEC_TEXT_MAX → 保留实例但放弃去重 +# (绝不写入截断键)。 # ============================================================ def InternSpec(arena: TypeSpecArena | t.CPtr, sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: @@ -840,9 +841,21 @@ def InternSpec(arena: TypeSpecArena | t.CPtr, return None return (TypeSpec | t.CPtr)(t.CVoid(uint64(slot_e[0]), t.CPtr)) i += 1 - # 未命中:追加(容量检查 → fail-fast) + # 未命中:追加。**表满 = fail-fast**(Debugger/_Type.md D14 风险 2): + # 不能返回 None —— 调用链会把 None 一路传到 entry.Spec,条目**静默失去类型信息** + # (如 _entry_spec_unsigned 恒返回 0 ⇒ zext/sext 方向取错),属静默数据损坏, + # 与「不兜底 / fail-fast」原则直接冲突(原注释声称 fail-fast,实现却只返回 None)。 + # 破环:TypeSpec 与 GenApi 互为依赖(GenApi→GenTypes→TypeSpec),故**函数内懒 import** + # (同 CallGenLib.vp:220「函数内懒 import 规避顶层循环依赖」的既有模式)。 if arena.Count >= arena.Cap: - return None + import lib.core.Gen.GenApi as GenApi + GenApi.fatal_error( + None, + f"TypeSpec 驻留表已满(上限 {arena.Cap} 条),无法登记新类型", + "InternalCompilerError") + # 仅在 fatal_error 无 gen 通道(no-op)时可达:退化为「不驻留但返回完整实例」, + # 守住"不返回 None"这一底线 —— 宁失去同型共享,也不让条目静默丢类型。 + return sp dst_key: str = _spec_key_at(arena.Keys, arena.Count) if dst_key is None: return None