jakt icon indicating copy to clipboard operation
jakt copied to clipboard

Dictionary is being recognized as void type

Open 0verse opened this issue 2 years ago • 7 comments

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 |     } 
-----

0verse avatar Jun 02 '22 16:06 0verse

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.

thatbakamono avatar Jun 03 '22 20:06 thatbakamono

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.

thatbakamono avatar Jun 03 '22 22:06 thatbakamono

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.

cg-jl avatar Jun 04 '22 16:06 cg-jl

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 | }

0verse avatar Jun 22 '22 14:06 0verse

the tyepchecker is correct, dict.set is void (check runtime.jakt)

cg-jl avatar Jun 22 '22 18:06 cg-jl

Looks like the original issue has been fixed by another commit.

cg-jl avatar Jun 22 '22 18:06 cg-jl

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.

0verse avatar Jun 23 '22 16:06 0verse

fixed as of 1ea81c6

lanmonster avatar Sep 01 '22 15:09 lanmonster