Files
sx/issues/0131-protocol-call-extra-args-silently-dropped.md
2026-06-12 21:52:11 +03:00

2.7 KiB

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

#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).

Resolution

RESOLVED (merged master d7808f6, 2026-06-12, Agra-directed in-session fix). emitProtocolDispatch arity-checks exactly (extra AND missing args) with the standard "expects N arguments" diagnostic at the call span. Regression pinned by examples/1634-protocol-call-arity; sweep 622/622 + unit tests green — nothing in the tree relied on the leniency. The three std.http call sites that exposed the gap were corrected separately in 81fa50c.