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:
agra
2026-06-12 09:31:53 +03:00
parent 515ecebea7
commit d8076b9333
1054 changed files with 6836 additions and 6839 deletions

View File

@@ -197,7 +197,7 @@ pub const Analyzer = struct {
// Variadic param becomes a slice type
const elem_name = switch (param.type_expr.data) {
.type_expr => |te| te.name,
// `..xs: []T` — the element is T, not a guessed s32.
// `..xs: []T` — the element is T, not a guessed i32.
.slice_type_expr => |st| if (st.element_type.data == .type_expr) st.element_type.data.type_expr.name else "<unresolved>",
else => "<unresolved>",
};
@@ -447,7 +447,7 @@ pub const Analyzer = struct {
return .void_type;
}
// type_expr or identifier — check aliases, enums, structs. A raw
// reference (`` `s2 ``) skips the builtin classifier and resolves
// reference (`` `i2 ``) skips the builtin classifier and resolves
// through user-defined types only.
if (tn.data == .type_expr or tn.data == .identifier) {
const name = if (tn.data == .type_expr) tn.data.type_expr.name else tn.data.identifier.name;
@@ -471,7 +471,7 @@ pub const Analyzer = struct {
/// structs), falling back to primitive spellings. Unlike `Type.fromName`,
/// this knows user-defined types; returns `unresolved` when it can't place
/// the name. `skip_builtin` is the backtick raw escape — a raw
/// reference (`` `s2 ``) bypasses the builtin/reserved classifier and
/// reference (`` `i2 ``) bypasses the builtin/reserved classifier and
/// resolves only through user-defined types, mirroring the codegen-side
/// `TypeResolver.resolveNamed`. Inner names of compound shapes
/// (pointer/slice element/pointee) are always bare, so their callers pass
@@ -501,10 +501,10 @@ pub const Analyzer = struct {
};
}
/// The backtick raw bit of an inner type-name node (`` `s2 ``). A compound
/// The backtick raw bit of an inner type-name node (`` `i2 ``). A compound
/// shape (`*T`, `?T`, `[]T`, …) stores its inner name as a bare string, so
/// this bit must travel ALONGSIDE that name — otherwise the
/// resolver re-reads `s2` as the builtin int. Non-leaf nodes are never raw.
/// resolver re-reads `i2` as the builtin int. Non-leaf nodes are never raw.
fn typeExprIsRaw(node: *Node) bool {
return switch (node.data) {
.type_expr => |te| te.is_raw,
@@ -516,7 +516,7 @@ pub const Analyzer = struct {
/// When a compound shape stores the NAME of an ALREADY-resolved inner type
/// (no syntactic node to read `is_raw` from — e.g. a for-loop element), a
/// user nominal type must be re-resolved with `skip_builtin` so a struct/
/// enum/union named `s2` is not reclassified as the builtin. Builtins keep
/// enum/union named `i2` is not reclassified as the builtin. Builtins keep
/// `false`. Harmless for non-colliding names (the registry lookup is the
/// same either way).
fn innerNameIsRaw(inner: Type) bool {
@@ -768,7 +768,7 @@ pub const Analyzer = struct {
if (self.struct_types.contains(target)) return .{ .struct_type = target };
}
} else if (sl.type_expr) |te| {
// Handle parameterized struct: List(s32).{} parses as call node
// Handle parameterized struct: List(i32).{} parses as call node
if (te.data == .call) {
if (self.resolveCalleeName(te.data.call)) |callee| {
if (self.instantiateGeneric(callee, te.data.call.args)) |inst| return inst;
@@ -1925,7 +1925,7 @@ test "sema: collect top-level declarations" {
test "sema: function params as symbols" {
const parser_mod = @import("parser.zig");
const source = "add :: (a: s32, b: s32) -> s32 { a + b; }";
const source = "add :: (a: i32, b: i32) -> i32 { a + b; }";
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();
@@ -2020,7 +2020,7 @@ test "sema: enum and struct declarations" {
test "sema: var_decl infers struct type from parameterized struct literal" {
const parser_mod = @import("parser.zig");
const source = "List :: struct { len: s64; } main :: () { list := List.{}; }";
const source = "List :: struct { len: i64; } main :: () { list := List.{}; }";
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();
@@ -2050,8 +2050,8 @@ test "sema: var_decl infers struct type from parameterized struct literal" {
test "sema: var_decl infers struct type from parameterized call literal" {
const parser_mod = @import("parser.zig");
// List(s32).{} — parser produces struct_literal with type_expr = call node
const source = "List :: struct { len: s64; } main :: () { list := List(s32).{}; }";
// List(i32).{} — parser produces struct_literal with type_expr = call node
const source = "List :: struct { len: i64; } main :: () { list := List(i32).{}; }";
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();
@@ -2081,8 +2081,8 @@ test "sema: index into generic List(T).items resolves the element struct" {
const parser_mod = @import("parser.zig");
const source =
"Move :: struct { score: s64; }" ++
"List :: struct ($T: Type) { items: [*]T = null; len: s64; }" ++
"Move :: struct { score: i64; }" ++
"List :: struct ($T: Type) { items: [*]T = null; len: i64; }" ++
"main :: () { legal := List(Move).{}; m := legal.items[0]; }";
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
@@ -2114,8 +2114,8 @@ test "sema: generic index resolves with pre-registered (imported) struct types"
const alloc = arena.allocator();
// An "imported" module defining List + Move.
const lib_src = "Move :: struct { score: s64; }" ++
"List :: struct ($T: Type) { items: [*]T = null; len: s64; }";
const lib_src = "Move :: struct { score: i64; }" ++
"List :: struct ($T: Type) { items: [*]T = null; len: i64; }";
var lib_parser = parser_mod.Parser.init(alloc, lib_src);
const lib_root = try lib_parser.parse();
var lib = Analyzer.init(alloc);
@@ -2152,10 +2152,10 @@ test "sema: generic index resolves with realistic List/Move (methods, cross-refs
const alloc = arena.allocator();
const lib_src =
"Square :: struct { index: s64; }" ++
"Square :: struct { index: i64; }" ++
"MoveFlag :: enum { none; promote_rook; }" ++
"Move :: struct { from: Square; to: Square; flag: MoveFlag; is_capture :: (self: Move) -> bool { true; } }" ++
"List :: struct ($T: Type) { items: [*]T = null; len: s64 = 0; cap: s64 = 0; append :: (list: *List(T), item: T) {} }";
"List :: struct ($T: Type) { items: [*]T = null; len: i64 = 0; cap: i64 = 0; append :: (list: *List(T), item: T) {} }";
var lib_parser = parser_mod.Parser.init(alloc, lib_src);
const lib_root = try lib_parser.parse();
var lib = Analyzer.init(alloc);
@@ -2191,7 +2191,7 @@ test "sema: method-return slice + .ptr index + tagged-enum element" {
const alloc = arena.allocator();
const source =
"Event :: enum { none; click: s64; }" ++
"Event :: enum { none; click: i64; }" ++
"Plat :: protocol { poll :: () -> []Event; }" ++
"go :: (p: *Plat) { evs := p.poll(); e := evs.ptr[0]; }";
var parser = parser_mod.Parser.init(alloc, source);
@@ -2220,7 +2220,7 @@ test "sema: field access + index through a *Struct param" {
const alloc = arena.allocator();
const source =
"Cell :: struct { v: s64; }" ++
"Cell :: struct { v: i64; }" ++
"Grid :: struct { cells: [4]Cell; }" ++
"look :: (g: *Grid) { c := g.cells[0]; }";
var parser = parser_mod.Parser.init(alloc, source);
@@ -2243,8 +2243,8 @@ test "sema: for-loop captures resolve element, by-ref pointer, and range cursor"
const alloc = arena.allocator();
const source =
"Move :: struct { flag: s64; }" ++
"List :: struct ($T: Type) { items: [*]T = null; len: s64 = 0; }" ++
"Move :: struct { flag: i64; }" ++
"List :: struct ($T: Type) { items: [*]T = null; len: i64 = 0; }" ++
"Game :: struct { legal: List(Move);" ++
" scan :: (self: *Game) {" ++
" for self.legal (m) { a := m.flag; }" ++
@@ -2271,7 +2271,7 @@ test "sema: for-loop captures resolve element, by-ref pointer, and range cursor"
// by-ref capture yields a pointer to the element.
try std.testing.expect(p_ty != null and p_ty.? == .pointer_type);
try std.testing.expectEqualStrings("Move", p_ty.?.pointer_type.pointee_name);
// range cursor is s64.
// range cursor is i64.
try std.testing.expect(i_ty != null and i_ty.? == .signed);
try std.testing.expect(i_ty.?.signed == 64);
@@ -2303,11 +2303,11 @@ test "sema: passing *T where a T value is expected is diagnosed" {
const alloc = arena.allocator();
const source =
"Move :: struct { flag: s64; }" ++
"take :: (m: Move) -> s64 { m.flag; }" ++
"take_ptr :: (m: *Move) -> s64 { m.flag; }" ++
"bad :: (p: *Move) -> s64 { take(p); }" ++ // *Move into a Move param → flagged
"good :: (p: *Move) -> s64 { take_ptr(p); }"; // *Move into a *Move param → fine
"Move :: struct { flag: i64; }" ++
"take :: (m: Move) -> i64 { m.flag; }" ++
"take_ptr :: (m: *Move) -> i64 { m.flag; }" ++
"bad :: (p: *Move) -> i64 { take(p); }" ++ // *Move into a Move param → flagged
"good :: (p: *Move) -> i64 { take_ptr(p); }"; // *Move into a *Move param → fine
var parser = parser_mod.Parser.init(alloc, source);
const root = try parser.parse();
var an = Analyzer.init(alloc);
@@ -2329,7 +2329,7 @@ test "sema: member references record fields, methods, and enum variants" {
const source =
"Color :: enum { red; green; }" ++
"P :: struct { x: s64; m :: (self: P) -> s64 { self.x; } }" ++
"P :: struct { x: i64; m :: (self: P) -> i64 { self.x; } }" ++
"use :: (p: *P) { a := p.x; b := p.m(); c := Color.red; }";
var parser = parser_mod.Parser.init(alloc, source);
const root = try parser.parse();
@@ -2358,9 +2358,9 @@ test "sema: context in a callconv(.c) function reports a specific diagnostic" {
const alloc = arena.allocator();
const source =
"Context :: struct { allocator: s64; data: s64; }" ++
"cb :: () -> s64 callconv(.c) { context; 0; }" ++
"ok :: () -> s64 { context; 0; }";
"Context :: struct { allocator: i64; data: i64; }" ++
"cb :: () -> i64 callconv(.c) { context; 0; }" ++
"ok :: () -> i64 { context; 0; }";
var parser = parser_mod.Parser.init(alloc, source);
const root = try parser.parse();
var an = Analyzer.init(alloc);
@@ -2381,7 +2381,7 @@ test "sema: variable shadowing in same scope is allowed" {
const parser_mod = @import("parser.zig");
// Two variables with the same name in the same function body — sx allows this
const source = "main :: () { x : s64 = 1; x : f64 = 2.0; }";
const source = "main :: () { x : i64 = 1; x : f64 = 2.0; }";
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();
@@ -2403,7 +2403,7 @@ test "sema: variable shadowing in same scope is allowed" {
test "sema: ufcs_alias registers symbol" {
const parser_mod = @import("parser.zig");
const source = "add :: (a: s64, b: s64) -> s64 { a + b; } main :: () { sum :: ufcs add; sum(1, 2); }";
const source = "add :: (a: i64, b: i64) -> i64 { a + b; } main :: () { sum :: ufcs add; sum(1, 2); }";
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();
@@ -2436,7 +2436,7 @@ test "sema: ufcs_alias registers symbol" {
test "sema: top-level ufcs_alias registers symbol" {
const parser_mod = @import("parser.zig");
const source = "add :: (a: s64, b: s64) -> s64 { a + b; } sum :: ufcs add;";
const source = "add :: (a: i64, b: i64) -> i64 { a + b; } sum :: ufcs add;";
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();