From 6a287b955eb6815c3ce4df6d811b43b08679bd92 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 30 Sep 2026 09:59:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(TypeGenCType):=20=E8=B7=A8=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E5=8F=AF=E8=A7=81=E5=AD=97=E6=AE=B5=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=9C=A8=E7=B1=BB=E4=BD=93=E5=A3=B0=E6=98=8E=EF=BC=88=E4=BF=AE?= =?UTF-8?q?=20Repl.vp:802=20=E5=B1=9E=E6=80=A7=E9=93=BE=E6=B1=82=E5=80=BC?= =?UTF-8?q?=E4=B8=BA=E7=A9=BA=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 类别:c 源码违规(跨模块读得到的字段必须在类体声明) 现象:TPC 编译 TransPyV/App/lib/core/Repl.vp:802 ct_names: list[str]* = GenApi._g_gen.TypeGenCType.CTypedefNames 报「带注解赋值表达式 …(Attribute 形态)编译期求值为空(表达式未解析出目标、无值可存), 赋值将被跳过、变量保持未初始化」。 判据(.vpi 与定义侧不同源,实证): · TypeGenCType 类体**一个字段都没声明**:CTypedefNames / CTypedefTypeStrs / CTypedefNameIdx / CTypedefNameIdxCap / CTypedefNameIdxBuilt 全部只以方法体里的裸 `self.x = ...` 出现 (:184 `self.CTypedefNames = tn`、:185、:66-73、:118-121)。 · 声明存根(.vpi)只携带**类体 AnnAssign 字段**与 `__init__` 里**带注解**的 self.x;方法体 里的裸赋值只被**定义模块自己**的成员收集(HandlesClassDef 的 self.x 扫描)收录 ⇒ 同一字段"定义模块成员表里有、引用模块没有"(实证:temp/05d515186a7c3668.vpi 内不含 CTypedefNames 条目)⇒ 引用模块的属性链在第三级断掉,整条带注解赋值被判"无值可存"而终止。 修法:把这 5 个字段在**类体**显式声明(类型取自各自赋值处的真实类型): CTypedefNames / CTypedefTypeStrs : list[str] | t.CPtr (:177-178 的 tn / ts 即 list[str]*) CTypedefNameIdx : sizet* (:64 / :71 的 idx) CTypedefNameIdxCap / CTypedefNameIdxBuilt : int 声明后定义侧与 .vpi 两侧字段集一致(类体 AnnAssign 先收集,方法体 self.x 扫描按名去重不再 重复登记)⇒ 布局同源。注意:该类的字段顺序/类型与旧构建不同(字段从"仅扫描收集"变为 "类体声明"),需要清缓存重编译。 附带(另一仓 commit):TPC 侧 `_handle_attr_nested` 的 7 处静默 return 已补 `_NoteAttrNone` 记账(含内层失败原因链),下次同类报错会直接给出"读取侧原因=…"。 --- App/lib/core/Gen/Type/TypeGenCType.vp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/App/lib/core/Gen/Type/TypeGenCType.vp b/App/lib/core/Gen/Type/TypeGenCType.vp index 97055a9..247c2af 100644 --- a/App/lib/core/Gen/Type/TypeGenCType.vp +++ b/App/lib/core/Gen/Type/TypeGenCType.vp @@ -52,6 +52,25 @@ def _ctypedef_idx_hash(name: str) -> uint64: class TypeGenCType(TypeGenBase.TypeGenBase): """CTypedef 表(register/lookup/ScanCTypedefDeclarations/_eval_const_int_expr)""" + # ============================================================ + # 字段必须在**类体**声明(跨模块可见性要求,不是风格问题) + # + # 缘由:`.vpi`(声明存根)只携带**类体 AnnAssign 字段**与 `__init__` 里**带注解**的 + # `self.x: T = ...`;而方法体里的裸 `self.x = ...` 只被**定义模块自己**的成员收集 + # (HandlesClassDef 的 self.x 扫描)收录 ⇒ 同一字段"定义模块的成员表里有、引用模块的 + # 没有",且两侧 struct 布局不同源。 + # 现场:`GenApi._g_gen.TypeGenCType.CTypedefNames`(Repl.vp:802)在引用模块里属性链 + # 求值为空 → 带注解赋值被判定"无值可存"而终止编译(该字段原仅由 `self.CTypedefNames = + # tn` 赋值,.vpi 与跨模块成员表里都没有它)。 + # 判据:凡会被**别的模块**读到的字段,一律在类体写注解;只在类内使用的临时状态才允许 + # 只写 `self.x = ...`。 + # ============================================================ + CTypedefNames: list[str] | t.CPtr + CTypedefTypeStrs: list[str] | t.CPtr + CTypedefNameIdx: sizet* + CTypedefNameIdxCap: int + CTypedefNameIdxBuilt: int + # ============================================================ # CTypedef 名索引(开放寻址;槽存 index+1,0=空槽) # ============================================================