fix(generic): 特化实参统一 mangling,失败立即终止
泛型实参在特化名/spec_key/type_map 中统一为 i32/指针形态,list[int].get 返回 i32;特化与翻译失败不再吞异常,include 缺失 .ll 直接终止。
This commit is contained in:
1 parent
88645fe7da
commit
de89b26bb7
8 files changed
+108
-56
No files matched your search
@@ -3913,8 +3913,12 @@ class Phase2Translator:
|
||||
for item in need_translate:
|
||||
src_path, sha1, module_name, ll_path, obj_path, precompiled_obj = item
|
||||
if not _CachedIsFile(ll_path):
|
||||
# 翻译成功(worker 返回 ok)却没有产物 = 翻译失败:立即终止,
|
||||
# 不允许跳过该模块继续后处理/编译/链接(否则只会得到链接期
|
||||
# undefined symbol,真因与现场脱节)。
|
||||
_vlog().error(f" 翻译未生成 .ll 文件: {module_name}.py")
|
||||
continue
|
||||
raise ReportedCompileError(
|
||||
f"include 翻译未生成 .ll 文件: {module_name}.py,编译立即停止")
|
||||
|
||||
ll_content = _ReadTextCached(ll_path)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ from lib.constants.config import mode as _config_mode
|
||||
from lib.core import TypeSystem
|
||||
from lib.core.SymbolUtils import (
|
||||
IsListAnnotation, ParseListAnnotation, RequireDefineConstStorable,
|
||||
FindAutoAddrMode,
|
||||
FindAutoAddrMode, MangleTypeArgByRegistry,
|
||||
)
|
||||
|
||||
|
||||
@@ -973,7 +973,9 @@ class AnnAssignHandle(BaseHandle):
|
||||
sn2 = sn2.value
|
||||
r2: tuple[str, str] | None = self.Trans.ExprCallHandle._resolve_generic_slice_type(sn2)
|
||||
if r2:
|
||||
resolved_cn = f'{CN}[{r2[0]}]'
|
||||
# 与特化名同源(int → i32):直接拼 r2[0] 会得到
|
||||
# 'list[CInt]',方法分派查不到 'list[i32].get'。
|
||||
resolved_cn = f'{CN}[{MangleTypeArgByRegistry(r2[0])}]'
|
||||
if resolved_cn != Gen.var_struct_class.get(VarName):
|
||||
Gen.var_struct_class[VarName] = resolved_cn
|
||||
Gen.global_struct_class[VarName] = resolved_cn
|
||||
|
||||
@@ -10,7 +10,7 @@ import llvmlite.ir as ir
|
||||
from lib.core.Exportable import EnumMember as ExportEnumMember
|
||||
from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta
|
||||
from lib.core.SymbolUtils import (
|
||||
MangleTypeArgByRegistry,
|
||||
MangleTypeArgByRegistry, NormalizeGenericArgName,
|
||||
EnumClassIntWidth,
|
||||
EnumBodyMemberNames, EnumMemberCountMismatchError,
|
||||
ClassHasFuncLevelCVTable, IsVtableSlotMethod)
|
||||
@@ -90,8 +90,12 @@ class ClassHandle(BaseHandle):
|
||||
单项 mangling 走 SymbolUtils.MangleTypeArgByRegistry(声明端
|
||||
DeclarationGenerator 的泛型分支以 ResolveGenericTypeArgStr 调用同一函数,
|
||||
两侧拼名规则唯一),'][' 分隔与 HandlesTypeMerge / DeclarationGenerator 一致。
|
||||
源码短名先经 NormalizeGenericArgName 归一(int → CInt → i32):直接对
|
||||
裸 'int' 调 MangleTypeArgByRegistry 会因注册表无 'int' 而原样保留,拼出
|
||||
与声明端不一致的 'list[int]'。ResolveGenericTypeArgStr 正是同两步组合。
|
||||
"""
|
||||
mangled_args: list[str] = [MangleTypeArgByRegistry(ta) for ta in type_args]
|
||||
mangled_args: list[str] = [
|
||||
MangleTypeArgByRegistry(NormalizeGenericArgName(ta)) for ta in type_args]
|
||||
return class_name + '[' + ']['.join(mangled_args) + ']'
|
||||
|
||||
def _HasClassDefinition(self, Name: str, Gen: LlvmGeneratorMixin) -> bool:
|
||||
@@ -142,6 +146,13 @@ class ClassHandle(BaseHandle):
|
||||
type_param_names: list[str] = template['type_params']
|
||||
if len(type_args) != len(type_param_names):
|
||||
return None
|
||||
# 实参先归一为**唯一规范形**(int → CInt → i32;与声明端
|
||||
# ResolveGenericTypeArgStr、定义端 _mangle_generic_class_name 同一两步)。
|
||||
# spec_key / spec_name / type_map 全部只认这一种写法:否则同一 list[int]
|
||||
# 会以 'list<CInt>'、'list<int>'、'list<i32>' 三个键各自特化一次
|
||||
# (struct 重复发射),或缓存键与特化名不同源导致补发方法体时找不到。
|
||||
type_args = [
|
||||
MangleTypeArgByRegistry(NormalizeGenericArgName(ta)) for ta in type_args]
|
||||
spec_key: str = ClassName + '<' + ','.join(type_args) + '>'
|
||||
# 缓存必须在 Gen 上(每个模块独立),不能在 ClassHandler 上跨模块共享,
|
||||
# 否则临时 Gen(如共享符号表构建阶段)的特化会污染正式翻译阶段的缓存
|
||||
@@ -1059,7 +1070,10 @@ class ClassHandle(BaseHandle):
|
||||
_ec_gc: str | None = None
|
||||
if _iname_c:
|
||||
try:
|
||||
_ec_gc = f'{_iname_c}[{self.Trans.ExprCallHandle._resolve_type_arg_str(_inner_sub_c.slice)}]'
|
||||
# 实参必须先 mangling(int → i32、CInt → i32):
|
||||
# _resolve_type_arg_str 只做源码名归一,直接拼会得到
|
||||
# 'list[CInt]',与特化名/struct 键 'list[i32]' 分裂。
|
||||
_ec_gc = f'{_iname_c}[{MangleTypeArgByRegistry(self.Trans.ExprCallHandle._resolve_type_arg_str(_inner_sub_c.slice))}]'
|
||||
except Exception:
|
||||
_ec_gc = None
|
||||
if _ec_gc:
|
||||
@@ -1105,7 +1119,10 @@ class ClassHandle(BaseHandle):
|
||||
if _elem_slice_c is not None:
|
||||
_ec_c: str | None = None
|
||||
try:
|
||||
_ec_c = f'list[{self.Trans.ExprCallHandle._resolve_type_arg_str(_elem_slice_c)}]'
|
||||
# 与特化名同源:实参 mangling 后拼(int → i32),
|
||||
# 否则登记成 'list[CInt]',方法分派查不到
|
||||
# 'list[i32].get'(Undefined method)。
|
||||
_ec_c = f'list[{MangleTypeArgByRegistry(self.Trans.ExprCallHandle._resolve_type_arg_str(_elem_slice_c))}]'
|
||||
except Exception:
|
||||
_ec_c = None
|
||||
if _ec_c:
|
||||
|
||||
@@ -14,7 +14,7 @@ from lib.core import TypeSystem
|
||||
from lib.core.TypeSystem import CTypeRegistry
|
||||
from lib.core.SymbolUtils import (
|
||||
ExtractTypeNameFromBinOp, IsPtrSubscriptNode,
|
||||
ResolveTypeArgStr, GenericArgRawName,
|
||||
ResolveTypeArgStr, GenericArgRawName, MangleTypeArgByRegistry,
|
||||
ClassHasFuncLevelCVTable, IsVtableSlotMethod)
|
||||
from lib.core.Handles.HandlesExpr import DefineUseWidthFromLLVMType
|
||||
from lib.vast.ExprParser import NEW_SRC_MEMGR
|
||||
@@ -835,6 +835,12 @@ class ExprCallHandle(BaseHandle):
|
||||
pass
|
||||
if Node.func.attr == '__sizeof__':
|
||||
if isinstance(Node.func.value, ast.Subscript):
|
||||
# 指针下标(`T*` 的脱糖形态 CPtr[T] / rawptr[T],T 替换后可能是
|
||||
# CPtr[CInt] / CPtr[sha1.AST]):指针尺寸恒为 8。这就是原先把
|
||||
# 泛型指针实参 T 在 sizeof 上下文替换成裸 CPtr 所表达的唯一语义,
|
||||
# 现在按真实类型节点判定,不再改写 T 本身。
|
||||
if IsPtrSubscriptNode(Node.func.value, self.Trans.SymbolTable):
|
||||
return ir.Constant(ir.IntType(64), 8)
|
||||
spec_name = self._ResolveGenericSlice(Node.func.value)
|
||||
if spec_name:
|
||||
return self._HandleSizeofLlvm(ast.Name(id=spec_name, ctx=ast.Load()))
|
||||
@@ -3029,6 +3035,10 @@ class ExprCallHandle(BaseHandle):
|
||||
type_names=_TypeNames, declare_only=False)
|
||||
except Exception as _spec_err:
|
||||
Gen._generic_spec_error = f'{type(_spec_err).__name__}: {_spec_err}'
|
||||
# 特化发射失败就是翻译失败:记录现场后立即上抛,禁止带着
|
||||
# 未生成的方法体继续编译(否则只剩链接期 undefined symbol,
|
||||
# 或调用点按错误签名继续生成 IR)。
|
||||
raise
|
||||
return
|
||||
cached_name: str = cached[0]
|
||||
# 检查方法是否已有 define(blocks 非空表示已编译方法体)
|
||||
@@ -3052,13 +3062,10 @@ class ExprCallHandle(BaseHandle):
|
||||
# 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' 在类中找不到"的连带错误),
|
||||
# 且后续指令会误插进内层函数的块。
|
||||
# 上下文快照:特化失败时先复位编译器上下文再上抛——`_EmitFunctionLlvm` 的
|
||||
# 类名/构建器恢复只在**成功路径**执行(失败路径直接 re-raise),异常穿过
|
||||
# 多层后 `Gen.builder/func` 与 `_CurrentCpythonObjectClass` 会停在内层
|
||||
# 特化方法的中间状态,导致错误报文/后续阶段按内层类解析。
|
||||
_saved_builder: object = Gen.builder
|
||||
_saved_func: object = Gen.func
|
||||
_saved_cpython_class: str | None = getattr(self.Trans, '_CurrentCpythonObjectClass', None)
|
||||
@@ -3069,14 +3076,15 @@ class ExprCallHandle(BaseHandle):
|
||||
type_names=cached_type_names, declare_only=False
|
||||
)
|
||||
except Exception as _spec_err:
|
||||
# 不静默吞特化异常:暴露到 Gen._generic_spec_error(Undefined method /
|
||||
# len 失败时随报文输出),并恢复 declare_only 标记避免后续调用跳过补发。
|
||||
# fail-fast:暴露到 Gen._generic_spec_error 后立即上抛(不再吞掉让
|
||||
# 外层方法继续编译),并恢复 declare_only 标记与编译上下文。
|
||||
Gen._generic_spec_error = f'{type(_spec_err).__name__}: {_spec_err}'
|
||||
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
|
||||
raise
|
||||
|
||||
def _compute_field_byte_offset(self, Gen: LlvmGeneratorMixin, ClassName: str, field_name: str) -> int | None:
|
||||
"""计算字段在 struct 中的字节偏移(按 LLVM 布局含对齐)。
|
||||
@@ -4218,10 +4226,13 @@ class ExprCallHandle(BaseHandle):
|
||||
"""
|
||||
Gen = self.Trans.LlvmGen
|
||||
StructSha1Map: dict[str, str] = getattr(Gen, '_struct_sha1_map', {}) if Gen is not None else {}
|
||||
return ResolveTypeArgStr(
|
||||
# 归一 + mangling 两步与声明端 ResolveGenericTypeArgStr 完全相同:
|
||||
# int → CInt → i32。只做 ResolveTypeArgStr 会返回 'CInt',据此拼出的
|
||||
# 特化名 'list[CInt]' 与 struct 键/方法名 'list[i32]' 分裂。
|
||||
return MangleTypeArgByRegistry(ResolveTypeArgStr(
|
||||
node,
|
||||
TCAliasMap=getattr(self.Trans, '_from_import_aliases', {}),
|
||||
StructSha1Map=StructSha1Map)
|
||||
StructSha1Map=StructSha1Map))
|
||||
|
||||
def _get_raw_type_name(self, node: ast.AST) -> str:
|
||||
"""获取类型节点的原始名称(不带模块前缀),用于泛型 T 替换。
|
||||
|
||||
@@ -183,6 +183,8 @@ class ExprUtils:
|
||||
self.Trans.ExprCallHandle._try_complete_generic_specialization(ClassName, op_name, Gen)
|
||||
except Exception as _spec_err:
|
||||
Gen._generic_spec_error = f'{type(_spec_err).__name__}: {_spec_err}'
|
||||
# fail-fast:补发特化失败即翻译失败,禁止继续按未生成的方法分派。
|
||||
raise
|
||||
FullMethodName = f'{ClassName}.{op_name}'
|
||||
if not Gen._has_function(FullMethodName):
|
||||
FullMethodName = f'{ClassName}.{op_name}__'
|
||||
@@ -226,6 +228,8 @@ class ExprUtils:
|
||||
self.Trans.ExprCallHandle._try_complete_generic_specialization(best_candidates[0], op_name, Gen)
|
||||
except Exception as _spec_err:
|
||||
Gen._generic_spec_error = f'{type(_spec_err).__name__}: {_spec_err}'
|
||||
# fail-fast:同上,补发失败立即终止。
|
||||
raise
|
||||
_fn2: str = f'{best_candidates[0]}.{op_name}' if Gen._has_function(f'{best_candidates[0]}.{op_name}') else f'{best_candidates[0]}.{op_name}__'
|
||||
_f2: Any = Gen._get_function(_fn2)
|
||||
if _f2 is not None and getattr(_f2, 'blocks', []):
|
||||
|
||||
@@ -595,10 +595,13 @@ class FunctionHandle(BaseHandle):
|
||||
spec_name2: str | None = self.Trans.ClassHandler._specialize_generic_class(
|
||||
ret_class, ret_type_args, Gen, type_names=ret_type_names, declare_only=True)
|
||||
except Exception as _spec_err:
|
||||
# 不静默吞特化异常:记录到 Gen._generic_spec_error 后再
|
||||
# 交给外层返回类型回退(否则只剩一个错误的 CInt 返回类型)。
|
||||
# fail-fast:返回类型特化失败 = 翻译失败。转成
|
||||
# FailFastError 并穿过外层"默认 CInt"回退继续上抛,
|
||||
# 不允许带着错误/缺失的返回类型继续编译。
|
||||
from lib.core.LLVMCG.FuncGen import FailFastError as _FFE
|
||||
Gen._generic_spec_error = f'{type(_spec_err).__name__}: {_spec_err}'
|
||||
raise
|
||||
raise _FFE(
|
||||
f"泛型返回类型特化失败:{type(_spec_err).__name__}: {_spec_err}") from _spec_err
|
||||
if spec_name2 and spec_name2 in Gen.structs:
|
||||
ReturnTypeInfo = CTypeInfo()
|
||||
ReturnTypeInfo.BaseType = TypeSystem.CStruct(name=spec_name2)
|
||||
@@ -608,7 +611,12 @@ class FunctionHandle(BaseHandle):
|
||||
ReturnTypeInfo.BaseType = TypeSystem.CInt()
|
||||
except TypeError:
|
||||
raise
|
||||
except Exception: # 回退:设置默认返回类型为 CInt
|
||||
except Exception as _ret_exc: # 回退:设置默认返回类型为 CInt
|
||||
# fail-fast 信号不得被默认返回类型吞掉(否则调用点按 i32
|
||||
# 继续生成 IR,错误被伪装成运行期崩溃/链接期未定义符号)。
|
||||
from lib.core.LLVMCG.FuncGen import FailFastError as _FFE
|
||||
if isinstance(_ret_exc, _FFE):
|
||||
raise
|
||||
ReturnTypeInfo = CTypeInfo()
|
||||
ReturnTypeInfo.BaseType = TypeSystem.CInt()
|
||||
else:
|
||||
@@ -1002,14 +1010,12 @@ class FunctionHandle(BaseHandle):
|
||||
if isinstance(node.func.value, ast.Name) and node.func.value.id in type_map:
|
||||
replacement: str = type_map[node.func.value.id]
|
||||
# 指针类型参数(如 list[CPtr[AST]] 中的 T):表达式里 T 的唯一
|
||||
# 用法是 `T.__sizeof__()`,指针大小恒为 8。替换成**裸 CPtr**
|
||||
# (而不是 CPtr[<mangled 串>]):mangled 串含 '.'/'*',既不是
|
||||
# 合法 Name,也会让 __sizeof__ 的 Subscript 分支(只认泛型切片)
|
||||
# 落空后把 CPtr 当变量求值 → "未定义名称: 'CPtr'"。
|
||||
if cptr_params and node.func.value.id in cptr_params:
|
||||
node.func.value = ast.Name(id='CPtr', ctx=ast.Load())
|
||||
else:
|
||||
node.func.value = self._make_name_node(replacement)
|
||||
# 用法是 `T.__sizeof__()`。统一替换成**真实类型节点**
|
||||
# (_make_replacement_node:'sha1.AST*' → CPtr[sha1.AST]),
|
||||
# 不再替换成裸 CPtr —— 裸 CPtr 把"指针实参"的语义写死进替换
|
||||
# 规则,标量实参一旦被误判进 cptr_params 就会得到错误的 8。
|
||||
# __sizeof__ 侧已直接识别指针下标并返回 8。
|
||||
node.func.value = self._make_replacement_node(replacement)
|
||||
else:
|
||||
self._apply_type_map_to_expr(node.func.value, type_map, cptr_params)
|
||||
elif isinstance(node.func, ast.Subscript):
|
||||
@@ -1020,12 +1026,9 @@ class FunctionHandle(BaseHandle):
|
||||
elif isinstance(node, ast.Attribute):
|
||||
if isinstance(node.value, ast.Name) and node.value.id in type_map:
|
||||
replacement: str = type_map[node.value.id]
|
||||
if cptr_params and node.value.id in cptr_params:
|
||||
# 同上:指针类型参数的表达式用法(T.__sizeof__ 等)只需
|
||||
# "指针语义",裸 CPtr 即指针大小 8;不要拼 mangled 串。
|
||||
node.value = ast.Name(id='CPtr', ctx=ast.Load())
|
||||
else:
|
||||
node.value = ast.Name(id=replacement, ctx=ast.Load())
|
||||
# 同上:按真实类型节点替换(指针实参 → CPtr[<被指类>]),
|
||||
# 不再退化为裸 CPtr。
|
||||
node.value = self._make_replacement_node(replacement)
|
||||
else:
|
||||
self._apply_type_map_to_expr(node.value, type_map, cptr_params)
|
||||
elif isinstance(node, ast.BinOp):
|
||||
@@ -1520,10 +1523,13 @@ class FunctionHandle(BaseHandle):
|
||||
spec_name2: str | None = self.Trans.ClassHandler._specialize_generic_class(
|
||||
ret_class, ret_type_args, Gen, type_names=ret_type_names, declare_only=True)
|
||||
except Exception as _spec_err:
|
||||
# 不静默吞特化异常:记录到 Gen._generic_spec_error 后再
|
||||
# 交给外层返回类型回退(否则只剩一个错误的 CInt 返回类型)。
|
||||
# fail-fast:返回类型特化失败 = 翻译失败。转成
|
||||
# FailFastError 并穿过外层"默认 CInt"回退继续上抛,
|
||||
# 不允许带着错误/缺失的返回类型继续编译。
|
||||
from lib.core.LLVMCG.FuncGen import FailFastError as _FFE
|
||||
Gen._generic_spec_error = f'{type(_spec_err).__name__}: {_spec_err}'
|
||||
raise
|
||||
raise _FFE(
|
||||
f"泛型返回类型特化失败:{type(_spec_err).__name__}: {_spec_err}") from _spec_err
|
||||
if spec_name2 and spec_name2 in Gen.structs:
|
||||
ReturnTypeInfo = CTypeInfo()
|
||||
ReturnTypeInfo.BaseType = TypeSystem.CStruct(name=spec_name2)
|
||||
@@ -1533,7 +1539,12 @@ class FunctionHandle(BaseHandle):
|
||||
ReturnTypeInfo.BaseType = TypeSystem.CInt()
|
||||
except TypeError:
|
||||
raise
|
||||
except Exception: # 回退:设置默认返回类型为 CInt
|
||||
except Exception as _ret_exc: # 回退:设置默认返回类型为 CInt
|
||||
# fail-fast 信号不得被默认返回类型吞掉(否则调用点按 i32
|
||||
# 继续生成 IR,错误被伪装成运行期崩溃/链接期未定义符号)。
|
||||
from lib.core.LLVMCG.FuncGen import FailFastError as _FFE
|
||||
if isinstance(_ret_exc, _FFE):
|
||||
raise
|
||||
ReturnTypeInfo = CTypeInfo()
|
||||
ReturnTypeInfo.BaseType = TypeSystem.CInt()
|
||||
else:
|
||||
@@ -2037,14 +2048,8 @@ class FunctionHandle(BaseHandle):
|
||||
try:
|
||||
self.Trans.BodyHandler.HandleBodyLlvm(func_body)
|
||||
except Exception as _body_exc:
|
||||
# 方法体编译失败:确保 block 终止(防止 expected instruction opcode 错误),
|
||||
# 然后重新抛出异常让编译立即终止(不吞掉错误)
|
||||
_fn_name: str = Node.name
|
||||
_cls_name: str = ClassName if ClassName else ''
|
||||
import sys as _sys
|
||||
import traceback as _tb
|
||||
print(f"[FATAL] 方法体编译失败 ({_cls_name}.{_fn_name}): {type(_body_exc).__name__}: {_body_exc}", file=_sys.stderr)
|
||||
_tb.print_exc(file=_sys.stderr)
|
||||
# 方法体编译失败:复位上下文后原样上抛,由 Phase2Translator 的
|
||||
# worker/主进程统一输出一次并终止(此处不打印,避免同一错误重复)。
|
||||
if Gen.builder is not None:
|
||||
try:
|
||||
if not Gen.builder.block.is_terminated:
|
||||
|
||||
@@ -15,7 +15,7 @@ from lib.constants.config import mode as _config_mode
|
||||
from lib.core import TypeSystem
|
||||
from lib.core.TypeSystem import CTypeRegistry
|
||||
from lib.core.SymbolUtils import ParseListAnnotation, AnnotationContainsName, FindAutoAddrMode
|
||||
from lib.core.SymbolUtils import EnumClassIntWidth, ExpandSoftKeywords
|
||||
from lib.core.SymbolUtils import EnumClassIntWidth, ExpandSoftKeywords, MangleTypeArgByRegistry
|
||||
from lib.core.SymbolUtils import ClassHasFuncLevelCVTable, IsVtableSlotMethod
|
||||
|
||||
|
||||
@@ -2442,7 +2442,9 @@ class ImportHandle(BaseHandle):
|
||||
_ec_gs: str | None = None
|
||||
if _iname_s:
|
||||
try:
|
||||
_ec_gs = f'{_iname_s}[{self.Trans.ExprCallHandle._resolve_type_arg_str(_inner_sub_s.slice)}]'
|
||||
# 实参先 mangling(int → i32):与特化名/struct 键
|
||||
# 'list[i32]' 保持同源,避免 'list[CInt]' 分派失败。
|
||||
_ec_gs = f'{_iname_s}[{MangleTypeArgByRegistry(self.Trans.ExprCallHandle._resolve_type_arg_str(_inner_sub_s.slice))}]'
|
||||
except Exception:
|
||||
_ec_gs = None
|
||||
if _ec_gs:
|
||||
@@ -2488,7 +2490,8 @@ class ImportHandle(BaseHandle):
|
||||
if _elem_slice_s is not None:
|
||||
_ec_s: str | None = None
|
||||
try:
|
||||
_ec_s = f'list[{self.Trans.ExprCallHandle._resolve_type_arg_str(_elem_slice_s)}]'
|
||||
# 同 HandlesClassDef:实参 mangling 后拼特化名(int → i32)
|
||||
_ec_s = f'list[{MangleTypeArgByRegistry(self.Trans.ExprCallHandle._resolve_type_arg_str(_elem_slice_s))}]'
|
||||
except Exception:
|
||||
_ec_s = None
|
||||
if _ec_s:
|
||||
@@ -4257,10 +4260,12 @@ class ImportHandle(BaseHandle):
|
||||
gc_base, gc_type_args, Gen, type_names=gc_type_names,
|
||||
declare_only=True)
|
||||
except Exception as _spec_err:
|
||||
# 不静默吞特化异常:记录现场,供后续 Undefined method /
|
||||
# len 失败路径把真因带进报错。
|
||||
# fail-fast:特化发射失败即翻译失败。记录现场、恢复
|
||||
# module_sha1 后立即上抛,不带着缺失的方法体继续编译。
|
||||
Gen._generic_spec_error = f'{type(_spec_err).__name__}: {_spec_err}'
|
||||
gc_spec = None
|
||||
Gen.module_sha1 = saved_module_sha1
|
||||
self.Trans._module_sha1 = saved_trans_sha1
|
||||
raise
|
||||
Gen.module_sha1 = saved_module_sha1
|
||||
self.Trans._module_sha1 = saved_trans_sha1
|
||||
if gc_spec and gc_spec in Gen.structs:
|
||||
|
||||
@@ -852,7 +852,11 @@ class HandlesTypeMerge(BaseHandle):
|
||||
_ig_args: list[str] = []
|
||||
for _ig_elt in _ig_slices:
|
||||
_ig_res = self.Trans.ExprCallHandle._resolve_generic_slice_type(_ig_elt)
|
||||
_ig_args.append(_ig_res[0] if _ig_res else self.Trans.ExprCallHandle._resolve_type_arg_str(_ig_elt))
|
||||
_ig_raw: str = _ig_res[0] if _ig_res else self.Trans.ExprCallHandle._resolve_type_arg_str(_ig_elt)
|
||||
# 与 _mangle_generic_class_name 同口径(CInt/CInt32T → i32、
|
||||
# CFloat64T → f64):直接拼原始名会得到 'list[CInt]',
|
||||
# 与 struct 键/方法名 'list[i32]' 分裂 → Undefined method。
|
||||
_ig_args.append(MangleTypeArgByRegistry(_ig_raw))
|
||||
_ig_spec: str = f'{_inner_gsub.value.id}[' + ']['.join(_ig_args) + ']'
|
||||
ResultInfo.BaseType = TypeSystem.CStruct(name=_ig_spec)
|
||||
ResultInfo.Name = _ig_spec
|
||||
|
||||
Reference in new issue
Block a user