Feat(ck_resolve): N3 local & item scope resolution — LocalId + E0301/E0305 #9
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/009-feat-ck-resolve-n3-local-item-scope-resolution"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Feat(ck_resolve): N3 local & item scope resolution — LocalId + E0301/E0305
Along the way:
Touches 54 files:
docs/impl/04-name-resolution.md,docs/impl/08-diagnostics.md,docs/impl/module-system/README.md,docs/impl/resolution/N3-local-scope-resolution.md,docs/impl/resolution/N4-qualified-paths.md,docs/impl/resolution/N5-header-impl-matching.mdand 48 more.A clear improvement. The change in
src/rust/crates/ck_resolve/src/graph.rsis the part I would have argued for.@ -0,0 +66,4 @@/// Whether the graph holds no modules.#[must_use]pub fn is_empty(&self) -> bool {is_emptyis public. Does anything outside the crate call it, or is it pub because that was easier? Every public item is a promise.@ -0,0 +353,4 @@}#[test]fn duplicate_module_name_across_two_impls_fires_e0602_naming_both() {duplicate_module_name_across_two_impls_fires_e0602_naming_bothreads, decides and writes in one function. The deciding part is the piece I would want to test on its own. Worth splitting?@ -0,0 +354,4 @@let (caller_tree, caller_src) = (&trees[last], files[last].1);let (caller_name, _) = crate::module_name(caller_tree, caller_src, &mut interner);let caller = linked.modules.module(caller_name).expect("caller module");let scope = linked.modules.scope(caller).expect("caller scope");The expect message on
scopeis the only thing a user sees if this fires. Does it say what they should do, or only what we assumed?Nothing outside calls
is_empty. It is pub(crate) insrc/rust/crates/ck_resolve/src/graph.rsnow.Split. The decision in
duplicate_module_name_across_two_impls_fires_e0602_naming_bothis a pure function now, with its own tests insrc/rust/crates/ck_resolve/src/link.rs.It said what I assumed. Reworded in
src/rust/crates/ck_resolve/src/paths.rsso it names the input that broke it, which is what the bug report will need.Close per-module resolution with the .ckh ↔ .ck cross-check, run inside the linker once a module's two files are merged. Only functions pair across the two files (a record/data/const lives wholly in one), so it matches header vs impl `fn`s by name: - E0401 — a header `fn` signature with no matching impl body (primary on the header declaration). - E0403 — a header `fn` whose impl signature diverges, as a self-contained structural-shape diff (primary on the impl declaration, both shapes in the message). Shape = new ck_syntax FnDecl::signature_shape: the significant- token text of generics + params + return type + effect clause, body omitted; syntactic, not resolved types, so N5 stays a name-resolution check. E0402 is retired, not implemented: under purely-structural visibility an impl-only declaration is simply private, never an error in itself (modules.md enforcement rule 2), so the reserved producer-side "impl-public without header" check has no trigger. The consumer-side privacy error is E0302 (N4), whose message now names the remedy — declare it in the owning module's header to make it public. 08-diagnostics.md gains a "retired row" convention. Goldens: tests/resolve/{header_without_impl,signature_mismatch,header_impl_match}.cktest; private_path.cktest re-blessed for the new E0302 message. Docs updated: N5 spec (status → landed, E0402 decision), resolution README, slices.md (#39), diagnostics registry. ck_resolve crate docstring refreshed to cover N1–N5.