Closed TimWhiting closed 7 months ago
I found the place where I was doing an incomplete pattern match and fixed it which resolved the issue.
This doesn't exhibit the same error, but is like the code that caused this error, and also behaves strangely:
effect change<v>
ctl change(v:v): maybe<v>
type greet
Hi
Bye
fun show(g: greet): string
match g
Hi -> "Hi"
Bye -> "Bye"
fun test()
match change(1)
Just(v) | v % 2 == 1 -> Hi
Nothing -> Bye
fun main()
with handler
ctl change(v)
resume(Just(v))
resume(Just(v + 1))
test().show.println
Which outputs
Hi
Bye
Hi
It should only output
Hi
** Some sort of match exception
Stepping through the C code using gdb, it never hits the kk_yield_final
code, or the default exception handler code at all, instead it returns from test through unboxing the dummy box that get's returned from the exception call. This does print something in this case due to the fact that the match in the greet show just checks g against the Hi constructor, and if it is not, then assumes that it is the Bye constructor. I believe it is calling the wrong handler, which suggests the evidence vector is not being adjusted propertly.
Adding an explicit match and exception throwing, causes exn to be inferred, which then allows for opening the evidence vector to the right spot, which is not happening for the incomplete pattern match code.
// monadic lift
fun .mlift397-test : (.y.386 : maybe<int>) -> (change<int>) greet
= fn<(change<int>)>(.y.386: maybe<int>){
match (.y.386) {
((std/core/types/Just((v0: int)) : maybe<int> ) as .pat: (maybe<int>))
| std/core/(==.1)((std/core/(%)(v0, 2)), 1) -> scratch/testbroken/Hi;
((std/core/types/Nothing() : maybe<int> ) as .pat0: (maybe<int>))
-> scratch/testbroken/Bye;
(.pat1: (maybe<int>))
-> std/core/error-pattern("../koka_code/scratch/testbroken.kk(14, 3)", "test");
};
};
// monadic lift
fun .mlift416-test : (.y.400 : maybe<int>) -> <change<int>,exn> greet
= fn<<change<int>,exn>>(.y.400: maybe<int>){
match (.y.400) {
((std/core/types/Just((v0: int)) : maybe<int> ) as .pat: (maybe<int>))
| std/core/(==.1)((std/core/(%)(v0, 2)), 1) -> scratch/testbroken/Hi;
((std/core/types/Just((.pat1: int)) : maybe<int> ) as .pat0: (maybe<int>))
-> std/core/hnd/.open-at2((std/core/ssize_t(1)), std/core/throw, "Error", std/core/types/None);
((.skip std/core/types/Nothing() : maybe<int> ) as .pat2: (maybe<int>))
-> scratch/testbroken/Bye;
};
};
Additionally it seems like the type issue is only present in the code that has been monadically lifted, and separating the match expression to match on a variable that stores the value of the effect call has the correct type, but they are all missing open-at to correctly adjust the effect vector..
Related #271
I keep getting segmentation faults when I start using a bunch of handlers, or once my program gets big enough. Usually I try to understand what is happening, and work around it, but this one is a particularly problematic one. The stack only has 98 frames, so it's not hitting a stack limit I think. (I've tried with
ulimit -s unlimited
as well). I've tried with both mimalloc and the standard allocator, and end up with the same issue.Crucially, you'll notice that
_ctx
changes betweenkk_std_core_error_pattern
andkk_std_core_hnd_claus_tail0
which I assumed would never happen.Additionally the exception handler should have a clause with 1 parameter, not 0, which is probably why the ctx address is wrong as well.
So, my conclusion is that there is something wrong with the evidence vector or the lookup into the evidence vector here.