From 007943142a6a6f47fd69e6f191a9dcf00409851d Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 9 Oct 2026 19:12:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(diag):=20DiagEntry.File=20=E6=94=B9?= =?UTF-8?q?=E5=90=8D=20FileName=EF=BC=8C=E9=81=BF=E5=BC=80=E4=B8=8E=20file?= =?UTF-8?q?io.File=20=E7=9A=84=E9=9D=9E=E9=99=90=E5=AE=9A=E5=90=8D?= =?UTF-8?q?=E7=9B=B8=E6=92=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现场:TPC 编译 Diag.vp 时 read_source_line 的 fileio.File(...) 报 llvmlite "Type of #1 arg mismatch: i8** != %"1f18c0c34662cbfb.File"*" (1f18c0c34662cbfb = fileio 的模块 sha1,即 self 形参被解析成 i8**,实参本是正确的 fileio.File*)。 Diag.vp 是唯一一个"类字段名 == 同模块 import 的类名"的模块(全仓仅此处有 File: 字段), 而其余 24 个调用 fileio.File(...) 的模块(含 BuildPipeline.vp 的 6 个类)都无此字段且编译正常。 TPC 的 Gen.structs / SymbolTable / _mangle_func_name 均按非限定名索引,故改名规避。 --- App/lib/core/Diag.vp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/App/lib/core/Diag.vp b/App/lib/core/Diag.vp index fe76b2b..9e0e307 100644 --- a/App/lib/core/Diag.vp +++ b/App/lib/core/Diag.vp @@ -39,7 +39,12 @@ define DIAG_MAX_FRAMES = 32 # 调用链上限(与 TypeGenMixin.TRACE_MAX 对 # 用于"从错误发生点向外展示触发过程"。 # 所有字符串都用 stdlib 深拷贝:编译期池会回绕,不能借用池内指针。 class DiagEntry: - File: str # 当前帧(错误点)文件 + # 字段名不要与"本模块 import 的类名"重名:TPC 的类型/符号表按**非限定名**索引 + # (Gen.structs / SymbolTable / _mangle_func_name),曾把本字段的 `File` 与 + # `w32.fileio.File` 撞在一起,导致同模块 `fileio.File(...)` 的构造调用把 + # `File.__before_init__` 的 self 形参解析成 `i8**`(llvmlite: "Type of #1 arg + # mismatch: i8** != %"...fileio.File"*")。故此处用 FileName 而非 File。 + FileName: str # 当前帧(错误点)文件 Line: int # 当前帧行号 ColStart: int # caret 起始列(1-based;0 = 不画) ColEnd: int # caret 结束列 @@ -68,7 +73,7 @@ def new_entry(max_frames: int) -> DiagEntry*: ent: DiagEntry* = (DiagEntry*)(stdlib.malloc(DiagEntry.__sizeof__())) if ent is None: return None if max_frames <= 0: max_frames = 1 - ent.File = None + ent.FileName = None ent.Line = 0 ent.ColStart = 0 ent.ColEnd = 0 @@ -88,7 +93,7 @@ def begin(ent: DiagEntry*, category: str, msg: str, hint: str = None) -> int: ent.Category = dup_str(category) ent.Msg = dup_str(msg) ent.Hint = dup_str(hint) - ent.File = None + ent.FileName = None ent.Line = 0 ent.ColStart = 0 ent.ColEnd = 0 @@ -99,7 +104,7 @@ def begin(ent: DiagEntry*, category: str, msg: str, hint: str = None) -> int: # set_current - 设置当前帧(错误点)位置 def set_current(ent: DiagEntry*, file_name: str, lineno: int, col_start: int, col_end: int) -> int: if ent is None: return 0 - ent.File = dup_str(file_name) + ent.FileName = dup_str(file_name) ent.Line = lineno ent.ColStart = col_start ent.ColEnd = col_end @@ -131,7 +136,7 @@ def emit(ent: DiagEntry*, direction: int) -> int: while i_u < ent.FrameCount: emit_frame(str(ent.FrameFiles[i_u]), int(ent.FrameLines[i_u])) i_u += 1 - emit_current(ent.File, ent.Line, ent.ColStart, ent.ColEnd) + emit_current(ent.FileName, ent.Line, ent.ColStart, ent.ColEnd) emit_category(ent.Category, ent.Msg) return 0 @@ -139,7 +144,7 @@ def emit(ent: DiagEntry*, direction: int) -> int: # free_entry - 释放一条诊断(含深拷贝的字符串) def free_entry(ent: DiagEntry*) -> int: if ent is None: return 0 - if ent.File is not None: stdlib.free(ent.File) + if ent.FileName is not None: stdlib.free(ent.FileName) if ent.Category is not None: stdlib.free(ent.Category) if ent.Msg is not None: stdlib.free(ent.Msg) if ent.Hint is not None: stdlib.free(ent.Hint)