issue 0131: protocol method calls silently drop extra arguments

This commit is contained in:
agra
2026-06-12 21:44:07 +03:00
parent 81fa50c77d
commit ff94b004c4

View File

@@ -0,0 +1,54 @@
# 0131 — protocol method call with extra arguments compiles and silently drops them
## Symptom
Calling a protocol method with MORE arguments than the protocol
declares is accepted by the compiler; the extra arguments are silently
dropped at the call. Observed: `Allocator.dealloc_bytes` is declared
`(ptr: *void)`, yet `a.dealloc_bytes(p, 12345)` compiles and runs
under both `sx run` and `sx build`. Expected: a compile diagnostic
("expected 1 argument, got 2"), exactly as for plain function calls.
Found via std.http (PLAN-HTTPZ S7a): three `dealloc_bytes(ptr, size)`
calls — written against an imagined two-arg signature — compiled
clean and survived the full example sweep. Corrected in `81fa50c`;
this issue is about the missing diagnostic.
## Reproduction
```sx
#import "modules/std.sx";
main :: () -> i32 {
gpa := GPA.init();
a : Allocator = xx gpa;
p := a.alloc_bytes(64);
a.dealloc_bytes(p, 12345); // protocol declares (ptr) — must be rejected
print("compiled and ran\n");
return 0;
}
```
Run `sx run repro.sx`: prints "compiled and ran", exit 0. Expected: a
compile error naming the arity mismatch.
## Investigation prompt
The sx compiler accepts protocol method calls with extra trailing
arguments and silently drops them (repro above — `Allocator.
dealloc_bytes(ptr)` called with `(ptr, extra)` compiles and runs).
Plain function calls DO arity-check, so the gap is specific to the
protocol-dispatch call path. Suspected area: the protocol call
planning/lowering in `src/ir/lower/call.zig` (and/or the protocol
method resolution in `src/ir/protocols.zig`) — wherever a protocol
method's parameter list is matched against call-site args, the
arg-count check that plain calls get is likely skipped, and lowering
then truncates args to the method's param count. The fix should emit
the same diagnostic plain calls produce (expected N args, got M) for
both too many AND verify too few is also caught. Verify with the
repro (expect a compile error) plus a negative-test example or a
`call.test.zig` case pinning the diagnostic; then `zig build &&
zig build test && bash tests/run_examples.sh` all green (existing
examples must not regress — if any example relied on dropped extra
args, that example is itself a latent bug to fix in the same
session).