Skip to content

Add methods from top level#669

Open
eliotmoss wants to merge 6 commits into
titzer:masterfrom
eliotmoss:add_methods_from_top_level
Open

Add methods from top level#669
eliotmoss wants to merge 6 commits into
titzer:masterfrom
eliotmoss:add_methods_from_top_level

Conversation

@eliotmoss

Copy link
Copy Markdown
Contributor

Allow top-level defs to add methods to classes, types, enums, and components. Also allows top-level defs to add fields to components (but not other constructs).

eliotmoss and others added 6 commits April 28, 2026 07:31
…ypes, fields, methods

Squashed snapshot of open_enums3b past master. Adds:

- Open enum types with hierarchical subtypes (`enum E.More { ... }`),
  `case _` defaults, DFS-assigned tag ranges for subtype matching,
  and qualified case access (`E.More.C`).
- Per-case enum method overrides (`Case { def m() ... }`) via
  synthetic per-case VstClass / IrClass / RaClass — Strategy B.
  Cases without overrides share the parent RaClass (elision).
- Subtype enum method overrides (`enum E.More { ...; def m() ... }`)
  with virtual dispatch through the root enum's mtable.
- Subtype field redeclaration / addition (`E.S(super, f: float)`,
  `E.S(super)`, `E.S { D(15) }`) with multi-level inheritance.
- `EnumSetType` for hierarchies (one set type per root, bit positions
  by DFS tag).
- Enum method closures with proper boxing on JVM (Integer) and
  wasm-gc (i31ref); Oop/raw tag receiver convention switched per
  target via NormConfig.
- Queue-based two-dimensional liveness (live cases x live virtuals -> live
  impls) and `-compact-mtable=N` optimization for compacting redundant
  mtable rows via tag->slot indirection.
- JvmV3EnumGen M_ABSTRACT guard, SsaInliner enum NullCheck skip,
  and other backend fixes for v3i / x86 / x86-64 / jar / wasm /
  wasm-gc.
- One master regression fix (lookupEnumExprMember VstField receiver),
  benchmarks (EnumScalability, EnumLiveness, EnumOverrides,
  EnumClosureBoxing), and the wasm bench runner.
- Tutorial and grammar reference updates for open enums.

37/37 ci/Makefile configs pass 3809/3809 tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Squashed delta from open_enums3b to open_enums3a. Strategy A is
Strategy B minus per-case enum method overrides — A and B differ
only in this user-visible feature.

Removed:
  - Parser: parseEnumCaseMembers and the `Case { def m() ... }`
    paths in parseEnumCase. Per-case method bodies are now a parse
    error.
  - Vst: VstCaseMember.members field; synthesizeEnumCaseMember no
    longer creates a synthetic per-case VstClass (decl is null again,
    matching the pre-Strategy-B baseline).
  - Verifier: linkEnumCaseMethods (per-case override IrClass setup)
    and the per-case method body type-check pass; per-case
    synthetic-decl tag setup blocks in assignEnumTagsDFS.
  - Reachability: RaClass.enumCaseRaClasses field and the per-case
    RaClass synthesis path in addEnumCaseClasses. The shared
    queue-based liveness driver is simplified to drop the
    synthetic-RaClass dispatch branch and keep only the
    declaring-enum-level fallback used for subtype dispatch.
  - Eval: lookupEnumVirtual no longer checks synthetic case decls.
  - V3: getSyntheticEnumCaseType (now unused).

Test changes:
  - Deleted test/enums/enum_cmethod00..06.v3 (execution).
  - Deleted test/enums/parser/enum_cmethod00.v3 (was //@parse pass).
  - Added test/enums/parser/no_per_case_method.v3 asserting that
    `Case { def m() ... }` syntax is now a parse error.

Doc changes: removed per-case override sections from
doc/grammar-claude.md, doc/tutorial/EnumMethods.md, and
doc/tutorial/Enums.md (the variant per-case method form in
doc/tutorial/ADTs.md is unchanged).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Get the latest changes to the configure script
Adds top-level extension declarations of the form

    def Target<T>.method<U>(args) -> R { body }
    def Component.field: T = init;

which add a member to an existing class, component, variant, or enum (or an
open enum/variant subtype via a multi-level qualifier) as if it had been
declared inside the target. Generic targets pass their type parameters
through to the extension's body; extension type-param names are fresh and
bind positionally.

`private` extensions are scoped to the file where they are declared, so
multiple files may declare a private extension with the same name on the
same target; lookup uses the calling method's file context.

Implementation summary:
- Parser: dispatch top-level `def` between regular file-scope def and
  extension via cheap lookahead; new `parseExtensionPath` and
  `parseExtensionMember` build `VstExtension` nodes on the file.
- Vst: `VstExtension`, `VstFile.extensions`, `VstMember.declarationFile`,
  `VstMember.privateAlts`.
- Verifier: new `attachExtensions` phase between `buildFile` and the rest
  of `verify()`; resolves target by global lookup + qualifier-chain check
  (no dependency on the `subtypes` map being populated yet), validates
  total type-param arity, rebinds extension type-param names to the
  target's TypeCons in the method body's TypeEnv, sets receiver and
  declarationFile, appends to members/memberMap, chains same-name private
  extensions across files via `privateAlts`. Adds `callerFile` to
  VstCompoundVerifier so access checks inside extension bodies use the
  extension's file.
- MethodEnv: class/component lookups route through
  `findAccessibleMember` to walk `privateAlts` on access failure.

Tests:
- 14 single-file tests under test/core/ (method, generic, override,
  closure, return-this, multiple-in-file, chaining, field inferred-type,
  field no-initializer, etc.) plus parser/seman negatives.
- 2 multi-level subtype tests under test/enums/ and test/open_types/.
- New test/ext_multifile/ harness with cross-file method, cross-file
  field, and private-alts cases; wired into test/all.bash.

Docs: new doc/tutorial/Extensions.md (linked from Overview), and the
top-level extension grammar + constraints added to grammar-claude.md and
claude-guide.md.

Verified clean across all of test/all.bash (minus darwin, which can't run
on this host) and on jvm, wasm-gc, x86-64-linux targets for the new
tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The other host checks use `findstring HOST,$(HOSTS),)` (empty) to mean
"HOST was found"; the jar branch was using `,jar)` instead, which means
"jar NOT found" — the opposite of the intent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant