Erasing a type to a protocol when it conforms only via a free function (not an explicit impl P for T) built a vtable of unreachable thunks -> SIGABRT on first dispatch, with no diagnostic. Per specs.md erasure is impl-driven, not structural, so the erasure was never valid. Add a conformance gate (firstUnimplementedMethod in buildProtocolValue, src/ir/lower/protocol.zig): emit a located diagnostic when a protocol method has no reachable impl, or when an impl method introduces its own type params (signature mismatch — it bails lazyLowerFunction and would reach the unreachable thunk). A std.debug.panic tripwire guards the diagnostics==null path so a non-conforming erasure can never silently ship as undef. Gate<->thunk equivalence verified bidirectional. Regressions: protocols/0419 (positive struct-field dispatch), diagnostics/1197 (no-impl) + 1198 (generic-method signature mismatch). Updated memory/0808 (it erased a non-conforming type that never dispatched). Verified by 3+1 adversarial reviews, suite 788/0. Filed adjacent bug 0178 (protocol impl method type-mismatch silent miscompile).
6 lines
428 B
Plaintext
6 lines
428 B
Plaintext
error: 'Dog' does not implement protocol 'Speaker': no `impl Speaker for Dog` provides method 'speak' (protocol erasure is impl-driven — a plain or `ufcs` free function with a matching receiver does not satisfy a protocol)
|
|
--> examples/diagnostics/1197-diagnostics-protocol-erasure-no-impl.sx:18:16
|
|
|
|
|
18 | h : Holder = .{ s = d, b = 5 }; // <- 'Dog' does not implement 'Speaker'
|
|
| ^^^^^^^^^^^^^^^^^
|