Skip to content

Conditionals using is expression do not propagate &mut declared in pattern arguments #1475

Open
@cg-jl

Description

@cg-jl

MVE:

/// Expect:
/// - output: "A::Foo(5)"

enum A {
    Foo(i32)
    Bar

    // asserts that `.a` is `Foo` and adds one to its content.
    fn foo_add_one_guard(mut this) {
        guard (&mut this) is Foo(&mut x) else {
            abort()
        }

        x += 1
    }

    // asserts that `.a` is `Foo` and adds one to its content.
    fn foo_add_one_if(mut this) {
        if (&mut this) is Foo(&mut x) {
            x += 1

        } else {
            abort()
        }
    }

    // asserts that `.a` is `Foo` and adds one to its content.
    fn foo_add_one_match(mut this) {
        match &mut this {
            Foo(&mut x) => {
                x += 1
            }
            else => {
                abort()
            }
        }
    }
}



fn main() {
    mut a = A::Foo(4)
    a.foo_add_one_guard()
    println("{}", a)
}

The compiler errors in both foo_add_one_if and foo_add_one_guard saying that x is not marked mutable:

[nix-shell:~/jakt]$ ./build/bin/jakt -cr mvs.jakt
Error: Assignment to immutable variable
────┬─ mvs.jakt:14:9
 13 │
 14 │         x += 1
    │         ─────┬
    │              ╰─ Assignment to immutable variable
 15 │     }
────┴─
Error: Assignment to immutable variable
────┬─ mvs.jakt:20:13
 19 │         if (&mut this) is Foo(&mut x) {
 20 │             x += 1
    │             ─────┬
    │                  ╰─ Assignment to immutable variable
 21 │
────┴─

Ideally if x is B(<arg>) would desugar to a match instead of an if, so that the semantics of pattern arguments have to be dealt with only once, which is already done correctly in match.

Note that foo_add_one_match would be a valid way to circunvent this issue, so it doesn't prevent the desired behavior from happening, just forces a path that uses match.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions