feat(v2): qualified module-member access M.member (G6 keystone)#331
Merged
Conversation
Closes the parse half of the G6 keystone gap (docs/v2-grammar-and-codegen- gaps-2026-06-16.adoc). Phase I (#43) already made an imported module's public items visible UNQUALIFIED; this adds the qualified `M.member` SYNTAX, which previously errored at the parser with "Named field access not yet supported". - grammar: `member_op` accepts a `constructor_name` after `.` (so both `M.fn` and `M.Ctor` lex). - surface AST: new `SurfaceExprKind::FieldAccess { base, field }`. - parser: a named member access builds `FieldAccess` instead of erroring. - desugar: `FieldAccess` resolves against the importer's imports — `M` is the last path segment of an `import` — to the unqualified member: an upper-case `member` desugars to a constructor (`Construct`), otherwise a function/value (`Var`), reusing phase I's shared scope. An unknown qualifier is a clean `QualifiedAccessUnknownModule` error; member access on a non-module base is rejected (record field access stays a follow-up). Verified: `lib.inc(...)` (function) + `lib.On` (constructor) compile end-to-end to wasm (new fixture tests/v2-grammar/fixtures/qualified-import/ + test src/ephapax-cli/tests/v2_grammar_phase_k_qualified.rs, 2 tests). Full parser/desugar/surface/cli suites pass — no regressions. Follow-ups: `M.Ctor(args)` (lowers to App, not Construct-with-args) and record field access on values. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AGFqWzByua4dKbA7W7oVsL
hyperpolymath
marked this pull request as ready for review
June 27, 2026 19:06
hyperpolymath
enabled auto-merge (squash)
June 27, 2026 19:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the parse half of G6, "the single highest-leverage v2 toolchain item" (
docs/v2-grammar-and-codegen-gaps-2026-06-16.adoc). Phase I (#43) already made an imported module's public items visible unqualified (the cross-module test passes). This adds the qualifiedM.membersyntax, which previously errored at the parser with "Named field access not yet supported".The change (parser → surface AST → desugar)
ephapax.pest):member_opaccepts aconstructor_nameafter., so bothM.fn(lower-case) andM.Ctor(upper-case) lex.SurfaceExprKind::FieldAccess { base, field }.surface.rs): a named member access buildsFieldAccessinstead of erroring.ephapax-desugar):FieldAccessresolves against the importer's imports —Mis the last path segment of animport(import lib/math→math) — to the unqualified member, reusing phase I's shared scope:member→ constructor (Construct),Var).QualifiedAccessUnknownModuleerror; member access on a non-module base → rejected (record field access stays a follow-up).Verified
tests/v2-grammar/fixtures/qualified-import/+ testsrc/ephapax-cli/tests/v2_grammar_phase_k_qualified.rs(2 tests):lib.inc(...)(qualified function),lib.On(qualified constructor), and unqualifiedinc(phase I) all compile end-to-end to wasm; an unknown qualifier is a clean error.TEST-NEEDS.mdcount bumped 486 → 488.Mapped to the doc
The G6 doc's first snippet (
Coproc.available(Coproc.Tensor)not parsing) is exactly this:available=function→Var,Tensor=nullary constructor→Construct. Resolution note added to the gaps doc.Follow-ups (documented, out of scope here)
M.Ctor(args)— qualified constructor with arguments currently lowers toApp(Ctor, args), notConstruct{Ctor,[args]}.value.field) — still unsupported.🤖 Generated with Claude Code
https://claude.ai/code/session_01AGFqWzByua4dKbA7W7oVsL
Generated by Claude Code