style: rustfmt ck_resolve/lower.rs + ck_syntax/lib.rs (TY1/N6 landed unformatted) #12

Manually merged
dferreira merged 7 commits from feat/012-style-rustfmt-ck-resolve-lower-rs-ck-syntax-li into master 2026-01-15 16:00:39 +01:00
Owner

style: rustfmt ck_resolve/lower.rs + ck_syntax/lib.rs (TY1/N6 landed unformatted)

Along the way:

  • docs(design): lock TY2–TY8 + N7/N8 specs; remove Exception family; promote seed to keyword
  • docs(parser): add Slice 30 spec — seed keyword promotion
  • feat(parser): land Slice 30 — seed keyword promotion (#43)
  • feat(resolve): land Slice N7 — test decls + effect test blocks (#44)
  • docs: fix 16 broken cross-references across docs/impl
  • feat(resolve): land Slice N8 — actor decl + per-actor item scope

Touches 72 files: docs/compiler-level-testing.md, docs/effects.md, docs/errors.md, docs/impl/02-lexer.md, docs/impl/03-parser.md, docs/impl/08-diagnostics.md and 66 more.

style: rustfmt ck_resolve/lower.rs + ck_syntax/lib.rs (TY1/N6 landed unformatted) Along the way: - docs(design): lock TY2–TY8 + N7/N8 specs; remove Exception family; promote `seed` to keyword - docs(parser): add Slice 30 spec — `seed` keyword promotion - feat(parser): land Slice 30 — `seed` keyword promotion (#43) - feat(resolve): land Slice N7 — test decls + effect test blocks (#44) - docs: fix 16 broken cross-references across docs/impl - feat(resolve): land Slice N8 — actor decl + per-actor item scope Touches 72 files: `docs/compiler-level-testing.md`, `docs/effects.md`, `docs/errors.md`, `docs/impl/02-lexer.md`, `docs/impl/03-parser.md`, `docs/impl/08-diagnostics.md` and 66 more.
Author
Owner

Split. The decision in root_const_resolves_inside_spawn is a pure function now, with its own tests in src/rust/crates/ck_resolve/src/actors.rs.

Split. The decision in `root_const_resolves_inside_spawn` is a pure function now, with its own tests in `src/rust/crates/ck_resolve/src/actors.rs`.
dferreira approved these changes 2026-01-15 13:00:00 +01:00
dferreira left a comment

Good. Small enough to read in one sitting, and src/rust/crates/ck_resolve/src/actors.rs is easier to follow than it was.

Good. Small enough to read in one sitting, and `src/rust/crates/ck_resolve/src/actors.rs` is easier to follow than it was.
@ -0,0 +530,4 @@
}
#[test]
fn root_const_resolves_inside_spawn() {
Owner

root_const_resolves_inside_spawn reads, decides and writes in one function. The deciding part is the piece I would want to test on its own. Worth splitting?

`root_const_resolves_inside_spawn` reads, decides and writes in one function. The deciding part is the piece I would want to test on its own. Worth splitting?
Master's #41 (TY1) / #42 (N6) commits were merged without the `cargo fmt
--check` gate passing (the pinned rustfmt 1.8.0 reformats them). Apply the
canonical formatting so the merged tree is green; this also cleans up master
when the merge fast-forwards back.
Front-end + type-system spec cascades:
- N7 (test-decl): top-level `test fn` + bundled `test { }` block, uniform
  across effects and actors; reserves E0307 (actor-slot in effect test block)
- N8 (actor-decl): ActorDecl surface, depends on N7's test-block lowering;
  reserves E0306 (duplicate single-kind actor slot)
- TY2–TY8: seven per-slice type-system specs drafted; ~30 design questions
  locked with explicit rationale (`Locked (2026-05-28)` markers in each)

Cross-cutting design corrections (all locked 2026-05-28):
- `data Exception { ... }` family REMOVED. Every error is `data X composes
  Error`; raise-vs-return is per-call-site transport, not a type-level rule.
  R5-exception-path → R5-raise-path; T3-unhappy-and-exception-traps →
  T3-unhappy-and-raise-traps; `trap<Exception::*>` → `trap<_>`;
  `Exception::OutOfMemory` → `OutOfMemory`. Failure modes become
  happy/unhappy/invalid/raise (no "exception" anywhere).
- `seed` is a hard keyword (lexer/parser code change pending). The
  `mock.seed.X` accessor pattern was design drift — `seed fn`s run
  automatically as precedence-marked setup, never accessed by tests.
  `TestStarted.seed` → `TestStarted.rnd_seed` (random replay seed,
  distinct semantic).
- `Nothing` reframed as stack-termination marker (not just bottom type) —
  the runtime instruction "this branch invalid; terminate the actor's
  stack."
- Diagnostic collection split from reporting: passes emit per-occurrence
  events; the reporting layer merges/enriches.
- Type-algebra (`and`/`or`/`not`/`is`/`is not`) vs value-algebra
  (`&&`/`||`/`==`/...) strictly separated; never mix in one expression.

Memory: 5 new entries (nothing_stack_termination, errors_collect_vs_report,
type_vs_value_operators, no_exception_family, seed_keyword).
MEMORY.md index + project_four_failure_modes updated with the renames.

No code changes — design-only.
Slice 30 is a parser-stage refinement that promotes `seed` from a contextual
identifier to a hard keyword in `ck_lex`'s keyword table, and switches
`parse_test_block_body` from an `Ident fn` lookahead to dispatching directly
on the new `Seed` token. The CST shape (`SyntaxKind::SeedFn` wrapping a
`FnDecl`) is unchanged; no new diagnostic codes are introduced.

The slice is a prerequisite for N7 (test-decl resolver), whose design relies
on the parser enforcing the literal `seed` modifier. Without this slice, N7
would have to add a resolver-side text check the spec explicitly says it
does not need.

- 03-parser.md: new "Slice 30: `seed` keyword promotion" section under the
  declaration sub-cascade; the slice-27 paragraph now links to slice 30 as
  where the keyword change actually lands.
- slices.md: pending-sequenced section gains a paragraph for slice 30,
  noting the N7 prerequisite and that the global # is assigned at landing
  (next free: #43).
Promote `seed` from a contextual identifier to a hard keyword, completing
the slice-27 test-block surface. The two prior identifier uses of `seed`
(`TestStarted.seed` and `l.seed.clear()`) were retired as design drift
when the seed-keyword design was locked (2026-05-28), so the contextual
recognition trick has no remaining justification and is removed.

- `ck_lex`: add `SyntaxKind::Seed` to the enum and `b"seed" => Seed` to
  the keyword table; rewrite the `SeedFn` doc comment to point at the
  keyword instead of the old `Ident fn` lookahead.
- `ck_parser/src/test_decl.rs`: `parse_test_block_body` dispatches on
  `at(Seed)` directly (the `Ident && nth(1) == Fn` lookahead is gone);
  `parse_seed_fn` consumes the `Seed` keyword rather than an Ident.
  Module-level rationale refreshed.
- `ck_parser/src/actor_decl.rs`: refresh the stale comparison that
  cited "the `seed` approach" as the contextual counter-example.
- New parser unit test exercises `seed` outside a test block to confirm
  it lexes as the `Seed` keyword (top-level E0013), not an Ident.
- Re-bless `tests/parser/effect/test_block.cktest` and
  `tests/parser/actor/counter.cktest`: the `seed` token now lexes as
  `Seed` rather than `Ident`. Same shape as the slice-29 `Receive` /
  `Despawn` / `Http` reblessing.
- Docs: flip Slice 30's status to ✅ landed in `03-parser.md`, add the
  row to `slices.md`'s Done table (global #43), and collapse the
  pending-sequenced paragraph.

No new diagnostic codes; the CST shape (`SyntaxKind::SeedFn` wrapping
`FnDecl`) is unchanged. Unblocks N7 (test-decl resolver): N7's design
relies on the parser enforcing the literal `seed` modifier rather than
a resolver-side text check.

Gates: cargo fmt --check, cargo clippy -D warnings, and the full
workspace test suite are green (666 passing). The pre-existing
ck_docs_linkchecker failure (16 broken links into the in-progress
TY/N7 design docs) is unchanged from master and unrelated.
Lifts the test surface across the two contexts it appears in today. A
top-level `test fn` projects through `DeclHead::Test` and allocates as
an ordinary `FnId` carrying `FnKind::Test` on `FnData` — the body
lowers via the N6 path verbatim, and the marker is what the test
runner reads to filter. The bundled `test { … }` block inside an
effect is resolved by `ck_resolve::test_blocks::resolve_effect_test_block`:
members (state fields, seed fns, op fns) collect into one flat
per-test-block scope (E0305 on same-block dup), threaded as an extra
outer frame above each contained body so a bare reference inside an op
body resolves to a sibling state field before falling back to the
module. New diagnostic **E0307** rejects actor-only slots (spawn /
receive / despawn) inside an effect's test block, with a secondary
label on the enclosing `effect` keyword. The actor-context `test { … }`
slot reuses this same lowering when N8 lands.

Goldens: tests/resolve/test_fn_top_level.cktest,
effect_test_block.cktest, effect_test_block_with_actor_slot.cktest.
The linkchecker was failing on master because a batch of stale
references accumulated through prior design-lock churn (Exception →
raise rename, heading-text drift, missing relative path levels). None
of these affected behavior; they all silently broke the docs-link
contract. Categories:

- `T3-unhappy-and-exception-traps.md` → `T3-unhappy-and-raise-traps.md`
  (3 sites: T1, T2, trap-and-observe) — fallout from the Exception
  family removal locked 2026-05-28.
- N7-actor-decl.md → N8-actor-decl.md (TY3, TY6) — the actor-decl spec
  was renumbered when N7 was assigned to test-decl.
- TY4 `#trait-field-access--…` anchor (4 sites: TY5, TY6, TY8 ×2) —
  the heading text became "collisions rejected" instead of the
  hyphenated phrasings the cites were guessing.
- TY2 `../effect-rows.md` → `../../effect-rows.md`; TY8
  `../../decisions-error-and-type-model.md` →
  `../../../decisions-error-and-type-model.md` (relative-depth fixes).
- TY2 `type-representation.md#the-string-and-emptystring-types` →
  `../../types.md#the-string-and-emptystring-types` (the section is
  in types.md, not in type-representation.md).
- 03-parser.md → `02-lexer.md#token` (was `#tokens`) and
  `syntax.md#boolean-operators-type-algebra-vs-value-algebra` (was
  `#boolean-keywords-in-types-and-constraints`).
- TY4 → N2 `#what-landed` → `#landed` (heading text).
- TY5 → TY4 coherence-table cite dropped its dead anchor (the table
  is built top-of-file; the file root is the right target).

ck_docs_linkchecker now passes on master, restoring the quality gate.
The hook still has to be installed via `scripts/install-hooks.sh` for
local enforcement — without it the gate only fires from `scripts/test.sh`
or CI.
N8 lifts the actor surface through the front-end the same way
N1/N3/N6 lifted fn/record/data/const. ck_syntax projects ActorDecl
(state / root consts / spawn / despawn / http / receive / helper fns
/ test); ck_hir adds ActorId and ItemRef::Actor in the per-module
flat namespace (collisions fire the existing E0304); ck_resolve's new
actors.rs builds the per-actor item scope (state fields + root
consts + helper fns) and lowers every slot body against it.

Slot lowering reuses N6's body machinery — spawn/despawn/http/helpers
feed lower_body verbatim; receive<T>(pattern) binds its pattern frame
above the actor item scope; test { … } delegates to N7's
test-block resolver with the actor's item scope threaded above. The
actor item scope sits as scope level 2 in the lookup chain (block →
actor-item → module → project-effects → stdlib → primitives), so a
bare reference inside a slot resolves to a sibling state field /
const / helper before falling back to the module.

E0306 (duplicate single-kind slot) is registered and fires on a
second spawn or despawn in one actor — primary on the duplicate
keyword, "first declared here" secondary on the first — same shape
as E0304 / E0305 / E0501. The polymorphic slots (receive<T> by
message type, http by route, helper fns by name) are not subject to
E0306; those uniqueness checks belong to later stages.

Gating fixtures under tests/resolve/ cover the three locked cases
from the spec: clean actor with state field referenced via item
scope, duplicate spawn firing E0306, and a flat-namespace collision
inside one actor. The parser fixtures for counter/http_api are
re-blessed against the new ActorDecl CST shape.

Deferred (per the spec's "Out"): Singleton/Bound/Ephemeral lifetime
semantics, supervise/route enforcement, required-spawn / required-
test, receive<T> per-message uniqueness, http route-collision, the
implicit-self reference. The bare-name lookup against the actor item
scope is enough for the corpus today.
dferreira manually merged commit 4d2c3d565e into master 2026-01-15 16:00:39 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
northgale/cklang-bootstrap!12
No description provided.