jakt
jakt copied to clipboard
Dictionary is being recognized as void type
This code caught a bug:
struct Foo {
str: String
num: i64
function obj(this, mut dict: [String:i64]) throws -> [String:i64] {
return dict.set(.str, .num)
}
}
The error message I get is this:
Error: Cannot call mutating method on an immutable object instance
----- hello.jakt:11:16
9 | function obj(this, mutable dict: [String:i64]) throws -> [String:i64] {
10 | return dict.set(.str, .num)
^- Cannot call mutating method on an immutable object instance
11 | }
-----
The original code doesn't work even without this bug, so I modified it a bit:
struct Foo {
str: String
num: i64
function obj(this, mutable dict: [String:i64]) throws {
dict.set(key: .str, value: .num)
}
}
The problem seems to lie in the parse_function
function. It correctly parses the mutable
keyword and sets current_param_is_mutable
to true, but that variable is accessed only when parsing this
, as can be seen here:
https://github.com/SerenityOS/jakt/blob/168329cd6fc32da4e675c3ceead5765be8a86901/src/parser.rs#L1663-L1675
https://github.com/SerenityOS/jakt/blob/168329cd6fc32da4e675c3ceead5765be8a86901/src/parser.rs#L1677-L1702
Parsing of non-instance parameters is delegated to parse_variable_declaration
which doesn't encounter mutable
because it was already consumed by parse_function
. If I'm not missing anything, a fix should be trivial - to use current_param_is_mutable
instead of whatever parse_variable_declaration
returned. I'm going to make a PR with that change.
That change unfortunately isn't enough, it quickly backfires in static methods. I checked if it's going to work if I use current_param_is_mutable
in non static methods and the result of parse_variable_declaration
in static methods, It seems to be working correctly, doesn't seem like a proper fix tho.
current_param_is_mutable
is needed in non-static methods for mutable this
. So probably a current_param_is_mutable || var_decl.mutable
would work.
As of now, building the sample code results with a different error message:
4 | function obj(this, mut dict: [String:i64]) throws -> [String:i64] { 5 | return dict.set(.str, .num) ^- Type mismatch: expected ‘[String:i64]’, but got ‘void’ 6 | }
the tyepchecker is correct, dict.set
is void (check runtime.jakt)
Looks like the original issue has been fixed by another commit.
The question is how one is going to set a dictionary inside a function then? Without the return type the sample code is invalid cpp code.
fixed as of 1ea81c6