diff --git a/lib/core/Handles/HandlesAnnAssign.py b/lib/core/Handles/HandlesAnnAssign.py index c9128d1..f243250 100644 --- a/lib/core/Handles/HandlesAnnAssign.py +++ b/lib/core/Handles/HandlesAnnAssign.py @@ -747,6 +747,27 @@ class AnnAssignHandle(BaseHandle): Gen.global_struct_class[VarName] = Node.annotation.id Gen._record_var_signedness(VarName, IsUnsigned) return + # 方向判定用:取注解一侧的泛型基名(`Base[...]` 或 `Base[...] | t.CPtr` + # 形态中的 Base)。此判据**不依赖泛型模板注册表**(list/dict 等内建 + # 容器可能未登记),只做结构性识别;仅 Name 形态可识别,属性链 + # (如 t.CPtr[...])不参与。 + _ann_gen_base: str | None = None + _ann_sub_side: ast.expr | None = None + if isinstance(Node.annotation, ast.Subscript): + _ann_sub_side = Node.annotation + elif (isinstance(Node.annotation, ast.BinOp) + and isinstance(Node.annotation.op, ast.BitOr)): + for _ann_side in (Node.annotation.left, Node.annotation.right): + if isinstance(_ann_side, ast.Subscript): + _ann_sub_side = _ann_side + break + if _ann_sub_side is not None: + _ann_base_v: ast.expr = _ann_sub_side.value + # 兼容嵌套下标链(Base[...][...]):逐层剥到最内层 Name + while isinstance(_ann_base_v, ast.Subscript): + _ann_base_v = _ann_base_v.value + if isinstance(_ann_base_v, ast.Name): + _ann_gen_base = _ann_base_v.id for CN, ST in Gen.structs.items(): # 泛型占位类型(T/U/V,如 GSList[T].Head 的元素类型)opaque 无 body, # 不参与变量类型重建/var_struct_class 设置:跟随 T* 会污染注解声明的 @@ -782,8 +803,26 @@ class AnnAssignHandle(BaseHandle): Gen.var_struct_class[VarName] = resolved_cn Gen.global_struct_class[VarName] = resolved_cn if isinstance(VarType, ir.PointerType) and VarType.pointee is not ST and VarType.pointee != ST: - var = Gen._allocaEntry(ir.PointerType(pointee), name=VarName) - VarType = ir.PointerType(pointee) + # 方向判定:本重建的本意是「注解退化成裸基类 / i8*, + # RHS 构造出精确特化 ⇒ 用 RHS 反向升级」(见 L765 注释)。 + # 但 RHS 的 pointee 若为**裸泛型基类**(丢类型实参,如 + # {sha1}.list)而注解一侧本身就是带类型实参的泛型 + # (`Base[...]` 或 `Base[...] | t.CPtr`),以 RHS 重建 + # alloca 会把注解已解析出的特化类型覆盖成裸基类 → 之后 + # .get() 按错误元素类型分派(list[int].get 返回 i32)→ + # inttoptr 截断指针 → 读垃圾 AST 节点崩溃 + # (MatchGenMixin._handle_renum_match 现场根因)。 + # 判据(_cn_short 无 '[' 且与注解泛型基名同名)只拦这一 + # 确定的方向错误,属**结构性识别**而非兜底:注解退化为 + # i8*/裸基类、RHS 精确特化的合法升级路径不受影响。 + _rb_is_bare_generic: bool = ( + _ann_gen_base is not None + and '[' not in _cn_short + and _cn_short == _ann_gen_base + ) + if not _rb_is_bare_generic: + var = Gen._allocaEntry(ir.PointerType(pointee), name=VarName) + VarType = ir.PointerType(pointee) break if InitValue: try: