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:
35
examples/route/0815-route-all-new-surfaces-ambiguous.sx
Normal file
35
examples/route/0815-route-all-new-surfaces-ambiguous.sx
Normal 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
|
||||
}
|
||||
@@ -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; }
|
||||
@@ -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; }
|
||||
29
examples/route/0816-route-all-new-surfaces-own-wins.sx
Normal file
29
examples/route/0816-route-all-new-surfaces-own-wins.sx
Normal 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
|
||||
}
|
||||
11
examples/route/0816-route-all-new-surfaces-own-wins/dep.sx
Normal file
11
examples/route/0816-route-all-new-surfaces-own-wins/dep.sx
Normal 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;
|
||||
}
|
||||
39
examples/route/0822-route-all-own-wins-surfaces.sx
Normal file
39
examples/route/0822-route-all-own-wins-surfaces.sx
Normal 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
|
||||
}
|
||||
10
examples/route/0822-route-all-own-wins-surfaces/dep.sx
Normal file
10
examples/route/0822-route-all-own-wins-surfaces/dep.sx
Normal 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;
|
||||
}
|
||||
32
examples/route/0823-route-all-own-wins-subform-wrappers.sx
Normal file
32
examples/route/0823-route-all-own-wins-subform-wrappers.sx
Normal 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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
opt=1 arr=2 sl=3 dep=99
|
||||
Reference in New Issue
Block a user