fix(lower): bare-call resolver skips non-plain authors before ambiguity gate [0102c F3]

resolveBareCallee's flat-collect branch counted ALL same-name authors —
including #foreign / generic / builtin / #compiler — before the
isPlainFreeFn filter, so two flat-imported modules each #foreign-ing the
same libc symbol under one sx name returned `.ambiguous` and errored,
instead of falling to `.none` and the existing first-wins foreign path
(master behavior). Filter authors to plain free functions DURING
collection, before the count/ambiguity determination: a non-plain
collision now yields 0 reroutable authors -> `.none`; genuine plain-fn
collisions still yield >= 2 -> `.ambiguous` (0724 unchanged). The
now-redundant single-author isPlainFreeFn check is dropped.

Regression: examples/0729-modules-flat-same-name-foreign — two flat FILE
imports each #foreign the same libc "abs" under name `absval`; a bare
call resolves first-wins and runs (exit 0). Fails-before on this branch
(ambiguity error), passes-after.
This commit is contained in:
agra
2026-06-06 15:31:14 +03:00
parent 8c88504849
commit 2131557669
7 changed files with 34 additions and 2 deletions

View File

@@ -0,0 +1,14 @@
// fix-0102c (issue 0102) F3 regression: two flat FILE imports each `#foreign`
// the SAME libc symbol under the SAME sx name `absval`. The bare-call resolver
// must NOT count `#foreign` (non-plain) authors when deciding ambiguity — it
// filters them out, returns "no rerouting", and the existing first-wins foreign
// dispatch binds the call. A same-name foreign collision therefore compiles and
// runs (master behavior), it does NOT error as ambiguous.
#import "modules/std.sx";
#import "0729-modules-flat-same-name-foreign/a.sx";
#import "0729-modules-flat-same-name-foreign/b.sx";
main :: () -> s32 {
print("absval = {}\n", absval(-7));
0
}

View File

@@ -0,0 +1,5 @@
// One of two flat authors of `absval`, a `#foreign` libc binding. A consumer
// flat-importing BOTH must NOT see this as an ambiguous bare-call collision —
// foreign authors are never rerouted by the bare-call resolver, so the call
// falls to the existing first-wins foreign dispatch.
absval :: (n: s32) -> s32 #foreign libc "abs";

View File

@@ -0,0 +1,2 @@
// The second flat author of `absval` — the identical `#foreign` libc binding.
absval :: (n: s32) -> s32 #foreign libc "abs";

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@
absval = 7