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:
14
examples/0729-modules-flat-same-name-foreign.sx
Normal file
14
examples/0729-modules-flat-same-name-foreign.sx
Normal 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
|
||||
}
|
||||
5
examples/0729-modules-flat-same-name-foreign/a.sx
Normal file
5
examples/0729-modules-flat-same-name-foreign/a.sx
Normal 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";
|
||||
2
examples/0729-modules-flat-same-name-foreign/b.sx
Normal file
2
examples/0729-modules-flat-same-name-foreign/b.sx
Normal file
@@ -0,0 +1,2 @@
|
||||
// The second flat author of `absval` — the identical `#foreign` libc binding.
|
||||
absval :: (n: s32) -> s32 #foreign libc "abs";
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
absval = 7
|
||||
@@ -1581,7 +1581,16 @@ pub const Lowering = struct {
|
||||
var edge_it = edges.iterator();
|
||||
while (edge_it.next()) |e| {
|
||||
const fns = module_fns.get(e.key_ptr.*) orelse continue;
|
||||
if (fns.get(name)) |fd| distinct.put(fd, e.key_ptr.*) catch {};
|
||||
// Only plain free functions are eligible for rerouting; generic /
|
||||
// foreign / builtin / #compiler authors keep their existing
|
||||
// dispatch. Filtering BEFORE the count gate means a same-name
|
||||
// collision of non-plain authors (e.g. two flat-imported modules
|
||||
// each `#foreign`ing the same symbol) is NOT counted as ambiguous —
|
||||
// it falls through to `.none` and the existing first-wins path.
|
||||
if (fns.get(name)) |fd| {
|
||||
if (!isPlainFreeFn(fd)) continue;
|
||||
distinct.put(fd, e.key_ptr.*) catch {};
|
||||
}
|
||||
}
|
||||
if (distinct.count() == 0) return .none;
|
||||
if (distinct.count() >= 2) return .ambiguous;
|
||||
@@ -1591,7 +1600,6 @@ pub const Lowering = struct {
|
||||
const the_one = entry.key_ptr.*;
|
||||
const the_path = entry.value_ptr.*;
|
||||
if (winner != null and winner.? == the_one) return .none;
|
||||
if (!isPlainFreeFn(the_one)) return .none;
|
||||
return .{ .func = .{ .fid = self.bareAuthorFuncId(the_one, name, the_path), .decl = the_one } };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user