authorgravatar for justus@klausecker.deJustus Klausecker <justus@klausecker.de> 2026-05-09 12:19:13+02:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-06-11 12:08:45+02:00
logffac200e66a493907270a02404bcd4ee1898eb3a
treea5e0e8033d84c0fc7af72b2c9172ac5f0d2425a3
parent5537704f6061c7ea9f7bfb6302a380b04978e2ad

AstGen: move check for primitive integer type with leading zero

Identifiers like `u0_` should be legal but were previously rejected because they were spuriously interpreted as primitive integer type identifiers. Now the integer is first parsed and only if that succeeds it's checked for a leading zero.

3 files changed, 26 insertions(+), 8 deletions(-)

lib/std/zig/AstGen.zig+8-8
......@@ -8069,14 +8069,6 @@ fn identifier(
80698069 if (std.mem.eql(u8, ident_name_raw, "i0")) {
80708070 return astgen.failNode(ident, "signed integer cannot have bit width 0", .{});
80718071 }
8072 if (ident_name_raw[1] == '0') {
8073 assert(ident_name_raw.len >= 3); // `u0` and `i0` handled
8074 return astgen.failNode(
8075 ident,
8076 "primitive integer type '{s}' has leading zero",
8077 .{ident_name_raw},
8078 );
8079 }
80808072 const bit_count = parseBitCount(ident_name_raw[1..]) catch |err| switch (err) {
80818073 error.Overflow => return astgen.failNode(
80828074 ident,
......@@ -8085,6 +8077,14 @@ fn identifier(
80858077 ),
80868078 error.InvalidCharacter => break :int_type,
80878079 };
8080 if (ident_name_raw[1] == '0') {
8081 assert(ident_name_raw.len >= 3); // `u0` and `i0` handled
8082 return astgen.failNode(
8083 ident,
8084 "primitive integer type '{s}' has leading zero",
8085 .{ident_name_raw},
8086 );
8087 }
80888088 const result = try gz.add(.{
80898089 .tag = .int_type,
80908090 .data = .{ .int_type = .{
test/behavior/basic.zig+11
......@@ -1437,3 +1437,14 @@ test "loading array from struct is not optimized away" {
14371437 var s = S{};
14381438 try s.doTheTest();
14391439}
1440
1441test "local variable name begins with primitive integer type" {
1442 const u032_ = 123;
1443 comptime assert(u032_ == 123);
1444
1445 const u0_ = 456;
1446 comptime assert(u0_ == 456);
1447
1448 const i0_ = 789;
1449 comptime assert(i0_ == 789);
1450}
test/cases/compile_errors/primitive_integer_type_with_leading_zero.zig created+7
......@@ -0,0 +1,7 @@
1export fn entry1() void {
2 _ = u032;
3}
4
5// error
6//
7// :2:9: error: primitive integer type 'u032' has leading zero