Skip to content

Commit

Permalink
Don't allow self param for implicit method declarations. fixes #71
Browse files Browse the repository at this point in the history
  • Loading branch information
fubark committed Jan 20, 2024
1 parent 2e6f0e3 commit d5de734
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ var n = [Node value: 123, next: none]
n.incAndPrint() -- Prints "444"
```

Methods can also be declared outside of the type declaration. To distinguish a method from a type function, `self` must be provided as a parameter:
Methods can be declared outside of the type declaration. When using the flat declaration style, `self` must be the first parameter to distinguish it from a type function:
```cy
func Node.getNext(self):
return self.next
Expand Down
3 changes: 2 additions & 1 deletion src/parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -831,9 +831,10 @@ pub const Parser = struct {
self.cur_indent = reqIndent;
defer self.cur_indent = prevIndent;

var numFields: u32 = 0;
var firstField = (try self.parseObjectField()) orelse NullId;
var numFields: u32 = 1;
if (firstField != NullId) {
numFields += 1;
var lastField = firstField;

while (true) {
Expand Down
4 changes: 4 additions & 0 deletions src/sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1699,6 +1699,10 @@ fn resolveImplicitMethodDecl(c: *cy.Chunk, parent: *Sym, nodeId: cy.NodeId) !Fun
var curParamId = header.head.funcHeader.paramHead;
while (curParamId != cy.NullId) {
const param = c.nodes[curParamId];
const paramName = c.ast.getNodeStringById(param.head.funcParam.name);
if (std.mem.eql(u8, "self", paramName)) {
return c.reportErrorAt("`self` param is not allowed in an implicit method declaration.", &.{}, curParamId);
}
const typeId = try resolveTypeFromSpecNode(c, param.head.funcParam.typeSpecHead);
try c.typeStack.append(c.alloc, typeId);
curParamId = param.next;
Expand Down
2 changes: 1 addition & 1 deletion test/behavior_test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ const Runner = struct {
}
};

// const caseFilter: ?[]const u8 = "call_recursive";
const caseFilter: ?[]const u8 = null;

// TODO: This could be split into compiler only tests and backend tests.
Expand Down Expand Up @@ -137,6 +136,7 @@ if (!aot) {
run.case("functions/call_typed_param.cy");
run.case("functions/call_undeclared_error.cy");
run.case("functions/declare_over_builtin.cy");
run.case("functions/method_self_param_error.cy");
run.case("functions/object_funcs.cy");
run.case("functions/overload.cy");
run.case("functions/read_capture_local_error.cy");
Expand Down
11 changes: 11 additions & 0 deletions test/functions/method_self_param_error.cy
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
type A:
func b(self):
pass

--cytest: error
--CompileError: `self` param is not allowed in an implicit method declaration.
--
--main:2:12:
-- func b(self):
-- ^
--

0 comments on commit d5de734

Please sign in to comment.