fix(stmt): translate_with 属性访问改用中间变量,规避 TPC 编译损坏致 asname 未绑定

TransPyC 编译 translate_with 时,联合类型转换后直接取属性(如
((ast.Name|CPtr)(ov)).id / ((ast.Call|CPtr)(ce)).func)的属性访问
(GEP+load)被编译器丢弃——编译产物 75904e6cbc83036b.text.ll 显示
store %asname 0 次、load 3 次,asname 恒 null → pool 从未绑定到
SymTab → body 内 pool.alloc 方法调用检测 lookup_var 失败 → 误报
"跨模块调用 'pool.alloc' 找不到模块 SHA1"。同理 cfn 恒 null 导致
cls_name(AnnotClassName)也设置不上。改为先转换到中间变量再取属性
(代码库已验证编译正常的 cmn 模式),修复 3 处(L264/L279/L298)。
This commit is contained in:
TermiNexus committed 2026-08-13 07:37:20 +08:00
1 parent f1530aac91
commit 9f7333b0f2
1 file changed
+9 -3
+9 -3
View File
@@ -261,7 +261,10 @@ class StmtGenMixin:
cls_name: str = None
ce: ast.AST | t.CPtr = item.context_expr
if ce.kind() == ast.ASTKind.Call:
cfn: ast.AST | t.CPtr = ((ast.Call | t.CPtr)(ce)).func
# 注意:联合类型转换后必须经中间变量再取属性(直接
# ((ast.Call|CPtr)(ce)).func 会被 TPC 编译损坏丢弃属性访问)
call_ce: ast.Call | t.CPtr = (ast.Call | t.CPtr)(ce)
cfn: ast.AST | t.CPtr = call_ce.func
if cfn is not None:
if cfn.kind() == ast.ASTKind.Attribute:
ca: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cfn)
@@ -276,7 +279,8 @@ class StmtGenMixin:
if cls_name is None:
cls_name = ca.attr
elif cfn.kind() == ast.ASTKind.Name:
cls_name = ((ast.Name | t.CPtr)(cfn)).id
nm_cfn: ast.Name | t.CPtr = (ast.Name | t.CPtr)(cfn)
cls_name = nm_cfn.id
# context 对象存入 __with_ctx(方法调用解析 self 用)
ctx_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(
builder, ctx_val.Ty)
@@ -295,7 +299,9 @@ class StmtGenMixin:
if item.optional_vars is not None:
ov: ast.AST | t.CPtr = item.optional_vars
if ov.kind() == ast.ASTKind.Name:
asname: str = ((ast.Name | t.CPtr)(ov)).id
# 联合类型转换后经中间变量再取属性(同 L264 注释,防 TPC 编译损坏)
ovn: ast.Name | t.CPtr = (ast.Name | t.CPtr)(ov)
asname: str = ovn.id
if asname is not None:
bind_val: llvmlite.Value | t.CPtr = enter_val
if bind_val is None: