Skip to content

Add named enums and exhaustive match - #98

Merged
itsfuad merged 16 commits into
mainfrom
feature/named-enums
Aug 25, 2026
Merged

itsfuad merged 16 commits into
mainfrom
feature/named-enums

Conversation

@itsfuad

@itsfuad itsfuad commented Aug 24, 2026 •

Copy link
Copy Markdown
Member

Summary

  • add payload-aware named enum declarations with declaration-owned variant symbols and generic substitution
  • construct fully named local and imported cases through canonical semantic evidence and shared tagged-variant lowering
  • add nonconsuming is tests, case-set CFG narrowing, exact-case fields, and alias-aware invalidation
  • add exhaustive statement match with arm scopes, case edges, definite initialization, ownership transfers, and cleanup evidence
  • preserve carrier ownership for copyable and shared-reference fields while rejecting move-only partial extraction
  • add structured variant constants, typed MIR statics, LLVM aggregate emission, enum FFI rejection, LSP support, fixtures, and documentation

Validation

  • CCACHE_DISABLE=1 GOCACHE=/tmp/peeper-go-cache go test -count=1 ./...
  • CCACHE_DISABLE=1 GOCACHE=/tmp/peeper-go-cache go vet ./...
  • CCACHE_DISABLE=1 GOCACHE=/tmp/peeper-go-cache go test -race -count=1 ./...
  • CCACHE_DISABLE=1 GOCACHE=/tmp/peeper-go-cache bash scripts/build.sh
  • PEEPER_BIN="$PWD/build/bin/peeper" CCACHE_DISABLE=1 GOCACHE=/tmp/peeper-go-cache go test -count=1 ./x_test
  • git diff --check
  • GitHub CI go and fixtures jobs pass at 63e4288

Boundaries

  • variants require fully named Enum::Variant syntax and never become types or callable constructors
  • struct literals remain .Point{...} and .{...}
  • match remains statement-only, exhaustive, and fully named; no wildcard, guard, alternative, nested, shorthand, or expression forms
  • move-only field extraction remains legal only from direct named local or parameter carriers; partial carriers are rejected
  • LLVM keeps one typed payload slot per data case; compact union storage remains Compact tagged variants into shared union payload storage #92
  • named enums remain rejected in extern signatures until Define explicit enum representation and foreign ABI #96

Merged into main after parent PRs #87, #88, and #97.

Deferred work: #30, #89, #91, #92, #94, #95, #96, #99, and #100.

Review follow-up

Cleanup audit

  • Enum aliases now qualify canonical variants without copied scopes; resolver and LSP share canonical declaration lookup.
  • Fixed imported completion, unreferenced typed constants, target ABI alignment, nominal fingerprints, unsupported comparisons, imported identity, stale LSP snapshots, reference-recursive enum lowerability, and dead match-carrier convergence.
  • Added focused compiler, LSP, backend, recursion, ABI, ownership, and executable fixture regressions.
  • Latest feature commit: 63e4288; merged to main as 5a7a5cf after Add optional narrowing and payload access #87, Add shared tagged variant core #88, and Add generic named type instances #97.

Parse enum payload schemas, variant literals, is tests, and match statements. Add payload-aware semantic cases, declaration-owned variant symbols, constructor evidence, and shared VariantMake lowering.\n\nCentralize qualified variant path splitting, imported-member diagnostics, and struct/variant field validation so later phases consume one semantic source of truth.
Resolve and typecheck exhaustive match arms through canonical semantic evidence, then build case-labelled CFG edges with definite-init and flow transfer.

Reuse shared case lookup and place origins, and lower copyable pattern bindings through existing HIR/MIR variant switches and payload projections.
Add structured variant constants, typed MIR static evidence, LLVM aggregate emission, nested extern rejection, LSP enum tooling, fixtures, and shipped-language documentation. Resolve static types through canonical ABI keys so nominally distinct enums with the same display name cannot collide.\n\nHelpers are limited to recursive constant storage, ABI identity, typed backend aggregate lowering, nested type traversal, and balanced incomplete-source completion contexts.
@itsfuad itsfuad moved this from Todo to In Progress in Peeper Roadmap Aug 24, 2026
@itsfuad itsfuad added this to the 0.2 Language Foundations milestone Aug 24, 2026
itsfuad added 11 commits August 24, 2026 22:50
# Conflicts:
#	docs/language-spec.md
#	internal/ir/hir/lower/module_lower_test.go
#	internal/ir/types.go
#	internal/semantics/place/origin_test.go
#	internal/semantics/typechecker/check_call.go
#	internal/semantics/typechecker/flow.go
Centralize transparent alias-to-enum declaration lookup so resolver and LSP completion share canonical variant identity without copied scopes. Record parser-owned match arm-list bounds so completion never replaces subjects or existing arms.
Generalize canonical enum lookup to retain qualifier owner and canonical declaration identity. This shared boundary lets empty-match completion preserve imported transparent-alias spelling while resolver and completion continue using declaration-owned variant symbols.
Resolve named variant syntax through resolver-owned qualifier symbols so cloned defaults keep declaration-module enum identity across construction, case tests, and match arms.\n\nCentralize the shared path/type/case lookup because all three checker consumers must preserve the same cross-module clone invariant.
Stamp compiled contexts with document generation so dependency overlay edits cannot reuse stale enum schemas. Preserve previous contexts for diagnostic replay and keep module-level incremental reuse intact.\n\nCentralize context, metrics, and generation publication because every recompile exit must publish one coherent snapshot.
Treat safe-reference cycles as lowerable indirection while preserving by-value cycle rejection. Stop stored-reference traversal at direct referents so referent fields are not mistaken for embedded carrier storage.
Generalize existing reference liveness into canonical tracked-symbol liveness, then normalize dead direct match carriers at falling arm exits. Keep live mixed joins and drop-bearing overwrite obligations rejected.

Helpers centralize direct carrier resolution and payload-move classification shared by match transfer and cleanup planning; no parallel walker or lowering path is added.
@itsfuad
itsfuad changed the base branch from feature/generic-named-types to main August 25, 2026 17:31
@itsfuad
itsfuad merged commit 5a7a5cf into main Aug 25, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Peeper Roadmap Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Allow dead enum match carriers after mixed arm moves

1 participant