salient-lang / salient

http://salient-lang.dev/
MIT License
0 stars 0 forks source link

Lift rework #9

Closed AjaniBilby closed 3 months ago

AjaniBilby commented 5 months ago

Rework value lifting from blocks to work properly with structs, and simplify the if/else block compilation so it doesn't make duplicate scopes.

This depends on the #8 being merged before work can be started

AjaniBilby commented 4 months ago

Only remaining feature for this PR is merging initialization states, i.e.

let a: i32;
if rand() {
  a = 3;
} else {
  a = 2;
}
// a is inited in here, because all possible paths lead to initialisation
AjaniBilby commented 3 months ago

Correctly identifies that a has been fully initialized within both branches

struct Finger {
    sig: i32;
}

fn consume(f: Finger): none {
    return;
}

fn main(): none {
    let a: Finger = [];

    if (true) {
        a.sig = 23;
    } else {
        a.sig = 42;
    };

    consume(a);

    return;
}

Correctly identifies that the if branch puts a in an unknown state and throws an error before even reaching consumption

// ...
fn main(): none {
    let a: Finger = [];

    if (true) {
        // a.sig = 23;
    } else {
        a.sig = 42;
    };

    consume(a);

    return;
}

Correctly identifies that if branch is not total, and thus does not override parent state since it lacks an else statement. Thus putting a into an unknown state and throws an error.

// ...

fn main(): none {
    let a: Finger = [];

    if (true) {
        a.sig = 23;
    };

    consume(a);

    return;
}