fix(lower): infer no-annotation return type with params in scope (issue 0059)
A function with no explicit return type (arrow `=> expr`, or a block whose `return <v>` drives the type) has its return type inferred from the body — but the body references the function's own params. resolveReturnType ran that inference before the params were pushed into self.scope (they're bound later, at body lowering), so inferExprType couldn't resolve them and yielded .unresolved, which reached LLVM emission and panicked. It only worked when a same-named binding lingered in scope from earlier lowering (e.g. inside the big smoke file). Bind the function's plain annotated value params into a temporary scope during return-type inference. Resolve their types via resolveTypeWithBindings rather than resolveParamType — the latter does variadic/pack bookkeeping that must run exactly once, at body lowering; calling it here too corrupted the format/index path. Variadic/pack/comptime/unannotated params are skipped (no by-name return dependency; their types come from substitution). Regression: examples/0308-closures-arrow-inferred-return.sx (arrow + block inferred-return, top-level + local). Resolves issue 0059. Suite: 293 passed.
This commit is contained in:
@@ -1,5 +1,18 @@
|
||||
# 0059 — expression-bodied lambda with inferred return type reaches LLVM emission unresolved
|
||||
|
||||
> **✅ RESOLVED.** Root cause: `resolveReturnType` ([src/ir/lower.zig]) infers a
|
||||
> no-annotation function's return type from its body, but the body references the
|
||||
> function's own params — which weren't in `self.scope` yet (they're bound later,
|
||||
> at body lowering). So `inferExprType` couldn't resolve `x` in `(x: s32) => x * 2`
|
||||
> and returned `.unresolved`, which reached LLVM emission. It only slipped through
|
||||
> when a same-named binding happened to linger in scope from earlier lowering.
|
||||
> Fix: bind the function's plain annotated value params into a temporary scope
|
||||
> during return-type inference (resolving types directly via
|
||||
> `resolveTypeWithBindings`, not `resolveParamType`, whose variadic/pack
|
||||
> bookkeeping must run exactly once at body lowering). Covers both the arrow (`=>`)
|
||||
> and inferred-via-`return` forms. Regression test:
|
||||
> `examples/0308-closures-arrow-inferred-return.sx`.
|
||||
|
||||
## Symptom
|
||||
|
||||
An expression-bodied lambda (`name :: (params) => expr;`) **without** an explicit
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// Repro for issue 0059: an expression-bodied `=>` lambda with an INFERRED
|
||||
// return type reaches LLVM emission with an unresolved return type and panics.
|
||||
// Adding an explicit `-> s32` makes it work; so does burying the same lambda
|
||||
// inside a large program (examples/.../50-smoke had it and ran fine).
|
||||
//
|
||||
// Expected: prints `14`, exit 0.
|
||||
// Actual: panic "unresolved type reached LLVM emission" (SIGABRT, exit 134).
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
f :: (x: s32) => x * 2;
|
||||
|
||||
main :: () {
|
||||
print("{}\n", f(7));
|
||||
}
|
||||
Reference in New Issue
Block a user