Open ggreif opened 1 week ago
It turns out that this is an old bug. The check_sub
check uses the relational infrastructure from module Type
. Type.sub
descends into the tuple components and then applies the relation to the codomain and domain of the function type sequences. When doing this, it uses List.for_all2
which throws Invalid_argument
when the argument sequences are of different lengths, resulting in false
. This is the case here, as length ()
= 0 but length (Non)
= 1.
Currently I have no idea how to make a special case for Type.Non
(bottom) that fits into the relational subtype check.
Also, I could not come up with an example that triggers this bug from Motoko directly, as the interpreter accepts this:
> let cont : (None -> (), Int -> (), () -> ()) = (func () {}, func (i : Int) {}, func () {});
gets accepted 😲
UPDATE: Here is an interpreter example:
> let cont : (() -> (), Int -> (), () -> ()) = (func () {}, func (i : Int) {}, func () {});
> let contA : (None -> (), Int -> (), () -> ()) = cont;
stdin:13.49-13.53: type error [M0096], expression of type
(() -> (), Int -> (), () -> ())
cannot produce expected type
(None -> (), Int -> (), () -> ())
Type checking continuations after
async
-lowering fails for unusual code:The error message is bogus!
() -> ()
is subtype ofNone -> ()
becauseNone
is subtype of()
.Here is the repro: