fpco / ide-backend

ide-backend drives the GHC API to build, query, and run your code
120 stars 17 forks source link

Initial "-fdefer-type-errors" update causes the setting to be sticky #260

Open mgsloan opened 10 years ago

mgsloan commented 10 years ago
{-# LANGUAGE OverloadedStrings #-}

import IdeSession
import Data.Monoid

main = do
    sess <- initSession defaultSessionInitParams defaultSessionConfig
    let update x = updateSession sess x print
    update $ updateGhcOpts ["-fdefer-type-errors"]
    update $ updateSourceFile "src/Main.hs" "main = '1' + 1"
    update $ updateRelativeIncludes ["", "src/"]
    putStrLn "With -fdefer-type-errors:"
    print =<< getSourceErrors sess
    update $ updateGhcOpts []
    putStrLn "No -fdefer-type-errors:"
    print =<< getSourceErrors sess

The output is:

[1 of 1] Compiling Main
[1 of 1] Compiling Main
With -fdefer-type-errors:
[SourceError {errorKind = KindWarning, errorSpan = src/Main.hs@1:1-1:1, errorMsg = "Couldn't match expected type \8216IO t0\8217 with actual type \8216Char\8217\nIn the expression: main\nWhen checking the type of the IO action \8216main\8217"},SourceError {errorKind = KindWarning, errorSpan = src/Main.hs@1:12-1:13, errorMsg = "No instance for (Num Char) arising from a use of \8216+\8217\nIn the expression: '1' + 1\nIn an equation for \8216main\8217: main = '1' + 1"}]
[1 of 1] Compiling Main
No -fdefer-type-errors:
[SourceError {errorKind = KindWarning, errorSpan = src/Main.hs@1:1-1:1, errorMsg = "Couldn't match expected type \8216IO t0\8217 with actual type \8216Char\8217\nIn the expression: main\nWhen checking the type of the IO action \8216main\8217"},SourceError {errorKind = KindWarning, errorSpan = src/Main.hs@1:12-1:13, errorMsg = "No instance for (Num Char) arising from a use of \8216+\8217\nIn the expression: '1' + 1\nIn an equation for \8216main\8217: main = '1' + 1"}]

I would expect the second getSourceErrors results to have an errorKind of KindError.

One interesting thing to note is that updateRelativeIncludes is indeed necessary for this repro, and moving it before updateGhcOpts causes the issue to go away.

mgsloan commented 10 years ago

Side note: my approach to debugging this was to add logging to the IR which generates code: https://gist.github.com/mgsloan/b974946bcb4dc90493c5

Unfortunately, this didn't work out as well as I'd hoped, because FileInfo isn't serializable. Doing a hack like this solved that:

    let (IdeSessionUpdate {ideUpdateFileCmds = [FileWrite info _]}) = updateSourceFile "src/Main.hs" ""

And then replacing all the instances of <<FileInfo src/Main.hs>> with info. Oddly enough, this didn't work - all of the calls to getSourceErrors return empty lists. What's going on?? https://gist.github.com/mgsloan/f47b0d61dd1257b6235b

So, instead, I gave up on the automated approach and translated these logs to using the normal public API, and then reduced the repro from there.