pschachte / wybe

A programming language supporting most of both declarative and imperative programming
MIT License
47 stars 6 forks source link

Some essential variables are not passed into the continuation proc #435

Closed wnats closed 8 months ago

wnats commented 10 months ago

Compiling b.wybe

constructors a | b(c:d)

type d {
    pub e | f
}

def foo:_ = bar where {
    ?bar = a
    (
        (pass | pass)
        !bar^c = e
    |
        pass
    )
}

pass

yields

Error detected during generating low level code in b, b.d
Uninitialised variable 'tmp#2'

Some relevant code snippets after unbranching:

proc foo > (0 calls)
0: foo(?#result:b @b:7:1):
    b.<0>a(?tmp#0:b @b:8:12)
    foreign llvm move(tmp#0:b, ?bar:b @b:8:6)
    foreign llvm move(bar:b, ?tmp#2:b)
    b.<0>foo#cont#1(bar:b, ?#result:b @b:7:1)

proc foo#cont#1 > (0 calls)
0: foo#cont#1(bar:b, ?#result:b @b:7:1):
    b.d.<0>e(?tmp#1:b.d @b:11:18)
    b.<1>c(!bar:b @b:11:10, tmp#1:b.d, ?tmp#3:wybe.bool)
    if {testbool tmp#3:wybe.bool::

        foreign llvm move(bar:b @b:7:13, ?#result:b @b:7:1)
    else::
        foreign llvm move(tmp#2:b, ?bar:b)
        foreign llvm move(bar:b @b:7:13, ?#result:b @b:7:1)

    }
   condition -> {bar::b, tmp#0::b, tmp#1::b.d, tmp#3::wybe.bool}
   then&else -> {#result::b, bar::b, tmp#0::b, tmp#1::b.d, tmp#3::wybe.bool}
   resources -> {}

We can see that tmp#2 is not passed into foo#cont#1

wnats commented 10 months ago

I think the reason tmp#2 is not passed into foo#cont#1 is due to it not being a member of the disjunction's VarDict.

tmp#2 is created by saveRestore in Types.hs. Would a solution be to add vars generated by saveRestore into the vardict?

jimbxb commented 10 months ago

Yet another reason we should delay (or recompute) these maps when we need them

wnats commented 10 months ago

(tagging #397)