lang: require explicit receiver in protocol method declarations
Protocol method declarations now declare their receiver explicitly as the first parameter — 'self: *Self' (or 'self: Self') — matching the impl method signature, instead of the old implicit-receiver form where the listed params were only the extra args. That asymmetry repeatedly caused confusion over whether the first param was the receiver or an argument. The parser validates the first param is 'self' typed Self/*Self, then strips it, so all downstream lowering and the dispatch ABI are unchanged (impl blocks and call sites are unaffected). A protocol method missing the receiver is now a parse error. Migrated all 129 protocol method signatures across library + examples (+ one inline-sx test in sema.zig) to the explicit form. Updated specs.md + readme.md. New: examples/0418-protocols-explicit-receiver.sx (feature), examples/1190-diagnostics-protocol-missing-receiver.sx (negative/diagnostic).
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Show :: protocol {
|
||||
show :: () -> string;
|
||||
show :: (self: *Self) -> string;
|
||||
}
|
||||
A :: struct { x: i64; }
|
||||
B :: struct { s: string; }
|
||||
|
||||
@@ -10,11 +10,11 @@ mul :: (a: i32, b: i32) -> i32 { a * b }
|
||||
|
||||
// P4 edge: Chained default→default calls
|
||||
Chained :: protocol {
|
||||
base :: (msg: string) -> i32;
|
||||
wrap :: (msg: string) -> i32 {
|
||||
base :: (self: *Self, msg: string) -> i32;
|
||||
wrap :: (self: *Self, msg: string) -> i32 {
|
||||
self.base(msg) + 1
|
||||
}
|
||||
double_wrap :: (msg: string) -> i32 {
|
||||
double_wrap :: (self: *Self, msg: string) -> i32 {
|
||||
self.wrap(msg) + self.wrap(msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,11 +28,11 @@ apply :: (f: (i32, i32) -> i32, x: i32, y: i32) -> i32 {
|
||||
|
||||
// P4 edge: Chained default→default calls
|
||||
Chained :: protocol {
|
||||
base :: (msg: string) -> i32;
|
||||
wrap :: (msg: string) -> i32 {
|
||||
base :: (self: *Self, msg: string) -> i32;
|
||||
wrap :: (self: *Self, msg: string) -> i32 {
|
||||
self.base(msg) + 1
|
||||
}
|
||||
double_wrap :: (msg: string) -> i32 {
|
||||
double_wrap :: (self: *Self, msg: string) -> i32 {
|
||||
self.wrap(msg) + self.wrap(msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,12 @@ Point :: struct { x, y: i32; }
|
||||
add :: (a: i32, b: i32) -> i32 { a + b }
|
||||
|
||||
Counter :: protocol {
|
||||
inc :: ();
|
||||
get :: () -> i32;
|
||||
inc :: (self: *Self);
|
||||
get :: (self: *Self) -> i32;
|
||||
}
|
||||
|
||||
Summable :: protocol {
|
||||
sum :: () -> i32;
|
||||
sum :: (self: *Self) -> i32;
|
||||
}
|
||||
|
||||
SimpleCounter :: struct { val: i32; }
|
||||
|
||||
@@ -28,7 +28,7 @@ Tag :: union {
|
||||
|
||||
// Protocol method SIGNATURE spelled with a reserved type name — bare is legal.
|
||||
Speaker :: protocol {
|
||||
i2 :: () -> i64;
|
||||
i2 :: (self: *Self) -> i64;
|
||||
}
|
||||
|
||||
Dog :: struct { n: i64; }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#import "modules/math";
|
||||
|
||||
Lerpable :: protocol #inline {
|
||||
lerp :: (b: Self, t: f32) -> Self;
|
||||
lerp :: (self: *Self, b: Self, t: f32) -> Self;
|
||||
}
|
||||
|
||||
Size :: struct {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
MyProtocol :: protocol {
|
||||
get_value :: () -> i64;
|
||||
get_value :: (self: *Self) -> i64;
|
||||
}
|
||||
|
||||
MyImpl :: struct { value: i64; }
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// `#inline` erasure.
|
||||
|
||||
Lerpable :: protocol #inline {
|
||||
lerp :: (b: Self, t: f32) -> Self;
|
||||
lerp :: (self: *Self, b: Self, t: f32) -> Self;
|
||||
}
|
||||
|
||||
impl Lerpable for f32 {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Sizable :: protocol {
|
||||
size :: () -> i64;
|
||||
size :: (self: *Self) -> i64;
|
||||
}
|
||||
|
||||
Widget :: struct { value: i64; }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Sizable :: protocol {
|
||||
size :: () -> i64;
|
||||
size :: (self: *Self) -> i64;
|
||||
}
|
||||
|
||||
Leaf :: struct { value: i64; }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Sizable :: protocol {
|
||||
size :: () -> i64;
|
||||
size :: (self: *Self) -> i64;
|
||||
}
|
||||
|
||||
Leaf :: struct { value: i64; }
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Drawable :: protocol {
|
||||
draw :: () -> i32;
|
||||
name :: () -> string;
|
||||
layout :: (x: i32) -> i32;
|
||||
handle :: (event: i32) -> bool;
|
||||
draw :: (self: *Self) -> i32;
|
||||
name :: (self: *Self) -> string;
|
||||
layout :: (self: *Self, x: i32) -> i32;
|
||||
handle :: (self: *Self, event: i32) -> bool;
|
||||
}
|
||||
|
||||
Circle :: struct { radius: i32; }
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
Fmt :: enum { a; b; }
|
||||
|
||||
Proto :: protocol {
|
||||
take_fmt :: (f: Fmt);
|
||||
take_fmt :: (self: *Self, f: Fmt);
|
||||
}
|
||||
|
||||
Impl :: struct {}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Proto :: protocol {
|
||||
get :: () -> *u8;
|
||||
get :: (self: *Self) -> *u8;
|
||||
}
|
||||
|
||||
Impl :: struct {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
GPU :: protocol {
|
||||
ping :: () -> i64;
|
||||
ping :: (self: *Self) -> i64;
|
||||
}
|
||||
|
||||
Impl :: struct {}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
VL :: protocol(T: Type) { get :: () -> T; }
|
||||
VL :: protocol(T: Type) { get :: (self: *Self) -> T; }
|
||||
IntCell :: struct { v: i64; }
|
||||
StrCell :: struct { s: string; }
|
||||
impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
VL :: protocol(T: Type) { get :: () -> T; }
|
||||
VL :: protocol(T: Type) { get :: (self: *Self) -> T; }
|
||||
IntCell :: struct { v: i64; }
|
||||
impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
|
||||
|
||||
@@ -203,12 +203,12 @@ c_abs :: (n: i32) -> i32 extern libc "abs";
|
||||
// --- Protocol declarations (Phase 1: static dispatch only) ---
|
||||
|
||||
Counter :: protocol {
|
||||
inc :: ();
|
||||
get :: () -> i32;
|
||||
inc :: (self: *Self);
|
||||
get :: (self: *Self) -> i32;
|
||||
}
|
||||
|
||||
Summable :: protocol {
|
||||
sum :: () -> i32;
|
||||
sum :: (self: *Self) -> i32;
|
||||
}
|
||||
|
||||
SimpleCounter :: struct { val: i32; }
|
||||
@@ -226,8 +226,8 @@ impl Summable for Point {
|
||||
|
||||
// Phase 2: #inline protocol for dynamic dispatch
|
||||
Adder :: protocol #inline {
|
||||
add :: (n: i32);
|
||||
value :: () -> i32;
|
||||
add :: (self: *Self, n: i32);
|
||||
value :: (self: *Self) -> i32;
|
||||
}
|
||||
|
||||
Accumulator :: struct {
|
||||
@@ -250,8 +250,8 @@ impl Adder for Doubler {
|
||||
|
||||
// Phase 4: default methods
|
||||
Repeater :: protocol {
|
||||
say :: (msg: string);
|
||||
say_twice :: (msg: string) {
|
||||
say :: (self: *Self, msg: string);
|
||||
say_twice :: (self: *Self, msg: string) {
|
||||
self.say(msg);
|
||||
self.say(msg);
|
||||
}
|
||||
@@ -270,11 +270,11 @@ impl Repeater for Printer {
|
||||
|
||||
// P4 edge: Chained default→default calls
|
||||
Chained :: protocol {
|
||||
base :: (msg: string) -> i32;
|
||||
wrap :: (msg: string) -> i32 {
|
||||
base :: (self: *Self, msg: string) -> i32;
|
||||
wrap :: (self: *Self, msg: string) -> i32 {
|
||||
self.base(msg) + 1
|
||||
}
|
||||
double_wrap :: (msg: string) -> i32 {
|
||||
double_wrap :: (self: *Self, msg: string) -> i32 {
|
||||
self.wrap(msg) + self.wrap(msg)
|
||||
}
|
||||
}
|
||||
@@ -291,7 +291,7 @@ impl Chained for ChainImpl {
|
||||
|
||||
// Phase 5: Self type
|
||||
Eq :: protocol {
|
||||
eq :: (other: Self) -> bool;
|
||||
eq :: (self: *Self, other: Self) -> bool;
|
||||
}
|
||||
|
||||
impl Eq for Point {
|
||||
@@ -301,7 +301,7 @@ impl Eq for Point {
|
||||
}
|
||||
|
||||
Cloneable :: protocol {
|
||||
clone :: () -> Self;
|
||||
clone :: (self: *Self) -> Self;
|
||||
}
|
||||
|
||||
impl Cloneable for Point {
|
||||
@@ -324,7 +324,7 @@ are_equal :: ($T: Type/Eq, a: T, b: T) -> bool {
|
||||
}
|
||||
|
||||
Hashable :: protocol {
|
||||
hash :: () -> i64;
|
||||
hash :: (self: *Self) -> i64;
|
||||
}
|
||||
|
||||
impl Hashable for Point {
|
||||
|
||||
@@ -9,12 +9,12 @@ Point :: struct { x, y: i32; }
|
||||
add :: (a: i32, b: i32) -> i32 { a + b }
|
||||
|
||||
Counter :: protocol {
|
||||
inc :: ();
|
||||
get :: () -> i32;
|
||||
inc :: (self: *Self);
|
||||
get :: (self: *Self) -> i32;
|
||||
}
|
||||
|
||||
Summable :: protocol {
|
||||
sum :: () -> i32;
|
||||
sum :: (self: *Self) -> i32;
|
||||
}
|
||||
|
||||
SimpleCounter :: struct { val: i32; }
|
||||
@@ -32,8 +32,8 @@ impl Summable for Point {
|
||||
|
||||
// Phase 2: #inline protocol for dynamic dispatch
|
||||
Adder :: protocol #inline {
|
||||
add :: (n: i32);
|
||||
value :: () -> i32;
|
||||
add :: (self: *Self, n: i32);
|
||||
value :: (self: *Self) -> i32;
|
||||
}
|
||||
|
||||
Accumulator :: struct {
|
||||
|
||||
@@ -24,7 +24,7 @@ Keycode :: enum { unknown; escape; enter; }
|
||||
KeyData :: struct { key: Keycode; }
|
||||
Event :: enum { none; key_up: KeyData; }
|
||||
|
||||
Plat :: protocol { one_event :: () -> Event; }
|
||||
Plat :: protocol { one_event :: (self: *Self) -> Event; }
|
||||
|
||||
Impl :: struct { dummy: i64; }
|
||||
impl Plat for Impl {
|
||||
|
||||
47
examples/0418-protocols-explicit-receiver.sx
Normal file
47
examples/0418-protocols-explicit-receiver.sx
Normal file
@@ -0,0 +1,47 @@
|
||||
// Protocol methods declare their receiver EXPLICITLY as the first parameter —
|
||||
// `self: *Self` (or `self: Self`) — matching the `impl` method signature. This
|
||||
// is required (the old implicit-receiver form is a parse error). The receiver
|
||||
// annotation is validated then erased, so dispatch and call sites are unchanged:
|
||||
// a method with N declared extra args is still called with N args.
|
||||
#import "modules/std.sx";
|
||||
|
||||
Size :: struct { w: i32; h: i32; }
|
||||
|
||||
// `self: *Self` receiver; one no-arg method and one with extra args.
|
||||
Measurable :: protocol #inline {
|
||||
measure :: (self: *Self) -> Size;
|
||||
scaled :: (self: *Self, factor: i32) -> Size;
|
||||
}
|
||||
|
||||
// `self: Self` (by-value) receiver is also accepted.
|
||||
Named :: protocol {
|
||||
name :: (self: Self) -> string;
|
||||
}
|
||||
|
||||
Widget :: struct { base: i32; }
|
||||
|
||||
impl Measurable for Widget {
|
||||
measure :: (self: *Widget) -> Size { return Size.{ w = self.base, h = self.base * 2 }; }
|
||||
scaled :: (self: *Widget, factor: i32) -> Size {
|
||||
return Size.{ w = self.base * factor, h = self.base * 2 * factor };
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for Widget {
|
||||
name :: (self: Widget) -> string { return "widget"; }
|
||||
}
|
||||
|
||||
main :: () -> i32 {
|
||||
w : Widget = .{ base = 5 };
|
||||
p : *Widget = @w;
|
||||
|
||||
m : Measurable = xx p;
|
||||
s := m.measure(); // 0 extra args
|
||||
s2 := m.scaled(3); // 1 extra arg
|
||||
print("measure={}x{}\n", s.w, s.h); // 5x10
|
||||
print("scaled={}x{}\n", s2.w, s2.h); // 15x30
|
||||
|
||||
n : Named = xx p;
|
||||
print("name={}\n", n.name()); // widget
|
||||
return 0;
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
// User-defined parameterised protocol + an impl, so has_impl can
|
||||
// confirm parameterised matching works with a known-true case.
|
||||
Wrap :: protocol(Target: Type) {
|
||||
wrap :: () -> Target;
|
||||
wrap :: (self: *Self) -> Target;
|
||||
}
|
||||
|
||||
impl Wrap(i64) for i32 {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Greeter :: protocol {
|
||||
greet :: () -> i64;
|
||||
greet :: (self: *Self) -> i64;
|
||||
}
|
||||
|
||||
Dog :: struct { age: i64; }
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Box :: protocol(T: Type) {
|
||||
get :: () -> T;
|
||||
get :: (self: *Self) -> T;
|
||||
}
|
||||
|
||||
IntCell :: struct { v: i64; }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Box :: protocol(T: Type) {
|
||||
get :: () -> T;
|
||||
get :: (self: *Self) -> T;
|
||||
}
|
||||
IntCell :: struct { v: i64; }
|
||||
impl Box(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Box :: protocol(T: Type) {
|
||||
get :: () -> T;
|
||||
get :: (self: *Self) -> T;
|
||||
}
|
||||
|
||||
IntCell :: struct { v: i64; }
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Box :: protocol(T: Type) {
|
||||
get :: () -> i64;
|
||||
get :: (self: *Self) -> i64;
|
||||
}
|
||||
IntCell :: struct { v: i64; }
|
||||
Dbl :: struct { n: i64; }
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Box :: protocol(T: Type) {
|
||||
get :: () -> T;
|
||||
get :: (self: *Self) -> T;
|
||||
}
|
||||
IntCell :: struct { v: i64; }
|
||||
StrCell :: struct { s: string; }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Box :: protocol(T: Type) {
|
||||
get :: () -> T;
|
||||
get :: (self: *Self) -> T;
|
||||
}
|
||||
|
||||
IntCell :: struct { v: i64; }
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
Show :: protocol { show :: () -> string; }
|
||||
Show :: protocol { show :: (self: *Self) -> string; }
|
||||
A :: struct { x: i64; }
|
||||
B :: struct { s: string; }
|
||||
impl Show for A { show :: (self: *A) -> string => "A"; }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
Show :: protocol { show :: () -> string; }
|
||||
Show :: protocol { show :: (self: *Self) -> string; }
|
||||
A :: struct {}
|
||||
impl Show for A { show :: (self: *A) -> string => "A"; }
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
Show :: protocol { show :: () -> string; }
|
||||
Show :: protocol { show :: (self: *Self) -> string; }
|
||||
A :: struct {}
|
||||
B :: struct { s: string; }
|
||||
impl Show for A { show :: (self: *A) -> string => "A"; }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
VL :: protocol(T: Type) { get :: () -> T; }
|
||||
VL :: protocol(T: Type) { get :: (self: *Self) -> T; }
|
||||
IntCell :: struct { v: i64; }
|
||||
StrCell :: struct { s: string; }
|
||||
impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
VL :: protocol(T: Type) { get :: () -> T; }
|
||||
VL :: protocol(T: Type) { get :: (self: *Self) -> T; }
|
||||
IntCell :: struct { v: i64; }
|
||||
impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
VL :: protocol(T: Type) { get :: () -> T; }
|
||||
VL :: protocol(T: Type) { get :: (self: *Self) -> T; }
|
||||
IntCell :: struct { v: i64; }
|
||||
StrCell :: struct { s: string; }
|
||||
impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
VL :: protocol(T: Type) { get :: () -> T; }
|
||||
VL :: protocol(T: Type) { get :: (self: *Self) -> T; }
|
||||
IntCell :: struct { v: i64; }
|
||||
impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
VL :: protocol(T: Type) { get :: () -> T; }
|
||||
VL :: protocol(T: Type) { get :: (self: *Self) -> T; }
|
||||
IntCell :: struct { v: i64; }
|
||||
impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
Show :: protocol { show :: () -> string; }
|
||||
Show :: protocol { show :: (self: *Self) -> string; }
|
||||
IntBox :: struct { v: i64; }
|
||||
StrBox :: struct { s: string; }
|
||||
impl Show for IntBox { show :: (self: *IntBox) -> string { int_to_string(self.v) } }
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
VL :: protocol(T: Type) { get :: () -> T; }
|
||||
VL :: protocol(T: Type) { get :: (self: *Self) -> T; }
|
||||
IntCell :: struct { v: i64; }
|
||||
impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
VL :: protocol(T: Type) { get :: () -> T; }
|
||||
VL :: protocol(T: Type) { get :: (self: *Self) -> T; }
|
||||
IntCell :: struct { v: i64; }
|
||||
impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; }
|
||||
Doubler :: struct { n: i64; }
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
Box :: struct { m: i32; }
|
||||
|
||||
Provider :: protocol {
|
||||
get :: () -> Box;
|
||||
get :: (self: *Self) -> Box;
|
||||
}
|
||||
|
||||
Holder :: struct { val: i32 = 7; }
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#import "0821-protocols-same-name-method-ambiguous/b.sx";
|
||||
|
||||
Provider :: protocol {
|
||||
get :: () -> Box;
|
||||
get :: (self: *Self) -> Box;
|
||||
}
|
||||
|
||||
main :: () -> i32 {
|
||||
|
||||
@@ -21,17 +21,17 @@ Holder :: struct { b: Box = ---; }
|
||||
|
||||
Provider :: protocol {
|
||||
// discriminating wrapped/compound RETURNS
|
||||
getp :: () -> *Box;
|
||||
geto :: () -> ?Box;
|
||||
gett :: () -> (Box, Box);
|
||||
geta :: () -> [2]Box;
|
||||
getp :: (self: *Self) -> *Box;
|
||||
geto :: (self: *Self) -> ?Box;
|
||||
gett :: (self: *Self) -> (Box, Box);
|
||||
geta :: (self: *Self) -> [2]Box;
|
||||
// routing-only wrapped/compound PARAMS
|
||||
sump :: (p: *Box) -> i32;
|
||||
sumo :: (o: ?Box) -> i32;
|
||||
sums :: (s: []Box) -> i32;
|
||||
suma :: (a: [2]Box) -> i32;
|
||||
sumt :: (t: (Box, Box)) -> i32;
|
||||
sumn :: (n: *?[]Box) -> i32;
|
||||
sump :: (self: *Self, p: *Box) -> i32;
|
||||
sumo :: (self: *Self, o: ?Box) -> i32;
|
||||
sums :: (self: *Self, s: []Box) -> i32;
|
||||
suma :: (self: *Self, a: [2]Box) -> i32;
|
||||
sumt :: (self: *Self, t: (Box, Box)) -> i32;
|
||||
sumn :: (self: *Self, n: *?[]Box) -> i32;
|
||||
}
|
||||
|
||||
impl Provider for Holder {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#import "0825-protocols-same-name-method-wrapped-ambiguous/b.sx";
|
||||
|
||||
Provider :: protocol {
|
||||
getp :: () -> *Box;
|
||||
getp :: (self: *Self) -> *Box;
|
||||
}
|
||||
|
||||
main :: () -> i32 {
|
||||
|
||||
@@ -15,7 +15,7 @@ Box :: struct { m: i32; }
|
||||
Holder :: struct { n: i32; }
|
||||
|
||||
Tagged :: protocol(T: Type) {
|
||||
tag :: () -> i32;
|
||||
tag :: (self: *Self) -> i32;
|
||||
}
|
||||
|
||||
impl Tagged(*Box) for Holder {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
Block :: struct { tag: i32; }
|
||||
|
||||
Sink :: protocol(T: Type) {
|
||||
convert :: () -> T;
|
||||
convert :: (self: *Self) -> T;
|
||||
}
|
||||
|
||||
impl Sink(Block) for Closure(*Box, ..$args) -> $R {
|
||||
|
||||
@@ -10,7 +10,7 @@ ProposedSize :: struct {
|
||||
}
|
||||
|
||||
Sizable :: protocol {
|
||||
size :: (proposal: ProposedSize) -> f32;
|
||||
size :: (self: *Self, proposal: ProposedSize) -> f32;
|
||||
}
|
||||
|
||||
Widget :: struct {}
|
||||
|
||||
@@ -16,7 +16,7 @@ direct_size :: (proposal: ProposedSize) -> f32 {
|
||||
}
|
||||
|
||||
Sizable :: protocol {
|
||||
size :: (proposal: ProposedSize) -> f32;
|
||||
size :: (self: *Self, proposal: ProposedSize) -> f32;
|
||||
}
|
||||
|
||||
Widget :: struct {}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
Show :: protocol { show :: () -> string; }
|
||||
Show :: protocol { show :: (self: *Self) -> string; }
|
||||
IntBox :: struct { v: i64; }
|
||||
impl Show for IntBox { show :: (self: *IntBox) -> string { int_to_string(self.v) } }
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Foo :: struct {
|
||||
weird :: (self: *Foo) -> $T { 0 }
|
||||
}
|
||||
|
||||
Show2 :: protocol { show2 :: () -> string; }
|
||||
Show2 :: protocol { show2 :: (self: *Self) -> string; }
|
||||
IntBox :: struct { v: i64; }
|
||||
impl Show2 for IntBox {
|
||||
show2 :: (self: *IntBox) -> string { "x" }
|
||||
|
||||
12
examples/1190-diagnostics-protocol-missing-receiver.sx
Normal file
12
examples/1190-diagnostics-protocol-missing-receiver.sx
Normal file
@@ -0,0 +1,12 @@
|
||||
// A protocol method that omits the explicit receiver (the old implicit form)
|
||||
// is now a parse error — the receiver `self: *Self`/`self: Self` is required as
|
||||
// the first parameter. This guards the diagnostic.
|
||||
#import "modules/std.sx";
|
||||
|
||||
Show :: protocol {
|
||||
show :: () -> string; // ERROR: missing `self` receiver
|
||||
}
|
||||
|
||||
main :: () -> i32 {
|
||||
return 0;
|
||||
}
|
||||
1
examples/expected/0418-protocols-explicit-receiver.exit
Normal file
1
examples/expected/0418-protocols-explicit-receiver.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
measure=5x10
|
||||
scaled=15x30
|
||||
name=widget
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,5 @@
|
||||
error: protocol method must declare its receiver as the first parameter: `self: *Self` (or `self: Self`)
|
||||
--> examples/1190-diagnostics-protocol-missing-receiver.sx:7:16
|
||||
|
|
||||
7 | show :: () -> string; // ERROR: missing `self` receiver
|
||||
| ^^
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user