diff --git a/App/lib/core/Gen/Class/ClassGenGeneric.vp b/App/lib/core/Gen/Class/ClassGenGeneric.vp index 3806f5d..c9881df 100644 --- a/App/lib/core/Gen/Class/ClassGenGeneric.vp +++ b/App/lib/core/Gen/Class/ClassGenGeneric.vp @@ -421,21 +421,29 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): (str/char/bytes/bool/float/double 的 SourceName 为 None):按 LLVM 形态映射为源码可解析名(double/float/int/char/bool)。指针/结构体返回 None(交由注解来源名路径处理;此处不做猜测,避免错特化)。 + + **只映射"位宽精确对应到某个裸名"的形态**(i1→bool、i8→char、i32→int、 + f32→float、f64→double)。i16/i64/f16 在 Viper 没有等位宽的裸名别名 + (裸 int=int32、裸 float=float32),映射过去会静默窄化/扩宽位宽 + (i64→int 即 i64→i32,直接改变 ABI 与数据),违反"禁止静默默认/兜底" + 原则 ⇒ 一律返回 None,由调用方汇总后 fail-fast 提示显式标注。 """ if pool is None or sp is None: return None buf: str = pool.alloc(32) if buf is None: return None buf[0] = '\0' - if TSpec.SpecToLLVMText(sp, buf, 32) == 0: + # SpecToLLVMText 约定 0=成功 / 1=失败(见 TypeSpec.vp 定义与 ClassGenVTable + # 的 `!= 0` 用法):原判据写成 `== 0` 恰好把"成功"当失败返回 None,导致本 + # 函数对任何内建标量都恒返回 None —— 泛型函数隐式推断里"实参是内建标量的 + # 形参"(如 fxi 体内 fxi2(a, ...),a: double)永远推不出,报 + # "无法从实参推断泛型函数 ... 禁止静默默认 int"。 + if TSpec.SpecToLLVMText(sp, buf, 32) != 0: return None if string.strcmp(buf, "double") == 0: return "double" if string.strcmp(buf, "float") == 0: return "float" - if string.strcmp(buf, "half") == 0: return "float" if string.strcmp(buf, "i1") == 0: return "bool" if string.strcmp(buf, "i8") == 0: return "char" - if string.strcmp(buf, "i16") == 0: return "int" if string.strcmp(buf, "i32") == 0: return "int" - if string.strcmp(buf, "i64") == 0: return "int" return None def _clone_funcdef_for_spec(self, pool: memhub.MemBuddy*,