fix(lang): numeric-limit intercept no longer shadows raw value bindings [NL.2]
The numeric-limit accessor intercept (NL.1 integer `.min`/`.max`, NL.2 float `.epsilon`/`.min_positive`/`.true_min`/`.inf`/`.nan`) treated ANY receiver whose text matched a builtin numeric type name as a TYPE receiver, without first checking for an in-scope VALUE binding. An F0.6 backtick raw identifier (`` `f64 := … ``) binds a local under the stripped name `f64`; field access on it (`` `f64.epsilon ``) parses as an `.identifier` receiver, which the intercept silently folded to the type's numeric limit — a silent-wrong-value bug (issue 0092). Fix: for `.identifier` receivers, prefer an in-scope value binding (`Scope.lookup`) over the fold — defer to ordinary field lowering when the identifier resolves to a value. `.type_expr` receivers are unambiguous types and are never shadowed, so a bare `f64.epsilon`/`s32.max` still folds even in a scope where `` `f64 `` is bound (the parser classifies a bare builtin name as a `.type_expr`). Mirrored in expr_typer.zig so inference matches lowering (avoids the issue-0083 two-resolver desync). Float-only-on-int and non-numeric-receiver errors are unchanged. - src/ir/lower.zig: value-binding guard in lowerNumericLimit. - src/ir/expr_typer.zig: same guard in the numeric-limit inference arm. - src/ir/expr_typer.test.zig: unit test pinning the two-resolver agreement. - examples/0161-types-numeric-limit-value-shadow.sx: regression — raw `` `f64 ``/`` `s32 ``/`` `u8 `` value reads coexisting with bare folds. - issues/0092: RESOLVED banner. - specs.md / readme.md: receiver-vs-shadowing-value-binding note.
This commit is contained in:
@@ -96,7 +96,10 @@ C's `DBL_MIN`) plus the float-only `.epsilon` (ULP of 1.0, not C#'s denormal
|
||||
`Epsilon`), `.min_positive` (smallest normal = C `DBL_MIN`), `.true_min` (smallest
|
||||
subnormal — beware flush-to-zero CPU modes), `.inf`, and `.nan`. A float-only
|
||||
accessor on an integer (`s32.epsilon`), or any accessor on a non-numeric type, is
|
||||
a clean compile error. See `specs.md` → Numeric Limits.
|
||||
a clean compile error. The fold applies only to a bare type-name receiver: a raw
|
||||
identifier that binds a value shadowing a type name (`` `f64 := … `` then
|
||||
`` `f64.epsilon ``) reads the value's field, not the limit. See `specs.md` →
|
||||
Numeric Limits.
|
||||
|
||||
### Declarations
|
||||
|
||||
|
||||
Reference in New Issue
Block a user