fix(lower): fn-value site lazily lowers winner only on resolver .none [0102d F1]
The bare-fn-as-value site (func_ref / fn-ptr / closure coercion) eagerly lazily-lowered the name-keyed first-wins WINNER before the resolveBareCallee block could reroute a genuine flat same-name collision to its per-source author. Taking a SHADOW author's fn value therefore lowered (and could mis-diagnose) the unused winner's body. Move lazyLowerFunction INSIDE blk_fv onto the `.none` fallback only, mirroring the closure(fn) and free-function UFCS sites: on `.func` use the resolved author's FuncId and never touch the winner; on `.none` fall through to lazy-lower + resolveFuncByName the winner. Regression: examples/0735-modules-flat-same-name-fn-value-winner — the first-wins winner's body is independently broken and never used; a shadow taken as a function value binds the shadow and runs (exit 0) while the winner is not lowered. Fails-before (unresolved symbol in the winner), passes-after.
This commit is contained in:
17
examples/0735-modules-flat-same-name-fn-value-winner.sx
Normal file
17
examples/0735-modules-flat-same-name-fn-value-winner.sx
Normal file
@@ -0,0 +1,17 @@
|
||||
// fix-0102d site 2 / attempt-2 (issue 0102): the first-wins winner's body is
|
||||
// independently BROKEN (references an undefined symbol) and is never used. A
|
||||
// shadow author from a later flat import takes its OWN `pick` as a function
|
||||
// VALUE (`g : () -> s64 = pick`). The value must bind the shadow (own-author
|
||||
// wins) and the broken winner must NOT be lowered — a rerouted fn value never
|
||||
// uses the winner. Before the fix the fn-value site eagerly lazily-lowered the
|
||||
// name-keyed winner BEFORE the resolver rerouted, surfacing the winner's
|
||||
// `unresolved 'missing_from_a'` for a function the value never touches.
|
||||
// Regression: per-source function-value conversion must not pre-lower the winner.
|
||||
#import "modules/std.sx";
|
||||
#import "0735-modules-flat-same-name-fn-value-winner/a.sx";
|
||||
#import "0735-modules-flat-same-name-fn-value-winner/b.sx";
|
||||
|
||||
main :: () -> s32 {
|
||||
print("from_b_value = {}\n", from_b_value());
|
||||
0
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// a.sx authors `pick` (imported first → the first-wins name-keyed winner) but
|
||||
// its body references an undefined symbol, so lowering a.pick AT ALL is an
|
||||
// error. Nothing uses a.pick — taking b.pick as a value must not pre-lower it.
|
||||
pick :: () -> s64 { return missing_from_a(); }
|
||||
@@ -0,0 +1,7 @@
|
||||
// b.sx authors its OWN `pick` (returns 2) and takes it as a function VALUE. The
|
||||
// value binds b.pick (own-author wins), never the broken winner from a.sx.
|
||||
pick :: () -> s64 { return 2; }
|
||||
from_b_value :: () -> s64 {
|
||||
g : () -> s64 = pick;
|
||||
return g();
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from_b_value = 2
|
||||
Reference in New Issue
Block a user