Files
TransPyC/lib
TermiNexus ecd336771f fix(FuncGen): base/字段偏移一律按"重名条目不占槽位"算,修 MatchCase 偏移 6(应为 7)
类别:a(编译器缺陷)

现象(早前现场,本轮定位):
  TypeError: [fast-fail] len(mcc_pre.children) 分派 'list[….AST*].__len__' 失败:
  类='MatchCase' 偏移=6 接收者类型=i32

判据(磁盘实证):
  · MatchCase 的 body 在 temp 与**全部** output stub 中都是 **10 槽**
    (vtable + AST 的 7 字段 + pattern/guard)⇒ `children` 的正确偏移 = base(1) + 表内下标(6) = **7**。
  · 观测到 6 ⇒ base 被算成 0 ⇒ `_member_base` 的 `_Delta = 槽数 - 表长` 为 0,
    即**表长 = 10**(9 个不同字段 + 1 条重名条目),而不是 9。
  · 重名条目是**产物**:源码层面的字段名遮蔽已由 HandlesClassDef 的
    "字段名遮蔽 fail-fast"(:1083)拦下 ⇒ 表里的重名只可能来自"展平残留
    (半截祖先块,已由 2e7bac18 在插入点剥除)/ 同一字段被两条收集路径各登记一次"。

修复(与 `_get_member_offset` 配对路径已有的"重名条目不占槽位"同口径,全线统一):
  · `_member_base` 的长度校准改用**去重名数**(`_Delta` 不再被重名条目冲掉 ⇒ base 正确);
  · 新增 `_MemberSlotIndex(Members, FieldName)`:取"首个同名的**去重**下标"
    (重名条目不计槽位),并把 `_get_member_offset` 中**全部 12 处** "base + 表内下标"
    站点改为调用它(含继承链回退、REnum 变体搜索、stub 重载后、_PreRegisterClassMembers
    之后等分支);"最后回退"里的 `_num_members_final` 同步改为去重计数。
  · 对无重名的表,取值与改前**逐字相同**(去重下标 == 原始下标)。

核验:py_compile + compileall 全 lib 通过;离线冒烟(真实方法、未绑定实例调用):
含 1 条重复 'children' 的表上 `children -> 6`、`guard -> 8`、缺名 -> -1;
去重名数 9 ⇒ `_Delta = 10 - 9 = 1` ⇒ base=1 ⇒ `children` 偏移 7(与 body 10 槽一致)。
未放宽任何 fail-fast。
2026-09-30 18:44:48 +08:00
..