From ba7e117ecb6b8246f3b24d194c5bd6d450e8f506 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 30 Sep 2026 16:38:09 +0800 Subject: [PATCH] =?UTF-8?q?fix(HandlesExprCall):=20=E5=90=8C=E5=90=8D?= =?UTF-8?q?=E7=B1=BB=E6=9E=84=E9=80=A0=E6=B6=88=E6=AD=A7=E2=80=94=E2=80=94?= =?UTF-8?q?ctor=20=E7=9A=84=20self=20=E5=AE=9E=E5=8F=82=E6=8C=89=20callee?= =?UTF-8?q?=20=E9=99=90=E5=AE=9A=E7=B1=BB=E5=90=8D=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E5=86=8D=E5=9B=9E=E9=80=80=E6=9C=89=E6=AD=A7?= =?UTF-8?q?=E4=B9=89=E7=9A=84=E7=9F=AD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 类别:a(编译器缺陷) 现象:includes/ast/parser.vp:1774 `kw: rawptr[AST] = KwNode(ps.pool, None, val)` 报 FailFastError: 指针隐式转换已禁止(非基本类型(结构体/类/联合)):调用 8312ce86a2fd82c0.Keyword.__new__ 第 0 个实参 %"fef783da4d24330d.Keyword"* 不能隐式转为形参 %"8312ce86a2fd82c0.Keyword"* 根因:Keyword 同时存在于 ast.astaux(8312ce86a2fd82c0) 与 ast.tokens(fef783da4d24330d)。 KwNode 是 `from .astaux import Keyword as KwNode` 的导入别名,_ctor_module_sha1 只从 ModulePath(ast.attr 形态) 解析 ⇒ 裸名/别名调用拿不到 sha1; _get_struct_type 回退短名 Gen.structs.get('Keyword') ⇒ 撞上 tokens 的同名实例。 修复:从**已解析到的构造函数对象**的 IR 名({sha1}.{Class}.{method})取限定类名, 仅在「同短名 + 已具化」时改判——同短名保证不会把无关类引进来,已具化保证 _allocaEntry 的尺寸正确(opaque 实例算不出大小)。取不到限定名时保持原短名回退, 对无同名冲突的类零变化。 --- lib/core/Handles/HandlesExprCall.py | 30 ++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index 16daa92..db00575 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -5063,11 +5063,39 @@ class ExprCallHandle(BaseHandle): print(f"[DEBUG_CLASSNEW] _HandleClassNewLlvm called for Asm, module_sha1={module_sha1}", file=_dbg_sys.stderr) # 跨模块类型引用:优先用 {module_sha1}.{ClassName} 查找 struct _struct_full_key: str | None = f"{module_sha1}.{ClassName}" if module_sha1 else None + # 【同名类消歧(2026-09-30)】ClassName 可能是**导入别名**( + # `from .astaux import Keyword as KwNode` 后写作 KwNode)或短名,而 + # `Gen.structs` / `Gen.functions` 的**短名键**在"两个模块各定义同名类"时是有歧义的 + # ——现场:Keyword 同时存在于 ast.astaux(8312ce86a2fd82c0) 与 + # ast.tokens(fef783da4d24330d)。ctor 的 self 实参按短名取到了 tokens.Keyword*, + # 而 callee 是 astaux 的 `8312ce86a2fd82c0.Keyword.__new__` ⇒ `_adjust_args` 报 + # "指针隐式转换已禁止(非基本类型(结构体/类/联合)):第 0 个实参 + # %"fef783da4d24330d.Keyword"* 不能隐式转为形参 %"8312ce86a2fd82c0.Keyword"*" + # (includes/ast/parser.vp:1774 `kw: rawptr[AST] = KwNode(ps.pool, None, val)`)。 + # 真名从**已解析到的构造函数对象**上取(其 IR 名是 `{sha1}.{Class}.{method}`), + # 与 callee 同源;取不到时保持原行为(短名回退),对无同名冲突的类零变化。 + _QCls: str | None = None + for _probe_key in (f'{ClassName}.__new__', f'{ClassName}.__before_init__', f'{ClassName}.__init__'): + _probe_fn: Any = Gen._find_function(_probe_key) + _probe_nm: str = (getattr(_probe_fn, 'name', '') or '') if _probe_fn is not None else '' + if _probe_nm.count('.') >= 2: + _QCls = _probe_nm.rsplit('.', 1)[0] + break def _get_struct_type(name: str) -> ir.Type | None: - """优先用 SHA1 前缀完整名查找,回退到短名""" + """优先用 SHA1 前缀完整名查找,再按"与 callee 同源的限定名"消歧,最后回退短名""" if _struct_full_key and _struct_full_key in Gen.structs: return Gen.structs[_struct_full_key] + if _QCls and _QCls != name and _QCls in Gen.structs: + _qc: Any = Gen.structs[_QCls] + # 只在"**同短名**(即确实是同名类的另一份实例)且**已具化**"时改判: + # 同短名保证不会把无关类引进来;已具化保证 `_allocaEntry` 的尺寸正确 + # (opaque 实例算不出大小,会让 ctor 的 self 指向尺寸错误的块)。 + if (isinstance(_qc, ir.IdentifiedStructType) + and (getattr(_qc, 'name', '') or '').rsplit('.', 1)[-1] + == (name or '').rsplit('.', 1)[-1] + and _qc.elements is not None): + return _qc return Gen.structs.get(name) if hasattr(self.Trans.ClassHandler, '_generic_class_templates') and ClassName in self.Trans.ClassHandler._generic_class_templates: