flix / flix

The Flix Programming Language
https://flix.dev/
Other
2.08k stars 150 forks source link

Optimizer should not remove prints in `bug!` #3719

Closed magnus-madsen closed 1 year ago

magnus-madsen commented 2 years ago

The optimizer is happy to rewrite this:

pub def bug!(m: String): a =
    let f = () -> {
        import static get java.lang.System.err: ##java.io.PrintStream & Pure as getErr;
        import java.io.PrintStream.println(String): Unit & Impure;
        import java.lang.String.repeat(Int32): ##java.lang.String & Pure;
        let prt = println(getErr());
        prt(repeat("*", 80));
        prt("**") ;
        prt("**  BUG: ${m}") ;
        prt("**") ;
        prt(repeat("*", 80));
        prt("")
    };
    let _ = f() as & Pure;
    ?panic

Do want a DontOptimize annotation or something like that temporarily?

JonathanStarup commented 2 years ago

I think longterm that bug! should be a macro/buitlin instead of a function. A function will forever be awkward as long as you can't see the flix callstack on exceptions. Maybe we could also improve that aspect by putting flix files as the class source?

magnus-madsen commented 2 years ago

I thought addSourceLocation in GenBytecode did this?

JonathanStarup commented 2 years ago

This program

def main(): Int32 = f(2)
def f(i: Int32): Int32 = g(i+2)
def g(_i: Int32): Int32 = bug!("error")

Causes error:

Exception in thread "main" dev.flix.runtime.HoleError: Hole '?panic' at Prelude.flix:158:5
    at Def%bug%exclamation%836744.invoke(Unknown Source)
    at Cont%Int32.unwind(Cont%Int32)
    at Def%main%.invoke(Unknown Source)
    at Cont%Obj.unwind(Cont%Obj)
    at Ns.m_main%(Unknown Source)
    at Main.main(Main)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at ca.uwaterloo.flix.language.phase.jvm.Bootstrap$.mainFunction$1(Bootstrap.scala:79)
    at ca.uwaterloo.flix.language.phase.jvm.Bootstrap$.$anonfun$bootstrap$9(Bootstrap.scala:88)
    at ca.uwaterloo.flix.language.phase.jvm.Bootstrap$.$anonfun$bootstrap$9$adapted(Bootstrap.scala:88)
    at ca.uwaterloo.flix.Main$.main(Main.scala:226)
    at ca.uwaterloo.flix.Main.main(Main.scala)

The location is the location of the ?hole which is in prelude. You can't really see here that the error was in g. Maybe the optimizer removed it?

That's why its easier to debug if you use ?error directly instead of using bug!(...)