issues: promote 6 fixed bug repros to focused regression tests

All six produce their target outputs cleanly today; renamed out of
the `issue-*` namespace per CLAUDE.md "Resolving an open issue":

| Old                  | New                                       |
|----------------------|-------------------------------------------|
| issue-0032           | 181-impl-duplicate-same-file              |
| issue-0041           | 182-compound-type-in-expression           |
| issue-0042           | 183-type-alias-size-align                 |
| issue-0044           | 184-objc-defined-class-method-self        |
| issue-0045           | 185-pack-fn-comptime-return               |
| issue-0046           | 186-nested-comptime-return                |

Comment headers tightened to feature-focused (drop the issue-NNNN
provenance — that's in git history now). Missing expected `.txt` /
`.exit` files captured for 0041 + 0042 (they were untracked because
the bugs were fixed silently in adjacent work).

`examples/issue-*` after this commit: just `issue-0030.sx` — a
feature request (`extern G : T;` cross-file globals) that's never
been implemented. Staying in the issue namespace as a parked
proposal until the feature lands or gets formally rejected.

220/220 example tests + `zig build test` green.
This commit is contained in:
agra
2026-05-28 12:14:52 +03:00
parent 5a5b12d42d
commit 280c12c630
20 changed files with 73 additions and 47 deletions

View File

@@ -0,0 +1,19 @@
// Duplicate impl detection (same-file) — two `impl Into(MyA) for s64`
// declarations in the same file produce a "duplicate impl" diagnostic
// at registration time, not silently shadow one with the other. Sibling
// case to `examples/180-impl-duplicate.sx` which covers the
// cross-module variant.
#import "modules/std.sx";
MyA :: struct { v: s64 = 0; }
impl Into(MyA) for s64 {
convert :: (self: s64) -> MyA { .{ v = self }; }
}
impl Into(MyA) for s64 {
convert :: (self: s64) -> MyA { .{ v = self * 2 }; }
}
main :: () -> s32 { 0; }

View File

@@ -1,5 +1,8 @@
// issue-0041 — Pointer / optional / array / function / tuple types as // Compound type literals in expression position — `size_of` /
// expression-position values (size_of / align_of arg, const-decl RHS). // `align_of` accept pointer (`*T`), optional (`?T`), array (`[N]T`),
// function (`(A) -> B`), and tuple (`(A, B)`) types directly. Also
// const-decl RHS aliases through the same forms (`Ptr :: *u8;` etc).
// Same shape as the existing `size_of(s32)` baseline path.
#import "modules/std.sx"; #import "modules/std.sx";

View File

@@ -1,8 +1,8 @@
// issue-0042 — const-decl type alias must resolve through // Type alias resolution through `size_of` / `align_of` — a const-decl
// `type_alias_map` when used as a `$T: Type` argument to size_of / // alias (`MyInt :: s32;`, `MyChain :: MyInt;`, `WideAlias :: Wide;`)
// align_of, not silently fall back to .s64 (8 bytes). // resolves through `type_alias_map` when used as a `$T: Type` argument.
// Also covers identifier-RHS aliases (chains + struct aliases), // Covers chains and struct-name aliases, not just structural-type
// not just *T / [N]T / ?T forms. // aliases (those land in `examples/182-compound-type-in-expression.sx`).
#import "modules/std.sx"; #import "modules/std.sx";
MyInt :: s32; MyInt :: s32;

View File

@@ -1,15 +1,13 @@
// issue-0044 — `xx this` inside a BOOL-returning #objc_class method // `xx self` inside a BOOL-returning `#objc_class` method must
// truncated to i8 when used as an argument to a foreign-class method // resolve to the full receiver pointer at a foreign-class method
// call. Root cause was resolveCallParamTypes returning an empty slice // call site, not get truncated to i8 by the enclosing function's
// for foreign-class method receivers (the type was a `#foreign // BOOL return type. Regression locks in the
// #objc_class` alias), so the per-arg target_type defaulted to the // `resolveCallParamTypes` fix that threads foreign-class method
// enclosing function's return type (BOOL → i8) and the `xx ptr` cast // param types correctly even when the receiver is a `#foreign
// silently truncated the pointer to its low byte. // #objc_class` alias. Every probe round-trips the receiver pointer
// // — a regression would read only the low byte and the observer
// Verification: every probe must round-trip the receiver pointer. A // pointer would appear as e.g. 0xC0 / 0x20 instead of its real
// pre-fix compiler reads the LOW BYTE of `xx this` at the // 64-bit value.
// `addObserver:selector:name:object:` call site, so the observer
// would be e.g. 0xC0/0x20 instead of the real pointer.
#import "modules/std.sx"; #import "modules/std.sx";
#import "modules/std/objc.sx"; #import "modules/std/objc.sx";
#import "modules/compiler.sx"; #import "modules/compiler.sx";

View File

@@ -1,6 +1,9 @@
// issue-0045 — calling a comptime fn whose body is a block // Pack-fn (or any comptime-param fn) with a block body containing
// containing an explicit `return X;` trips LLVM's "Terminator found // an explicit `return X;` lowers to clean IR — the inline-return
// in the middle of a basic block" verifier. // path stores into a dedicated result slot and branches to the
// shared `ret_done` block instead of emitting a `ret` inside the
// caller's basic block. Without that, LLVM's verifier rejected the
// IR with "Terminator found in the middle of a basic block".
// //
// Surfaced by the variadic heterogeneous type packs feature (step // Surfaced by the variadic heterogeneous type packs feature (step
// 1 made `..$args` parseable, so the simplest pack-fn smoke test // 1 made `..$args` parseable, so the simplest pack-fn smoke test

View File

@@ -1,10 +1,11 @@
// issue-0046 — nested comptime call + return: state leak from // Nested comptime call + return — a comptime fn (`$x: s32`) whose
// outer `lowerComptimeCall` into the wrapper fn built by // body contains BOTH a nested comptime call (`print`) AND a
// `createComptimeFunction`. Without saving/restoring // `return X;` statement must lower cleanly. The wrapper fn built
// `inline_return_target`, the wrapper inherits an inline-return // by `createComptimeFunction` saves/restores `inline_return_target`
// slot belonging to a different basic block; the interp executes // so it doesn't inherit a slot belonging to the OUTER caller's
// the wrapper and trips a null-pointer store at // basic block. Pre-fix: interp executed the wrapper with a
// `storeAtRawPtr`. // stale-frame inline-return slot and tripped a null-pointer store
// at `storeAtRawPtr`.
// //
// Repro: comptime fn (`$x: s32`) whose body has BOTH a nested // Repro: comptime fn (`$x: s32`) whose body has BOTH a nested
// comptime call (`print`) AND a `return X;` statement. Pre-fix: // comptime call (`print`) AND a `return X;` statement. Pre-fix:

View File

@@ -1,17 +0,0 @@
// Phase 2 verification: two impls for the same parameterised-protocol
// (Source, Target) pair declared in the same file MUST produce a clean
// "duplicate impl" diagnostic at registration time.
#import "modules/std.sx";
MyA :: struct { v: s64 = 0; }
impl Into(MyA) for s64 {
convert :: (self: s64) -> MyA { .{ v = self }; }
}
impl Into(MyA) for s64 {
convert :: (self: s64) -> MyA { .{ v = self * 2 }; }
}
main :: () -> s32 { 0; }

View File

@@ -0,0 +1 @@
/Users/agra/projects/sx/examples/181-impl-duplicate-same-file.sx:15:1: error: duplicate impl 'Into' for source 's64' in /Users/agra/projects/sx/examples/181-impl-duplicate-same-file.sx

View File

@@ -0,0 +1,10 @@
size_of(*u8) = 8
align_of(*u8) = 8
size_of(?u8) = 2
size_of([3]u8) = 3
size_of((s32)->s32) = 8
size_of((s32, s32)) = 8
size_of(Ptr) = 8
size_of(Maybe) = 2
size_of(Arr) = 3
size_of(Cb) = 8

View File

@@ -0,0 +1,7 @@
direct s32: 4
alias s32: 4
chain s32: 4
align alias: 4
align chain: 4
size struct-alias: 16
align struct-alias:8

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@
0

View File

@@ -1 +0,0 @@
/Users/agra/projects/sx/examples/issue-0032.sx:13:1: error: duplicate impl 'Into' for source 's64' in /Users/agra/projects/sx/examples/issue-0032.sx