Issue #728: A float literal is never f32: let y: f32 = 0.5 is NK1103

Open and answer this issue on GitHub.

decision · opened 2026-10-19 · updated 2026-10-20 · 2 comments

Found while building #703 item 1 (0.0.1098).

Probe

fn main() {
    let y: f32 = 0.5
    print(f"{y}")
}

Today: NK1103 “This value is f64 …”. Part I 2.2 allows a float literal in an f32 place, but nothing in the checker types a float literal as f32. The same holds for an argument, a return, a field, and an element of Vec[f32].

A second, smaller finding: let v: Vec[f64] = [1.0, 2] reports both NK1154 and NK1103. It should report only NK1154.

To build

  1. Type a float literal by the place it flows into (f32 or f64, defaulting to f64), the way an integer literal takes its type from its position (Part I 2.4). Tests: let, argument, return, field, Vec[f32] literal, x * 0.5 with x: f32; probes in tests/accepted/ (they must compile in rustc).
  2. [1.0, 2] in a Vec[f64] place reports only NK1154. Add a test asserting the single code.

Comments

keywan-ghadami, 2026-10-20

  1. A float literal pattern (1.5 => …) does not parse. This was found while building #704 item 8. First decide from Part I 3.4 whether a float pattern is part of the language. Rust allows one, with a lint. Then either parse it, with a probe in tests/accepted/, or refuse it with a clear code.

Generated by Claude Code

keywan-ghadami, 2026-10-20

Steps 1 and 2 are built in 0.0.1115:

Step 3, the float literal pattern, needs a decision. Part I 3.4’s table lists integer, text, bool and char patterns, but no float. Whether 1.5 => belongs in the language, and what NaN and -0.0 would mean there, is the owner’s call. Label → decision.

Also found on the way: x as f32 is NK1122, and == on two f32 values is NK1188. Both are filed as #736.


Generated by Claude Code

Back to Open Issues