feat: implement ADT RC - pointer fields in algebraic data types

ADT values with pointer fields (like recursive Tree types) now properly
manage memory:

- Assign unique type tags (starting at 100) to each ADT type
- Track which ADTs have pointer fields that need cleanup
- Generate lux_drop_adt() function with per-ADT drop logic
- Allocate ADT pointer fields with lux_rc_alloc instead of malloc
- Track ADT variables with pointer fields in scope
- Emit field cleanup code at scope exit (switch on tag, decref fields)

Test results:
- ADT test: [RC] No leaks: 6 allocs, 6 frees
- List test: [RC] No leaks: 31 allocs, 31 frees
- Closure test: [RC] No leaks: 8 allocs, 8 frees
- All 263 tests pass

Remaining: early returns, complex conditionals.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-14 13:24:21 -05:00
parent 397c633d51
commit 5098104aaf
4 changed files with 204 additions and 12 deletions

View File

@@ -295,8 +295,8 @@ Inspired by Perceus (Koka), our RC system:
-**Scope tracking** - compiler tracks RC variable lifetimes
-**Automatic decref at scope exit** - verified leak-free
-**Closure RC** - closures and environments are RC-managed
-**ADT RC** - pointer fields in ADTs are RC-managed
- ⏳ Early return handling (decref before nested returns)
- ⏳ ADT RC (algebraic data types)
- ⏳ Last-use optimization / reuse (FBIP)
See [docs/REFERENCE_COUNTING.md](REFERENCE_COUNTING.md) for details.

View File

@@ -17,6 +17,7 @@ The RC system is now functional for lists and boxed values.
- List operations incref shared elements
- **Closures and environments** - RC-managed with automatic cleanup
- **Inline lambda cleanup** - temporary closures freed after use
- **ADT pointer fields** - RC-allocated and cleaned up at scope exit
- **Scope tracking** - compiler tracks RC variable lifetimes
- **Automatic decref at scope exit** - variables are freed when out of scope
- **Memory tracking** - debug mode reports allocs/frees at program exit
@@ -29,7 +30,6 @@ The RC system is now functional for lists and boxed values.
### What's NOT Yet Implemented
- Early return handling (decref before return in nested scopes)
- Conditional branch handling (complex if/else patterns)
- ADT RC
## The Problem
@@ -409,7 +409,7 @@ Rust's ownership system is fundamentally different:
- Environments allocated with `lux_rc_alloc(sizeof(LuxEnv_N), LUX_TAG_ENV)`
- Inline lambdas freed after use in List operations
2. **ADT RC** - Algebraic data types with heap fields
2. ~~**ADT RC**~~ ✅ DONE - Algebraic data types with heap fields
- Track which variants contain RC fields
- Generate drop functions for each ADT
- ~100 lines
@@ -448,14 +448,14 @@ Rust's ownership system is fundamentally different:
| Phase | Description | Lines | Priority | Status |
|-------|-------------|-------|----------|--------|
| A1 | Closure RC | ~50 | P0 | ✅ Done |
| A2 | ADT RC | ~100 | P1 - ADTs leak | Pending |
| A2 | ADT RC | ~150 | P1 | ✅ Done |
| A3 | Early returns | ~30 | P1 - Edge cases | Pending |
| A4 | Conditionals | ~50 | P2 - Uncommon | Pending |
| B1 | Last-use opt | ~200 | P3 - Performance | Pending |
| B2 | Reuse (FBIP) | ~300 | P3 - Performance | Pending |
| B3 | Drop special | ~100 | P3 - Performance | Pending |
**Phase A remaining: ~180 lines** - Gets us to "no leaks"
**Phase A remaining: ~80 lines** - Gets us to "no leaks"
**Phase B total: ~600 lines** - Gets us to Koka-level performance
### Cycle Detection