-
Notifications
You must be signed in to change notification settings - Fork 194
Description
import std/os/path
import std/os/env
effect val package-root: path
fun main()
println("Expecting :" ++ (cwd() / ".kokac").show)
with set-package-root(cwd())
println(package-root)
noinline fun set-package-root(root: path, f: () -> <package-root,ndet|e> a): <ndet|e> a
with val package-root = root / ".kokac"
f()When the compiler inlines the set-package-root function here, it adds a open-none, however, when I add noinline, it doesn't. Although (/) is total from the outside, it adds an effect handler within, which I'm assuming needs open-none but isn't getting it.
I did track down maybe the source of these handler errors. I think it is related to OpenResolve.hs. If the handled effects are both empty, you are assuming you can get rid of open-none. But that is not the case because we haven't checked the effect variable. Sometimes you are in an open context with an effect variable and the target function is total with no effect variable, in which case we need an open-none.
It's a bit more subtle to change though, my naive fix to OpenResolve.hs ends up adds open-none in more places than actually need it I think, and is causing issues with compiling the standard libraries from scratch. With that change though and pre-compiled standard libraries I get the above example to work.
The issue is located here in the fact that the tail of the effects are not compared for whether they are open rows or closed.
Line 179 in b31a53d
| case lsTo of |
I'm also concerned about the logic of isHandlerFree since even if a function is total it could use effects internally at which point it would need to do an open-none prior to introducing the handler, but open-none is only used in a few special cases, and never when inserting a handler in a total context as far as I can tell.
My naive fix is as follows:
case lsTo of
[] | matchType tlFrom tlTo -> trace (" no handled effect, in no handled effect context: use cast")
expr
_ -> if (n <= 4)
then wrapper (resolve (nameOpenNone n)) [] -- fails in perf1c with exceeded stack size if --optmaxdup < 500 (since it prevents a tailcall)
-- expr -- fails in nim as it evidence is not cleared
else wrapperThunk (resolve (nameOpenNone 0)) []It runs into issues with core libraries depending on open-none which don't import hnd because they are themselves imported by hnd. Particularly undiv whose definitions must be in that library because divergence checking expects the name to be there. Adding back isHandlerFree and removing the Var case that deals with externals fixes the issue for the standard library and I can run the simple example, but causes more issues in the larger example that at least compiles in debug mode prior to this.