The issue-0176 conformance gate was name-only, so an impl P for T with a mismatched return/param type (or arity) built a wrong-ABI thunk that silently miscompiled (exit 0, wrong value). firstUnimplementedMethod now validates arity (after self), each param type, and the return type against the protocol declaration, substituting protocol Self->concrete via resolveProtoTypeSubSelf (recurses through pointer/many-pointer/ optional/slice/array so []Self<->[]T match; conservative .unresolved for Self-in-generic-arg). Comparison is by structural formatTypeName (alias/module/spelling independent); typesClearlyDiffer skips when either side has an unresolved leaf at any depth, biasing against false-positives. Regressions: diagnostics/1201 (negative), protocols/0420 (positive, []Self param). Verified by 3+3 adversarial reviews (a mid-fix []Self false-positive was found and closed); suite 792/0.
23 lines
1.1 KiB
Plaintext
23 lines
1.1 KiB
Plaintext
// A protocol-method impl with the right NAME but a mismatched RETURN type (or
|
|
// parameter type) is a hard error, not a silent miscompile. Regression (issue
|
|
// 0178): the issue-0176 conformance gate is name-based, so an `impl P for T`
|
|
// whose method returns `bool` where the protocol method returns `i64` passed
|
|
// the gate and built a wrong-ABI thunk — dispatch through the erased protocol
|
|
// silently returned the wrong value (exit 0, no diagnostic). The conformance
|
|
// gate now validates each impl method's signature (arity after `self`, each
|
|
// parameter type, and the return type) against the protocol declaration, with
|
|
// `Self` substituted to the concrete type (so the REQUIRED `*T` / `T` impl form
|
|
// is NOT flagged). A clear type mismatch reports at the erasure site, exit 1.
|
|
|
|
#import "modules/std.sx";
|
|
|
|
P :: protocol { val :: (self: *Self) -> i64; }
|
|
T :: struct { n: i64 = 7; }
|
|
impl P for T { val :: (self: *T) -> bool { return true; } } // return bool != i64
|
|
|
|
main :: () {
|
|
t := T.{ n = 7 };
|
|
p : P = t; // <- 'T' does not implement 'P' (return type)
|
|
print("{}\n", p.val());
|
|
}
|