Skip to content

Stage c/228 qualified type effect path#309

Closed
hyperpolymath wants to merge 2 commits into
mainfrom
stage-c/228-qualified-type-effect-path
Closed

Stage c/228 qualified type effect path#309
hyperpolymath wants to merge 2 commits into
mainfrom
stage-c/228-qualified-type-effect-path

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

No description provided.

claude added 2 commits May 18, 2026 23:31
…tor (Refs #228)

The type/effect grammar had no module-qualified path production, so
`Externs.Res` / `prelude.Option` / any `Pkg.Type` in type or effect
position failed `parse error` at the `.` — contradicting ADR-011 (real
modules with qualified paths). This adds full, SOUND module-qualified
paths in type and effect position, with `.` as the canonical separator
(`::` stays value/import per ADR-011); decision recorded as ADR-014.

Resolution is by sound module-scoped member lookup, never flat scope:
load module `[A;B]` through the loader, resolve+typecheck it as an
import would, then look the member up *inside that module's own
resolved symbols*, requiring Public/PubCrate and the right kind
(SKType / SKEffect). Unknown/wrong module, missing member, private
member, or wrong-kind member is a resolution error at the use-site
span — never a parse error and never silently accepted.

- lib/ast.ml: `ident` gains `modpath : string list` ([]=unqualified);
  add `mk_ident` helper so synthetic idents set the field in one place.
- lib/parser.mly: `mk_qualified_ident`; `path_seg`/`module_prefix`/
  `qualified_type_path` helpers; qualified bare/[args]/<args> forms for
  types and bare/[args] for effects. Module-prefix segments accept
  lower OR upper case (stdlib modules are `prelude`/`option` as well as
  `Network`/`Http`); member segment is upper_ident.
- lib/typecheck.ml: `lower_type_expr`/`lower_effect_expr` validate the
  qualified case via a loader-backed `qualified_member_check` threaded
  into the context; `Qualified_path_error` -> `QualifiedPathError` at
  the check_program boundary (same pattern as Effect_validation_error).
  A validated qualified effect's name is admitted as a declared effect
  (issue #59) so a sibling module's public effect is usable like a
  local one. Resolved representation is the canonical nominal
  type/effect — identical to the bare/imported form; the validation,
  not the representation, is the soundness gate. Typecheck/codegen
  otherwise unchanged.
- lib/resolve.ml: `make_qualified_member_check` built where the loader
  lives, inside the `resolve_and_typecheck_module` recursive group so
  transitively-qualified stdlib paths resolve too.
- bin/main.ml: thread the validator into the 6 patterned check_program
  calls (via the type_ctx returned by resolve_program_with_loader).
- Fixed ~10 internal direct `ident` record literals (trait/codegen_gc/
  borrow/verilog) to route through `Ast.mk_ident`.
- docs/specs/SETTLED-DECISIONS.adoc + .machine_readable/6a2/META.a2ml:
  ADR-014 (full stanza, same shape as ADR-011/012/013).
- tests/conformance/qualified-paths/{valid,invalid}: 5 conformance
  fixtures wired into the e2e gate (valid qualified type+effect;
  unknown module; private member; absent member).

Parser-conflict delta: ZERO. menhir --explain summary is byte-identical
to the pre-change parser — 21 shift/reduce states, 1 reduce/reduce
state, 68 s/r + 7 r/r arbitrarily resolved. The `upper_ident` vs
`upper_ident DOT ...` decision is the expected benign DOT shift
(Menhir shifts, disclosed per ADR-012); no new unexplained conflict.

Test gate: 258 -> 263 (5 new #228 cases), zero regressions. Adding
`modpath` to `ident` reflows every golden .expected AST dump;
regenerated — the span-normalised golden harness confirms no
structural change.

STAGE-C peer of #225 (typed-wasm Http) and #160 (C-spine). Language
decision is human-gated (ISSUE-CLOSURE): Refs #228, not Closes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ture limitation

- .machine_readable/6a2/STATE.a2ml: bump last-updated; add
  session-note-2026-05-18 recording #228/ADR-014/PR#231 (machine
  state/progress convention was stale).
- docs/specs/SETTLED-DECISIONS.adoc (ADR-014): add 'Known limitation'
  paragraph — qualified-effect positive fixture is harness-only (no
  public stdlib effect for a self-contained positive); bare-oracle
  audits must exclude it.
- tests/conformance/qualified-paths/valid/qualified_effect.affine:
  header now states the harness-search-path dependency explicitly.

Turns a silent landmine into a stated limitation. No code change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath
Copy link
Copy Markdown
Owner Author

Superseded — closing as duplicate / stale re-open.

This PR's head (3ad1bed95ecaa44b457c8076bd74498b155d8a11, branch stage-c/228-qualified-type-effect-path) is the identical commit as the previously-closed DRAFT #231. The owner closed #231 on 2026-05-19 with the rationale:

Superseded by #241 (merged): ADR-014 module-qualified type/effect paths landed with zero Menhir conflict delta, 270/270 gate, ADR recorded in META.a2ml + SETTLED-DECISIONS.adoc. #231 was the grammar-only DRAFT; #241 is the complete, gated implementation.

PR #241 merged to main on 2026-05-19 at commit 5cca379 (feat(parser)!: ADR-014 — module-qualified type/effect paths (Refs #228)). The grammar-only sketch on this branch is strictly subsumed by what is already on main, hence the DIRTY conflict state against current main.

No salvageable content — closing without rebase. Refs #228, #231, #241.

@hyperpolymath hyperpolymath deleted the stage-c/228-qualified-type-effect-path branch May 20, 2026 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants