fix(narrow): HandlesAnnAssign._StoreWithCoerce 补注解式整数窄化 fail-fast

此前该路径对整数窄化静默 trunc,导致 x: <32位> = <64位> 注解声明绕过规则;现与 MemoryOps._coerce_value 同口径:豁免 i1 归一化与落进目标位宽的编译期常量,其余抛 FailFastError
This commit is contained in:
TermiNexus committed 2026-10-11 09:51:03 +08:00
1 parent 3b16334f5d
commit 815a6245a5
1 file changed
+12 -1
+12 -1
View File
@@ -281,8 +281,19 @@ class AnnAssignHandle(BaseHandle):
# 不是 trunc 取最低位(运行时值 2 会得 false,与 `if 2:` 相反)
if TargetType.width == 1:
Value = Gen._CoerceIntToI1(Value, name="bool_norm")
# 隐式窄化**禁止**(与 MemoryOps._coerce_value 同口径,规则 2026-10-10):
# 位宽高→低会丢高位,必须显式 cast 或加宽目标类型。
# 唯一豁免:源是**编译期常量且值落进目标位宽**(无信息损失)。
elif (isinstance(Value, ir.Constant) and isinstance(Value.constant, int)
and -(1 << (TargetType.width - 1)) <= Value.constant <= (1 << TargetType.width) - 1):
Value = Gen.builder.trunc(Value, TargetType, name="trunc_const")
else:
Value = Gen.builder.trunc(Value, TargetType, name="trunc")
from lib.core.LLVMCG.FuncGen import FailFastError
raise FailFastError(
f"隐式窄化禁止:{Value.type.width} 位整数不能隐式赋给 {TargetType.width} 位类型"
f"(会丢高位);请显式转换(如 int32(x) / t.CInt32T(x) )或把目标类型加宽"
f"{Gen._DescribeValueNode(Node)}"
)
else:
Value = Gen.builder.zext(Value, TargetType, name="zext")
elif isinstance(TargetType, ir.PointerType) and isinstance(Value.type, ir.PointerType):