fix(type): 支持内建裸名函数指针构造子 callable[[...], R]
TransPyV 侧 TypeGenResolve._IsCallableSubscriptValue 已把 t.Callable[...] 与内建裸名 callable[...] / Callable[...] 视为逐点等价,TPC 侧只有模块限定形态能识别: - TypeAnnotationResolver._from_node_subscript 的 Callable 分支要求 IsTModule(parts[0]), 裸名落进泛型特化兜底未命中 → 空 CTypeInfo;改为裸名同判并共用同一构造体。 - DeclarationGenerator._get_type_str 的 Subscript 分支缺 callable 判定,落到末尾 兜底 'i32';补判返回 'i8*'(与 Attribute 分支的 t.Callable 一致)。 现场:Repl.vp:307 ReplFragFn: callable[[rawptr], int] 被声明成 i32 全局, Repl.vp:2727 ReplFragFn = fp_addr(i8*)触发「指针隐式转整数已禁止」。
This commit is contained in:
1 parent
f0e630457f
commit
85d68e5913
2 files changed
+21
-3
No files matched your search
@@ -1377,6 +1377,12 @@ class DeclarationGenerator:
|
||||
if (IsPtrSubscriptNode(annotation, TCAliasMap=self._t_c_imported_names)
|
||||
or (ValueIsCPtr and isinstance(annotation.slice, (ast.Attribute, ast.Name, ast.Subscript)))):
|
||||
return self._ptr_subscript_type_str(annotation)
|
||||
# 内建裸名函数指针构造子 callable[...] / Callable[...]:与 Attribute 分支的
|
||||
# t.Callable[...] 逐点等价(同为 i8*)。缺此分支时落到下方 Name 泛型特化 /
|
||||
# 兜底返回 'i32'(现场 Repl.vp:307 `ReplFragFn: callable[[rawptr], int]`
|
||||
# 声明成 i32 全局 ⇒ 赋 i8* 触发「指针隐式转整数」)。
|
||||
if isinstance(annotation.value, ast.Name) and (annotation.value.id == 'callable' or annotation.value.id == 'Callable'):
|
||||
return 'i8*'
|
||||
base: str = self._get_type_str(annotation.value)
|
||||
if base == 'i8*' and isinstance(annotation.slice, ast.Constant):
|
||||
return f'[{self._get_const_int(annotation.slice)} x i8]'
|
||||
|
||||
@@ -954,15 +954,27 @@ class TypeAnnotationResolver:
|
||||
if ElemInfo.IsPtr and not ElemInfo.ArrayDims:
|
||||
Result.PtrCount = max(Result.PtrCount, 1)
|
||||
return Result
|
||||
# 函数指针构造子的两种书写形态逐点等价(对齐 TPV
|
||||
# TypeGenResolve._IsCallableSubscriptValue):
|
||||
# t.Callable[...] / c.Callable[...] → 模块限定 Attribute
|
||||
# callable[...] / Callable[...] → 内建裸名(无需 import)
|
||||
# 裸名形态此前落进下方泛型特化兜底(ResolveGenericClassSpecName)未命中 ⇒
|
||||
# 空 CTypeInfo ⇒ 槽位类型退化 i32(现场 Repl.vp:307
|
||||
# `ReplFragFn: callable[[rawptr], int]`,赋 i8* 时被「指针隐式转整数」拦下)。
|
||||
parts: list[str] = []
|
||||
IsBareCallable: bool = False
|
||||
if isinstance(base, ast.Attribute):
|
||||
parts: list[str] = []
|
||||
current: ast.AST = base
|
||||
while isinstance(current, ast.Attribute):
|
||||
parts.insert(0, current.attr)
|
||||
current = current.value
|
||||
if isinstance(current, ast.Name):
|
||||
parts.insert(0, current.id)
|
||||
if parts and IsTModule(parts[0], SymbolTable) and parts[-1] == t.CPtr.__name__:
|
||||
elif isinstance(base, ast.Name) and (base.id == 'callable' or base.id == 'Callable'):
|
||||
# 裸名只在注解位置当函数指针构造子(非类型位置仍是普通标识符)
|
||||
IsBareCallable = True
|
||||
if isinstance(base, ast.Attribute) or IsBareCallable:
|
||||
if (not IsBareCallable) and parts and IsTModule(parts[0], SymbolTable) and parts[-1] == t.CPtr.__name__:
|
||||
Result: CTypeInfo = CTypeInfo()
|
||||
Result.BaseType = t.CVoid()
|
||||
Result.PtrCount = 1
|
||||
@@ -990,7 +1002,7 @@ class TypeAnnotationResolver:
|
||||
if SliceInfo and SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, t.CVoid):
|
||||
Result.BaseType = SliceInfo.BaseType
|
||||
return Result
|
||||
if parts and IsTModule(parts[0], SymbolTable) and parts[-1] == 'Callable':
|
||||
if IsBareCallable or (parts and IsTModule(parts[0], SymbolTable) and parts[-1] == 'Callable'):
|
||||
Result = CTypeInfo()
|
||||
Result.IsFuncPtr = True
|
||||
slice_node = Node.slice
|
||||
|
||||
Reference in new issue
Block a user