diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index d187936..24f27fe 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -310,6 +310,42 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return res_c # ---- 6. 查不到:保持原样 ---- return type_name + + def _str_contains_ident(self, s: str, ident: str) -> int: + """检查 s 中是否包含独立标识符 ident(两侧非字母/数字/下划线) + + 用于泛型实参污染检测:单字符参数名(如 'T')在实参串 "AST|t.CPtr" + 中作为 AST/CPtr 内部字符出现时不算污染——必须两侧是边界 + (空格/|/[/]/,等)才算独立标识符。strstr 子串匹配会把实参内部 + 的 'T' 误判为参数名 → 合法特化 list[AST|t.CPtr] 被误杀。 + """ + if s is None or ident is None or ident[0] == '\0': + return 0 + s_len: t.CSizeT = string.strlen(s) + id_len: t.CSizeT = string.strlen(ident) + if id_len == 0 or s_len < id_len: + return 0 + i: t.CSizeT + for i in range(s_len - id_len + 1): + if string.strncmp(s + i, ident, id_len) != 0: + continue + # 左边界:i==0 或前一字符非标识符字符 + left_ok: int = 1 + if i > 0: + lc: t.CChar = s[i - 1] + if (lc >= 'a' and lc <= 'z') or (lc >= 'A' and lc <= 'Z') \ + or (lc >= '0' and lc <= '9') or lc == '_': + left_ok = 0 + right_ok: int = 1 + if i + id_len < s_len: + rc: t.CChar = s[i + id_len] + if (rc >= 'a' and rc <= 'z') or (rc >= 'A' and rc <= 'Z') \ + or (rc >= '0' and rc <= '9') or rc == '_': + right_ok = 0 + if left_ok != 0 and right_ok != 0: + return 1 + return 0 + def _parse_type_string(self, pool: memhub.MemBuddy | t.CPtr, type_str: str, ctx: t.CInt) -> ast.AST | t.CPtr: @@ -1265,7 +1301,13 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): gp_j: t.CSizeT for gp_j in range(gp_n): gp_pn: str = tpn_g.get(gp_j) - if gp_pn is not None and string.strstr(gp_ta, gp_pn) is not None: + # token 边界匹配(非 strstr 子串):实参串中必须出现 + # "独立标识符"参数名(两侧非字母/数字/_)。否则 strstr + # 把实参内部字符误判为参数名——"e9dfb296a8674aee.AST| + # t.CPtr" 含 'T' 字符但 T 在 AST/CPtr 内部不是独立 + # 参数名 → 合法特化 list[AST|t.CPtr] 被误杀(_list.vp + # L57 elem_ptr: T | t.CPtr 根因)。 + if gp_pn is not None and self._str_contains_ident(gp_ta, gp_pn) != 0: polluted = 1 break if polluted != 0: