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
// expression-position values (size_of / align_of arg, const-decl RHS).
// Compound type literals in expression position — `size_of` /
// `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";

View File

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

View File

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

View File

@@ -1,6 +1,9 @@
// issue-0045 — calling a comptime fn whose body is a block
// containing an explicit `return X;` trips LLVM's "Terminator found
// in the middle of a basic block" verifier.
// Pack-fn (or any comptime-param fn) with a block body containing
// an explicit `return X;` lowers to clean IR — the inline-return
// 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
// 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
// outer `lowerComptimeCall` into the wrapper fn built by
// `createComptimeFunction`. Without saving/restoring
// `inline_return_target`, the wrapper inherits an inline-return
// slot belonging to a different basic block; the interp executes
// the wrapper and trips a null-pointer store at
// `storeAtRawPtr`.
// Nested comptime call + return — a comptime fn (`$x: s32`) whose
// body contains BOTH a nested comptime call (`print`) AND a
// `return X;` statement must lower cleanly. The wrapper fn built
// by `createComptimeFunction` saves/restores `inline_return_target`
// so it doesn't inherit a slot belonging to the OUTER caller's
// basic block. Pre-fix: interp executed the wrapper with a
// stale-frame inline-return slot and tripped a null-pointer store
// at `storeAtRawPtr`.
//
// Repro: comptime fn (`$x: s32`) whose body has BOTH a nested
// 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