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.
25 lines
1.1 KiB
Plaintext
25 lines
1.1 KiB
Plaintext
// Regression (issue 0059): a function with NO explicit return type infers it
|
|
// from the body, which references the function's own parameters. The inference
|
|
// must see those params — before the fix they weren't in scope during
|
|
// return-type resolution, so the inferred type came out `.unresolved` and tripped
|
|
// the LLVM-emission guard ("unresolved type reached LLVM emission"). Whether it
|
|
// slipped through used to depend on a same-named binding lingering from earlier
|
|
// lowering. Covers the arrow (`=>`) and inferred-via-`return` forms, at top level
|
|
// and as locals.
|
|
|
|
#import "modules/std.sx";
|
|
|
|
dbl :: (x: s32) => x * 2; // top-level arrow, inferred return
|
|
inc :: (x: s32) { return x + 1; } // top-level block, inferred via `return`
|
|
|
|
main :: () {
|
|
print("{}\n", dbl(7)); // 14
|
|
print("{}\n", inc(41)); // 42
|
|
|
|
tripl :: (x: s32) => x * 3; // local arrow, inferred return
|
|
print("{}\n", tripl(4)); // 12
|
|
|
|
half :: (x: f32) => x / 2.0; // inferred float return
|
|
print("{}\n", half(9.0)); // 4.500000
|
|
}
|