diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index c6b72dd..e4fe8a3 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -2894,6 +2894,18 @@ class ExprCallHandle(BaseHandle): # 不预先标记:_specialize_generic_class 内部缓存逻辑会检测 # cached_declare_only=True 且 declare_only=False,自动补发方法体 # 并更新缓存为 (spec_name, False)。预注册机制(L117)防止递归。 + # + # 上下文快照:本函数**吞掉**特化异常、让外层方法继续编译,故必须在失败时把 + # 编译器上下文复位——`_EmitFunctionLlvm` 的类名/构建器恢复只在**成功路径** + # 执行(失败路径直接 re-raise),异常穿过多层后 `Gen.builder/func` 与 + # `_CurrentCpythonObjectClass` 会停在内层特化方法的中间状态:外层方法随后 + # 的 `self.X` 被按内层类解析(ExprGenFstr.vp 的 `self.Gen` 被按 + # `list[cfc4ca8da95a30e1.AST*]` 解析 → "属性 'Gen' 在类中找不到"的连带错误), + # 且后续指令会误插进内层函数的块。 + _saved_builder: object = Gen.builder + _saved_func: object = Gen.func + _saved_cpython_class: str | None = getattr(self.Trans, '_CurrentCpythonObjectClass', None) + _saved_class_name: object = getattr(Gen, '_current_class_name', None) try: self.Trans.ClassHandler._specialize_generic_class( base_name, cached_type_args, Gen, @@ -2902,6 +2914,10 @@ class ExprCallHandle(BaseHandle): except Exception: # 失败时恢复 declare_only 标记,避免后续调用跳过补发 Gen._generic_class_specializations[spec_key] = (cached_name, True) + Gen.builder = _saved_builder + Gen.func = _saved_func + self.Trans._CurrentCpythonObjectClass = _saved_cpython_class + Gen._current_class_name = _saved_class_name def _compute_field_byte_offset(self, Gen: LlvmGeneratorMixin, ClassName: str, field_name: str) -> int | None: """计算字段在 struct 中的字节偏移(按 LLVM 布局含对齐)。 diff --git a/lib/core/Handles/HandlesFunctions.py b/lib/core/Handles/HandlesFunctions.py index 13f5ca2..8f67ebf 100644 --- a/lib/core/Handles/HandlesFunctions.py +++ b/lib/core/Handles/HandlesFunctions.py @@ -2086,6 +2086,18 @@ class FunctionHandle(BaseHandle): Gen.builder.ret_void() except Exception: pass + # 失败路径也要复位「当前方法」上下文(成功路径的复位在函数末尾,异常 + # 直接 re-raise 会跳过它)。上层有吞掉异常的调用点(如泛型特化按需补全 + # _try_complete_generic_specialization、类按需实例化),它们让外层方法 + # 继续编译;若此时 _CurrentCpythonObjectClass / var_struct_class 仍指向 + # 内层特化类,外层方法的 `self.X` 会被按内层类解析(典型现象: + # ExprGenFstr.translate_joined_str 的 `self.Gen` 被按 + # `list[cfc4ca8da95a30e1.AST*]` 解析 → "属性 'Gen' 在类中找不到")。 + Gen._current_class_name = _saved_class_name + self.Trans._CurrentCpythonObjectClass = saved_cpython_class + Gen.var_struct_class = saved_var_struct_class + if hasattr(Gen, 'global_struct_class'): + Gen.global_struct_class = saved_global_struct_class raise if not Gen.builder.block.is_terminated: if 'naked' in fn_attrs: