Resolved conflicts in:
- Monomorphizer.zig: Keep deletion of monomorphize() function
- RocEmitter.zig: Use cleaner e_lookup_external handling without capture
- roc_emitter_test.zig: Use undefined with comments for type vars
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Zig's archive generator doesn't add the required padding byte after
odd-sized members, causing lld to reject the archive. This adds a
build step that appends the missing padding byte when needed.
See https://codeberg.org/ziglang/zig/issues/30572
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The increfLayoutPtr function properly handled .tag_union layouts by
reading the discriminant and incrementing the reference count of the
active variant's payload. However, decrefLayoutPtr was missing this
handling entirely, causing memory leaks when tag union values with
heap-allocated payloads were freed.
This fix adds symmetric .tag_union handling to decrefLayoutPtr that
reads the discriminant and decrefs the active variant's payload.
Fixes#8710
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolved conflicts in src/cli/main.zig:
- Updated createUniqueTempDir to use ctx: *CliContext instead of allocs
- Kept cache cleanup via CacheConfig.getVersionTempDir approach
- Added background cache cleanup thread with new Io.init() pattern
- Updated exe_cache_dir to use ctx.arena with getExeCacheDir helper
- Fixed deleteTempDir calls to use ctx.arena
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The layout store was incorrectly adding alias types to in_progress_vars,
but aliases just continue to their backing type without ever being
"completed" (removed from in_progress_vars). This caused spurious cycle
detection when the same alias was encountered again during layout
computation for a nominal type like Try.
The fix is to skip adding aliases to in_progress_vars since they are
transparent wrappers that immediately continue to their backing type.
Fixes#8708
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused `self` parameter from Monomorphizer.monomorphize placeholder
- Remove unused `lookup` capture in RocEmitter e_lookup_external handler
- Replace @enumFromInt(0) with undefined for variant_var/ext_var in test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove separator comments (// ====) from mono_emit_test.zig
- Use _ parameter instead of _ = self for unused self in Monomorphizer
- Use |_| pattern for unused lookup in RocEmitter
- Replace @enumFromInt(0) with undefined in roc_emitter_test.zig
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Pure lambda test: validates closures with no captures work correctly
- Nested closure test: validates closures that return closures with
captures (currying pattern) work correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed closure tag names from backtick syntax (`f) to capitalized
tags (Closure_f) for valid Roc parsing
- Added roundtrip tests that verify transformed code evaluates to
the same result as the original source
- Updated all tests to expect new Closure_ tag prefix
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Completes the core of Slice 2 by implementing:
1. Closure binding tracking: The transformer now tracks which patterns
are bound to closures via pattern_closures map.
2. Dispatch match generation: When a call is made to a closure variable,
the transformer generates an inline match expression that:
- Pattern matches on the closure tag to extract captures
- Creates a block that binds call arguments to lambda parameters
- Executes the original lambda body with both captures and args in scope
Example transformation:
```roc
# Input
{
x = 42
f = |y| x + y
f(10)
}
# Output
{
x = 42
f = `f({x: x})
match f {
`f({x}) => {
y = 10
(x + y)
},
}
}
```
This completes the closure-to-defunctionalized-form transformation,
which is the foundation for lambda set specialization.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This implements the first part of Slice 2 (closures with captures) from the
monomorphization plan. The ClosureTransformer:
- Transforms closures with captures into tagged values with capture records
e.g., `|y| x + y` with captured `x` becomes `` `f({x: x}) ``
- Transforms pure lambdas (no captures) into tags with empty records
- Generates unique tag names based on binding hints or counters
- Recursively transforms all expression types in the CIR
Tests verify transformation of:
- Pure lambdas to tags with empty records
- Closures with single capture
- Closures with multiple captures
Next step: implement dispatch function generation for call sites.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This adds tests that verify emitted Roc code produces the same results
as the original when run through the interpreter:
- evalToInt/evalToBool helpers for evaluating expressions
- Roundtrip tests for:
- Integer literals
- Arithmetic expressions
- If expressions
- Boolean True/False
- Complex arithmetic
The tests parse source, emit it as Roc code, re-parse the emitted code,
run both through the interpreter, and verify they produce identical results.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This adds the foundation for the monomorphizing compiler:
- RocEmitter: Converts CIR (Canonical IR) to valid Roc source code
- Handles all expression types (numbers, lambdas, records, tags, etc.)
- Handles patterns and statements
- Unit tests for basic expression emission
- Monomorphizer: Infrastructure for specializing polymorphic functions
- Type hash computation for specialization keys
- Specialized name generation
- Integration with type system
- End-to-end tests in eval module:
- Parse -> Canonicalize -> Type Check -> Emit pipeline
- Tests for identity function, blocks, and basic expressions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>