lang: rename signed integer types sN -> iN
Surface rename of the signed integer family: s1..s64 become i1..i64
(u1..u64, usize, isize unchanged). 'string' keeps the s-prefix arm in
name classification; width parsing moves to the i-prefix arm next to
isize.
Internal TypeId tags follow the surface (.s8/.s16/.s32/.s64 ->
.i8/.i16/.i32/.i64), as do mono-key mangle fragments (ptr_i64,
tu_i64_bool) and all display/diagnostic formatting (i{d}).
Migrated in the same sweep: stdlib + examples + issue repros + FFI C
companions (shared symbol names like ffi_id_i64), expected
stdout/stderr/ir snapshots, specs.md, readme.md, CLAUDE.md/AGENTS.md,
implementation_plan.md, docs/, issue writeups. Vendored stb_image and
historical flow state left untouched.
zig build test: 426/426; examples suite: 595/595.
This commit is contained in:
@@ -12,8 +12,8 @@ const types = @import("types.zig");
|
||||
const Type = types.Type;
|
||||
|
||||
// the backtick raw escape must hold in BOTH classifiers. A raw
|
||||
// reserved-name type reference (`` `s2 ``) resolves to the user-declared type,
|
||||
// while a BARE `s2` stays the builtin int. Before the fix sema's
|
||||
// reserved-name type reference (`` `i2 ``) resolves to the user-declared type,
|
||||
// while a BARE `i2` stays the builtin int. Before the fix sema's
|
||||
// `resolveTypeNode` ran `Type.fromName` first and ignored `is_raw`, so the
|
||||
// editor index would show the builtin for backtick code (the
|
||||
// two-resolver divergence applied to raw types).
|
||||
@@ -23,7 +23,7 @@ test "sema: backtick raw type reference resolves to the user type; bare stays bu
|
||||
const alloc = arena.allocator();
|
||||
|
||||
const src =
|
||||
\\`s2 :: struct { x: s64; }
|
||||
\\`i2 :: struct { x: i64; }
|
||||
\\
|
||||
;
|
||||
var parser = Parser.init(alloc, src);
|
||||
@@ -33,16 +33,16 @@ test "sema: backtick raw type reference resolves to the user type; bare stays bu
|
||||
_ = try analyzer.analyze(root);
|
||||
|
||||
// The reserved-spelled user type registered under its plain name.
|
||||
try std.testing.expect(analyzer.struct_types.contains("s2"));
|
||||
try std.testing.expect(analyzer.struct_types.contains("i2"));
|
||||
|
||||
// RAW reference (`` `s2 ``) → the user struct, NOT the 2-bit signed int.
|
||||
var raw_node = Node{ .span = .{ .start = 0, .end = 0 }, .data = .{ .type_expr = .{ .name = "s2", .is_raw = true } } };
|
||||
// RAW reference (`` `i2 ``) → the user struct, NOT the 2-bit signed int.
|
||||
var raw_node = Node{ .span = .{ .start = 0, .end = 0 }, .data = .{ .type_expr = .{ .name = "i2", .is_raw = true } } };
|
||||
const raw_ty = analyzer.resolveTypeNode(&raw_node);
|
||||
try std.testing.expect(raw_ty == .struct_type);
|
||||
try std.testing.expectEqualStrings("s2", raw_ty.struct_type);
|
||||
try std.testing.expectEqualStrings("i2", raw_ty.struct_type);
|
||||
|
||||
// BARE `s2` → the builtin 2-bit signed int.
|
||||
var bare_node = Node{ .span = .{ .start = 0, .end = 0 }, .data = .{ .type_expr = .{ .name = "s2", .is_raw = false } } };
|
||||
// BARE `i2` → the builtin 2-bit signed int.
|
||||
var bare_node = Node{ .span = .{ .start = 0, .end = 0 }, .data = .{ .type_expr = .{ .name = "i2", .is_raw = false } } };
|
||||
const bare_ty = analyzer.resolveTypeNode(&bare_node);
|
||||
try std.testing.expect(bare_ty == .signed);
|
||||
try std.testing.expectEqual(@as(u8, 2), bare_ty.signed);
|
||||
@@ -58,7 +58,7 @@ test "sema: a raw struct-field annotation resolves to the user type; bare stays
|
||||
const alloc = arena.allocator();
|
||||
|
||||
const src =
|
||||
\\`u8 :: struct { y: s64; }
|
||||
\\`u8 :: struct { y: i64; }
|
||||
\\Holder :: struct { a: `u8; b: u8; }
|
||||
\\
|
||||
;
|
||||
@@ -87,12 +87,12 @@ test "sema: a raw struct-field annotation resolves to the user type; bare stays
|
||||
|
||||
// ── raw provenance through sema's COMPOUND type metadata ────────
|
||||
//
|
||||
// The direct-case fix (above) only covered a bare `` `s2 `` reference. A
|
||||
// COMPOUND raw type (`*`s2`, `?`s2`, `[N]`s2`, …) stores its inner name as a
|
||||
// The direct-case fix (above) only covered a bare `` `i2 `` reference. A
|
||||
// COMPOUND raw type (`*`i2`, `?`i2`, `[N]`i2`, …) stores its inner name as a
|
||||
// bare string on the Type's info struct; the resolver re-reads that name via
|
||||
// `resolveTypeNameStr`. Before threading `is_raw` ALONGSIDE the stored name,
|
||||
// the resolver passed `skip_builtin = false`, so the LSP index reclassified a
|
||||
// user type named `s2` as the builtin int — diverging from codegen. These
|
||||
// user type named `i2` as the builtin int — diverging from codegen. These
|
||||
// pin every compound form: the raw inner resolves to the user type (FAILS on
|
||||
// pre-fix sema), the bare inner stays the builtin (control, preserved).
|
||||
|
||||
@@ -103,15 +103,15 @@ fn symType(res: sema.SemaResult, name: []const u8) ?Type {
|
||||
return null;
|
||||
}
|
||||
|
||||
test "sema: field access through a raw `*`s2` pointer resolves the user field; bare `*s2` stays builtin" {
|
||||
test "sema: field access through a raw `*`i2` pointer resolves the user field; bare `*i2` stays builtin" {
|
||||
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena.deinit();
|
||||
const alloc = arena.allocator();
|
||||
|
||||
const src =
|
||||
\\`s2 :: struct { x: s64; }
|
||||
\\f :: (p: *`s2) { y := p.x; }
|
||||
\\g :: (q: *s2) { w := q.*; }
|
||||
\\`i2 :: struct { x: i64; }
|
||||
\\f :: (p: *`i2) { y := p.x; }
|
||||
\\g :: (q: *i2) { w := q.*; }
|
||||
\\
|
||||
;
|
||||
var parser = Parser.init(alloc, src);
|
||||
@@ -119,27 +119,27 @@ test "sema: field access through a raw `*`s2` pointer resolves the user field; b
|
||||
var analyzer = sema.Analyzer.init(alloc);
|
||||
const res = try analyzer.analyze(root);
|
||||
|
||||
// RAW: `p: *`s2` → field `x` on the user struct → s64. (Pre-fix: the
|
||||
// pointee `s2` reclassified to the 2-bit int, `.x` not found → unresolved.)
|
||||
// RAW: `p: *`i2` → field `x` on the user struct → i64. (Pre-fix: the
|
||||
// pointee `i2` reclassified to the 2-bit int, `.x` not found → unresolved.)
|
||||
const y = symType(res, "y") orelse return error.MissingSymbol;
|
||||
try std.testing.expect(y == .signed);
|
||||
try std.testing.expectEqual(@as(u8, 64), y.signed);
|
||||
|
||||
// CONTROL: `q: *s2` (bare) → deref yields the builtin 2-bit signed int.
|
||||
// CONTROL: `q: *i2` (bare) → deref yields the builtin 2-bit signed int.
|
||||
const w = symType(res, "w") orelse return error.MissingSymbol;
|
||||
try std.testing.expect(w == .signed);
|
||||
try std.testing.expectEqual(@as(u8, 2), w.signed);
|
||||
}
|
||||
|
||||
test "sema: unwrapping a raw `?`s2` optional resolves the user field; bare `?s2` stays builtin" {
|
||||
test "sema: unwrapping a raw `?`i2` optional resolves the user field; bare `?i2` stays builtin" {
|
||||
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena.deinit();
|
||||
const alloc = arena.allocator();
|
||||
|
||||
const src =
|
||||
\\`s2 :: struct { x: s64; }
|
||||
\\f :: (o: ?`s2) { if val := o { y := val.x; } }
|
||||
\\g :: (b: ?s2) { if v := b { w := v; } }
|
||||
\\`i2 :: struct { x: i64; }
|
||||
\\f :: (o: ?`i2) { if val := o { y := val.x; } }
|
||||
\\g :: (b: ?i2) { if v := b { w := v; } }
|
||||
\\
|
||||
;
|
||||
var parser = Parser.init(alloc, src);
|
||||
@@ -147,26 +147,26 @@ test "sema: unwrapping a raw `?`s2` optional resolves the user field; bare `?s2`
|
||||
var analyzer = sema.Analyzer.init(alloc);
|
||||
const res = try analyzer.analyze(root);
|
||||
|
||||
// RAW: `o: ?`s2` → `if val := o` unwraps to the user struct → `val.x` is s64.
|
||||
// (Pre-fix: the optional child `s2` reclassified to the 2-bit int.)
|
||||
// RAW: `o: ?`i2` → `if val := o` unwraps to the user struct → `val.x` is i64.
|
||||
// (Pre-fix: the optional child `i2` reclassified to the 2-bit int.)
|
||||
const y = symType(res, "y") orelse return error.MissingSymbol;
|
||||
try std.testing.expect(y == .signed);
|
||||
try std.testing.expectEqual(@as(u8, 64), y.signed);
|
||||
|
||||
// CONTROL: `b: ?s2` (bare) unwraps to the builtin 2-bit signed int.
|
||||
// CONTROL: `b: ?i2` (bare) unwraps to the builtin 2-bit signed int.
|
||||
const w = symType(res, "w") orelse return error.MissingSymbol;
|
||||
try std.testing.expect(w == .signed);
|
||||
try std.testing.expectEqual(@as(u8, 2), w.signed);
|
||||
}
|
||||
|
||||
test "sema: indexing a raw `[N]`s2` array resolves the user element; bare `[N]s2` stays builtin" {
|
||||
test "sema: indexing a raw `[N]`i2` array resolves the user element; bare `[N]i2` stays builtin" {
|
||||
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena.deinit();
|
||||
const alloc = arena.allocator();
|
||||
|
||||
const src =
|
||||
\\`s2 :: struct { x: s64; }
|
||||
\\f :: (a: [4]`s2, b: [4]s2) { y := a[0]; w := b[0]; }
|
||||
\\`i2 :: struct { x: i64; }
|
||||
\\f :: (a: [4]`i2, b: [4]i2) { y := a[0]; w := b[0]; }
|
||||
\\
|
||||
;
|
||||
var parser = Parser.init(alloc, src);
|
||||
@@ -174,32 +174,32 @@ test "sema: indexing a raw `[N]`s2` array resolves the user element; bare `[N]s2
|
||||
var analyzer = sema.Analyzer.init(alloc);
|
||||
const res = try analyzer.analyze(root);
|
||||
|
||||
// RAW: `a: [4]`s2` → element is the user struct. (Pre-fix: reclassified to
|
||||
// RAW: `a: [4]`i2` → element is the user struct. (Pre-fix: reclassified to
|
||||
// the 2-bit int.)
|
||||
const y = symType(res, "y") orelse return error.MissingSymbol;
|
||||
try std.testing.expect(y == .struct_type);
|
||||
try std.testing.expectEqualStrings("s2", y.struct_type);
|
||||
try std.testing.expectEqualStrings("i2", y.struct_type);
|
||||
|
||||
// CONTROL: `b: [4]s2` (bare) → element is the builtin 2-bit signed int.
|
||||
// CONTROL: `b: [4]i2` (bare) → element is the builtin 2-bit signed int.
|
||||
const w = symType(res, "w") orelse return error.MissingSymbol;
|
||||
try std.testing.expect(w == .signed);
|
||||
try std.testing.expectEqual(@as(u8, 2), w.signed);
|
||||
}
|
||||
|
||||
// Parameterized raw type (`` `s2(s64) ``). Unlike the shapes above this never
|
||||
// Parameterized raw type (`` `i2(i64) ``). Unlike the shapes above this never
|
||||
// had the divergence — instantiation resolves the base name straight against
|
||||
// `struct_types` (no builtin classifier in the path), so it passes before AND
|
||||
// after. Included as coverage that the universal model holds for the
|
||||
// parameterized form too: a `` `s2 ``-declared generic instantiates and its
|
||||
// parameterized form too: a `` `i2 ``-declared generic instantiates and its
|
||||
// field resolves.
|
||||
test "sema: a raw parameterized type `` `s2(s64) `` instantiates the user generic" {
|
||||
test "sema: a raw parameterized type `` `i2(i64) `` instantiates the user generic" {
|
||||
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena.deinit();
|
||||
const alloc = arena.allocator();
|
||||
|
||||
const src =
|
||||
\\`s2 :: struct ($T: Type) { items: [*]T = null; n: s64 = 0; }
|
||||
\\f :: (v: `s2(s64)) { y := v.n; }
|
||||
\\`i2 :: struct ($T: Type) { items: [*]T = null; n: i64 = 0; }
|
||||
\\f :: (v: `i2(i64)) { y := v.n; }
|
||||
\\
|
||||
;
|
||||
var parser = Parser.init(alloc, src);
|
||||
@@ -207,8 +207,8 @@ test "sema: a raw parameterized type `` `s2(s64) `` instantiates the user generi
|
||||
var analyzer = sema.Analyzer.init(alloc);
|
||||
const res = try analyzer.analyze(root);
|
||||
|
||||
// `v: `s2(s64)` instantiates the `` `s2 ``-declared generic; its concrete
|
||||
// field `n` resolves to s64 (the raw base name was not misread as a builtin).
|
||||
// `v: `i2(i64)` instantiates the `` `i2 ``-declared generic; its concrete
|
||||
// field `n` resolves to i64 (the raw base name was not misread as a builtin).
|
||||
const y = symType(res, "y") orelse return error.MissingSymbol;
|
||||
try std.testing.expect(y == .signed);
|
||||
try std.testing.expectEqual(@as(u8, 64), y.signed);
|
||||
|
||||
Reference in New Issue
Block a user