test: group examples into per-category folders

Move examples/*.sx and their expected/ snapshots into per-category
subfolders (examples/<category>/...). Folder = leading filename token,
with ffi-objc/ffi-jni kept whole; filenames are unchanged. The corpus
runner and LSP sweep now discover each category's expected/ dir, while
issues/ stays flat. Example 1058's repo-root-relative companion import
is made file-relative. Path strings embedded in 164 snapshots were
regenerated (path-only changes). Test-layout docs in CLAUDE.md updated.
This commit is contained in:
agra
2026-06-21 14:41:34 +03:00
parent 6d1409bc1f
commit 66bdc70bf1
3357 changed files with 456 additions and 363 deletions

View File

@@ -0,0 +1,35 @@
// E6b-R — route-all: the NEW use surfaces a same-name type reaches now funnel
// through the source-aware engine, so an ambiguous bare name poisons LOUDLY at
// each of them instead of silently picking a global `findByName` last-wins author.
// `main` flat-imports two same-name `Box` struct authors and authors none itself,
// so every bare `Box` below is a genuine collision. `Box` is the kind-agnostic
// canary (the bare-leaf forms — annotations / size_of / match / `!Named` — are
// already locked per kind by 0755/0795/0797/0811); these cells exercise the
// surfaces E6b-R added:
//
// - wrapper-alias element `BoxPtr :: *Box` (engine wrapper aliasing)
// - union body-builder child `WrapU :: union { b: Box }` (C1, registerUnionDecl)
// - enum body-builder child `WrapE :: enum { V: Box }` (C1, registerEnumDecl)
// - tuple-literal element `size_of((Box, i32))` (O1/K5)
// - inline-anonymous body child `x : union { b: Box }` (inline-anon engine arm)
//
// Fail-before (pre-E6b-R): each of these resolved `Box` through the stateless
// `type_bridge.resolveAstType` global last-wins, silently binding one arbitrary
// author with NO diagnostic. Pass-after: every surface emits the LOUD
// "type 'Box' is ambiguous" and the build exits 1.
#import "modules/std.sx";
#import "0815-route-all-new-surfaces-ambiguous/a.sx";
#import "0815-route-all-new-surfaces-ambiguous/b.sx";
BoxPtr :: *Box;
WrapU :: union { b: Box; n: i32; }
WrapE :: enum { V: Box; }
main :: () -> i32 {
sz := size_of((Box, i32));
x : union { b: Box; n: i32 } = ---;
0
}

View File

@@ -0,0 +1,6 @@
// One of two flat-imported authors of a same-name `Box` struct. With both modules
// flat-visible from a file that authors none itself, every bare reference to the
// name is genuinely ambiguous — at EVERY use surface, including the ones E6b-R
// newly routed through the source-aware engine (wrapper aliases, tuple-literal
// elements, enum/union body-builder child types, inline-anonymous types).
Box :: struct { x: i32; }

View File

@@ -0,0 +1,4 @@
// The second flat-imported author of a same-name `Box` struct. A separate nominal
// identity from a.sx's `Box`, so each bare reference is a real collision the
// importing source cannot disambiguate.
Box :: struct { x: i32; }

View File

@@ -0,0 +1,29 @@
// E6b-R — own-wins-over-flat at the NEW use surfaces route-all funnels through the
// source-aware engine. `main` flat-imports `dep.sx` (which authors `Box { a }`) AND
// authors its OWN `Box { m }`; the field sets are DISJOINT, so the observable is
// field access: `.m` typechecks only against main's `Box`, `.a` only against dep's.
//
// `WrapU` is authored only by `main`, so its union field type `Box` resolves at
// registration (`registerUnionDecl` → the source-aware body builder, E6b-R C1) to
// MAIN's `Box`. Accessing `w.b.m` therefore typechecks, while `dep_box` uses dep's
// DISTINCT `Box { a }`.
//
// Fail-before (pre-E6b-R): `registerUnionDecl` built the union body through the
// stateless `type_bridge.buildUnionInfo`, whose `findByName` short-circuit bound
// the global last-wins `Box`. If dep's `Box { a }` won the slot, `WrapU.b` was
// dep's `Box` and `w.b.m` was a hard "field not found" — silently wrong nominal.
// Pass-after: the union field is main's own `Box`, `w.b.m` resolves, exit 0.
#import "modules/std.sx";
#import "0816-route-all-new-surfaces-own-wins/dep.sx";
Box :: struct { m: i32; }
WrapU :: union { b: Box; n: i32; }
main :: () -> i32 {
w : WrapU = ---;
w.b.m = 5;
print("own={} dep={}\n", w.b.m, dep_box());
0
}

View File

@@ -0,0 +1,11 @@
// A flat-imported module authors its OWN `Box { a }`. The importing file (`main`)
// ALSO authors a `Box { m }` — its own author must win there (own-wins), while this
// module's `Box` stays a DISTINCT nominal type used by `dep_box`. The field sets
// are disjoint, so a cross-binding to the wrong `Box` is a hard compile error.
Box :: struct { a: i32; }
dep_box :: () -> i32 {
b : Box = ---;
b.a = 9;
return b.a;
}

View File

@@ -0,0 +1,39 @@
// G3 — own-wins HALVES for the route-all surfaces 0815 covered only on the
// ambiguous half. `main` authors its OWN `Box { m }` and flat-imports `dep.sx`
// (`Box { a }`); each surface below must bind main's OWN `Box`, observed by a
// `.m` access (disjoint field sets → a wrong-author binding is a hard compile
// error). Complements 0816 (which covered only the union body-builder child):
// - pointer wrapper-alias element `BoxPtr :: *Box`
// - tuple element `(Box, i32)`
// - enum body-builder child `WrapE :: enum { V: Box }`
// - inline-anonymous union child `x : union { b: Box }`
#import "modules/std.sx";
#import "0822-route-all-own-wins-surfaces/dep.sx";
Box :: struct { m: i32; }
BoxPtr :: *Box;
WrapE :: enum { V: Box; }
main :: () -> i32 {
own : Box = ---;
own.m = 10;
// *Named wrapper-alias element own-wins
bp : BoxPtr = @own;
// tuple element own-wins
t : (Box, i32) = ---;
t.0.m = 12;
// enum body-builder child own-wins (payload must be main's `Box`)
we : WrapE = .V(own);
ev := we.V.m;
// inline-anonymous union child own-wins
x : union { b: Box; n: i32 } = ---;
x.b.m = 13;
print("bp={} t={} ev={} x={} dep={}\n", bp.m, t.0.m, ev, x.b.m, dep_box());
0
}

View File

@@ -0,0 +1,10 @@
// A flat-imported module authoring its OWN `Box { a }`, a DISTINCT nominal from
// main's `Box { m }`. The four route-all surfaces in `main` must each bind main's
// own `Box`; the disjoint field sets make a wrong binding a hard compile error.
Box :: struct { a: i32; }
dep_box :: () -> i32 {
b : Box = ---;
b.a = 99;
return b.a;
}

View File

@@ -0,0 +1,32 @@
// G4 — own-wins halves for the §D row-2 SUB-FORM wrappers (`?Named`, `[]Named`,
// `[N]Named`). Each wraps a named element type whose resolution recurses through
// the SAME source-aware `resolveCompound` element path that `*Named` uses (0822),
// so they share one routing mechanism rather than a per-form path. `main` authors
// its OWN `Box { m }` and flat-imports `dep.sx` (`Box { a }`); each wrapped
// element must bind main's own `Box`, observed by a `.m` access (disjoint field
// sets → a wrong-author binding is a hard compile error).
#import "modules/std.sx";
#import "0823-route-all-own-wins-subform-wrappers/dep.sx";
Box :: struct { m: i32; }
main :: () -> i32 {
seed : Box = ---;
seed.m = 1;
// ?Named element own-wins
opt : ?Box = seed;
o := opt!;
// [N]Named element own-wins
arr : [2]Box = ---;
arr[0].m = 2;
arr[1].m = 3;
// []Named element own-wins
sl : []Box = arr[0..2];
print("opt={} arr={} sl={} dep={}\n", o.m, arr[0].m, sl[1].m, dep_box());
0
}

View File

@@ -0,0 +1,10 @@
// A flat-imported module authoring its OWN `Box { a }`, a DISTINCT nominal from
// main's `Box { m }`. The `?Box` / `[N]Box` / `[]Box` element wrappers in `main`
// must each bind main's own `Box`; disjoint field sets make a wrong binding fail.
Box :: struct { a: i32; }
dep_box :: () -> i32 {
b : Box = ---;
b.a = 99;
return b.a;
}

View File

@@ -0,0 +1 @@
opt=1 arr=2 sl=3 dep=99