-
Notifications
You must be signed in to change notification settings - Fork 96
Conversation
I spent a while experimenting to try to understand where the It doesn't happen with ghc or ghci itself if you use I also tried setting an unrelated flag ( |
2ba97f2
to
e4bec00
Compare
It looks like the qualified names are something general to do with how In the following code, there's a warning about the unnecessary constraint
|
I tracked down why it's happening (I think) - the warnings collection code uses |
I think the three things we can/want to defer are
I think at least typed-holes is implied by type-errors. A few comments on the code:
|
I've removed it, and the tests still pass, as demonstrated on the branch rebased on #59 [Edit: this is now available on this branch too.] |
The gyrations are only ugly because Haskell records suck, but we should just fix that problem at source 😝. I prefer having the dynflag stuff localised where possible since it's just unclear what the impact is, and this way we can actually get at the original to see if the user had already set deferred type errors and thus avoid promoting them, whereas setting them in runGhcEnv makes that harder. However, I'm not against the other if people think it has benefits. |
e4bec00
to
06cbc63
Compare
That hypothesis seems to be disproved by the commit entitled BTW, this branch is now rebased on top of #59, as the latter seems to be cruicial to its correctness. |
Agreed. |
e540ea6
to
0ed59c8
Compare
This seems to be working now, including the extra deferals proposed by @hsenag, so I think it's ready for review. It does crucially depend on #59, therefore it is rebased on top of it. I have gradually modified the tests and implementation in separate commits, in order to document which approaches work / don't work and which flags are needed / not need. |
Unfortunately Github presents the commits in timestamp order, rather than DAG order, thoroughly confusing the story I'm trying to tell! |
Excellent!
Wouldn't you have needed to use merge commits to get an actual DAG? I just see a linear history in I'd be inclined to squish it down to a single commit now (maybe that'll happen anyway when it's merged, I'm not too familiar with what github does). Having lots of logical commits is great during development to keep track of uncertain options, but is not necessarily so helpful when the feature is done. If there's something future readers of the code should understand, a comment is likely to be more discoverable than git history. |
It's Directed, it's Acyclic, and it's a Graph, so it's a DAG! (A single vertex is a DAG ... even an empty graph is a DAG ... not very interesting ones, admittedly :-)
I'll leave that to the owners of this repo to decide. I've crafted the commits like this, so that the necessity, or otherwise, of various bits is easily verifiable. |
0ed59c8
to
7d22abd
Compare
At DA we always used squash merges so that you have a guarantee your history all passed all CI tests, which is useful for bisecting. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks awesome! Looking forward to using this.
It certainly was nice having it available in my editor while hacking on it! |
Haven't done it recently, but I recall having a workflow where |
Thanks a lot for the contribution and sorry for my lack of response. I hope to get around to taking a closer look at this next week. |
7d22abd
to
e805d8b
Compare
One thing I noticed after using this for a bit is that the text of the "error" still says warning:
Regardless of minor glitches like that, now I've been using it for a little while, I can also confirm that it is indeed awesome for improving the development experience :-) |
Yes, I had also noticed this glitch while using it, but it seemed very much a second-order problem, and it slipped my mind. Maybe I'll manage to have a look at it and fix it before @cocreature gets around to reviewing it. |
e805d8b
to
4655e51
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thank you very much!
It would be great if you could address two things before merging:
- I would like this behavior to be configurable in
IdeOptions
so add a field there that allows you to turn this on/off. - A test that depends on the new behavior would be great.
, "foo a = _ a" | ||
] | ||
_ <- openDoc' "Testing.hs" "haskell" content | ||
expectDiagnostics |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m not sure what you are trying to test here. Afaik, this test passes without any of your changes as well? It would be good to get a test that actually relies on this behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you want to test that the undemoting works? Looks reasonable in that case but a comment would be good and it would still be nice to have a test that checks that actually relies on deferring the errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the point is that the definition of this test (and a couple of others like it) evolves through this sequence of commits, and the implementation has to follow the tests through the Error -> Warning -> Error route. When all is said and done, we end up where we started (error) but these test document, in the sequence of commits, that each individual step did what it was supposed to; or, quite importantly in the case of the first attempt to defer type errors, that the obvious approach does NOT work, justifying the more complex implementation that ended up being used.
Anyway, I have added tests which detect if any of the deferrals are removed. These, of course, will have to be duplicated once I've added the deferral on/off switch.
Presumably you would want a single option that switches all three deferrals together ... or three different options, one for each deferral? For completeness, the three things being deferred are:
If there are to be 3 separate ones, the names are fairly obvious:
which closely follow similar names in It's less obvious what the name would be if there is to be a single option controlling all three. |
This test fails, thereby falsifying the hypothesis that `Opt_DeferTypeErrors` implies `Opt_DeferTypedHoles`.
... and pass the failing test.
... failing the test until the implementation catches up in the next commit.
... and pass the test once again.
... test fails until next commit.
... passing the test which was changed in the last commit.
... failing the test, and forcing the implementation to catch up.
... passing the test once again.
4655e51
to
28fe605
Compare
The easiest option to get access to the options is probably to call As for the tests, I don’t mind if we don’t test the non-defer codepath right now. |
28fe605
to
1e08d50
Compare
If you don't need tests for it, then I have pushed something that seems to do the job. I have tested it informally by setting the default to |
Any preference as to the position in which the new parameter of |
src/Development/IDE/Core/Compile.hs
Outdated
@@ -82,19 +82,22 @@ computePackageDeps env pkg = do | |||
|
|||
-- | Typecheck a single module using the supplied dependencies and packages. | |||
typecheckModule | |||
:: HscEnv | |||
:: Bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting it as the first parameter is very reasonable but it would be great if we could get a newtype for this to get something a bit more informative than Bool
.
7f85128
to
14f2b3e
Compare
src/Development/IDE/Types/Options.hs
Outdated
@@ -44,9 +45,16 @@ data IdeOptions = IdeOptions | |||
-- ^ the ```language to use | |||
, optNewColonConvention :: Bool | |||
-- ^ whether to use new colon convention | |||
, optDefer :: Bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
, optDefer :: Bool | |
, optDefer :: IdeDefer |
src/Development/IDE/Types/Options.hs
Outdated
@@ -63,6 +71,7 @@ defaultIdeOptions session = IdeOptions | |||
,optReportProgress = IdeReportProgress False | |||
,optLanguageSyntax = "haskell" | |||
,optNewColonConvention = False | |||
,optDefer = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
,optDefer = True | |
,optDefer = IdeDefer True |
src/Development/IDE/Core/Rules.hs
Outdated
@@ -312,7 +312,8 @@ typeCheckRule = | |||
tms <- uses_ TypeCheck (transitiveModuleDeps deps) | |||
setPriority priorityTypeCheck | |||
packageState <- hscEnv <$> use_ GhcSession file | |||
liftIO $ typecheckModule packageState tms pm | |||
IdeOptions{ optDefer = defer} <- getIdeOptions | |||
liftIO $ typecheckModule (IdeDefer defer) packageState tms pm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
liftIO $ typecheckModule (IdeDefer defer) packageState tms pm | |
liftIO $ typecheckModule defer packageState tms pm |
14f2b3e
to
6a33708
Compare
Hmm, that was confusing: I think that your suggestions, which were almost identical to the changes I had just pushed, appeared here just after the push, so I was left wondering why on earth my changes were appearing as your suggestions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thank you so much!
You're welcome. It's a pleasure. Thank you for |
* TEST: Degrade type error to warning It will be upgraded again later, but for the time being we want to see whether the proposed mechanism for deferring type errors works at all. As it turns out the first, most obvious approach, does not work: this is documented in the next commit. A second approach was found that does work, and appears in the commit after the next. This test is failing until the second approach is implemented. * Defer type errors (first approach: FAILED) The idea is to set the `-fdefer-type-errors` and `-fwarn-deferred-type-errors` flags, by setting options programatically inside the `Ghc` monad. Deferral of type errors was not observed with this approach. The (less obvious) approach used in the next commit seems to be more successful. * Defer type errors (second approach: SUCCESS) This approach modifies the `ParsedModule` which is passed to `GHC.typecheckedModule` by hie-core's `typecheckModule`. Type warning deferral is now observed at run time, and the tests pass. * TEST: Reinstate severity of type errors So far, type errors have been deferred and reported as warnings. The next step is to ensure that the deferred type errors are reported as errors rather than warnings, once again. This test fails until the implementation arrives in the next commit. * Upgrade severity of deferred Type Errors after typecheck ... and make the test pass again. * Hide helper functions in local scopes * Stop setting Opt_WarnDeferredTypeErrors ... and the tests still pass, thereby confirming @hsenag's hypothesis that this flag is not needed. * TEST: Check that typed holes are reported as errors * TEST: Downgrade severity of typed holes Error -> Warning This test fails, thereby falsifying the hypothesis that `Opt_DeferTypeErrors` implies `Opt_DeferTypedHoles`. * Defer typed holes ... and pass the failing test. * TEST: Reinstate severity of typed holes ... failing the test until the implementation catches up in the next commit. * Upgrade severity of deferred Typed Holes after typecheck ... and pass the test once again. * TEST: Degrade variable out of scope from Error to Warning ... test fails until next commit. * Defer out of scope variables ... passing the test which was changed in the last commit. * TEST: Reinstate severity of out of scope variables ... failing the test, and forcing the implementation to catch up. * Upgrade severity of deferred out of scope vars after typecheck ... passing the test once again. * Add explicit tests for deferrals * Add IdeOption for deferral switching * Improve documentation of optDefer * Add IdeDefer newtype
* TEST: Degrade type error to warning It will be upgraded again later, but for the time being we want to see whether the proposed mechanism for deferring type errors works at all. As it turns out the first, most obvious approach, does not work: this is documented in the next commit. A second approach was found that does work, and appears in the commit after the next. This test is failing until the second approach is implemented. * Defer type errors (first approach: FAILED) The idea is to set the `-fdefer-type-errors` and `-fwarn-deferred-type-errors` flags, by setting options programatically inside the `Ghc` monad. Deferral of type errors was not observed with this approach. The (less obvious) approach used in the next commit seems to be more successful. * Defer type errors (second approach: SUCCESS) This approach modifies the `ParsedModule` which is passed to `GHC.typecheckedModule` by hie-core's `typecheckModule`. Type warning deferral is now observed at run time, and the tests pass. * TEST: Reinstate severity of type errors So far, type errors have been deferred and reported as warnings. The next step is to ensure that the deferred type errors are reported as errors rather than warnings, once again. This test fails until the implementation arrives in the next commit. * Upgrade severity of deferred Type Errors after typecheck ... and make the test pass again. * Hide helper functions in local scopes * Stop setting Opt_WarnDeferredTypeErrors ... and the tests still pass, thereby confirming @hsenag's hypothesis that this flag is not needed. * TEST: Check that typed holes are reported as errors * TEST: Downgrade severity of typed holes Error -> Warning This test fails, thereby falsifying the hypothesis that `Opt_DeferTypeErrors` implies `Opt_DeferTypedHoles`. * Defer typed holes ... and pass the failing test. * TEST: Reinstate severity of typed holes ... failing the test until the implementation catches up in the next commit. * Upgrade severity of deferred Typed Holes after typecheck ... and pass the test once again. * TEST: Degrade variable out of scope from Error to Warning ... test fails until next commit. * Defer out of scope variables ... passing the test which was changed in the last commit. * TEST: Reinstate severity of out of scope variables ... failing the test, and forcing the implementation to catch up. * Upgrade severity of deferred out of scope vars after typecheck ... passing the test once again. * Add explicit tests for deferrals * Add IdeOption for deferral switching * Improve documentation of optDefer * Add IdeDefer newtype
* TEST: Degrade type error to warning It will be upgraded again later, but for the time being we want to see whether the proposed mechanism for deferring type errors works at all. As it turns out the first, most obvious approach, does not work: this is documented in the next commit. A second approach was found that does work, and appears in the commit after the next. This test is failing until the second approach is implemented. * Defer type errors (first approach: FAILED) The idea is to set the `-fdefer-type-errors` and `-fwarn-deferred-type-errors` flags, by setting options programatically inside the `Ghc` monad. Deferral of type errors was not observed with this approach. The (less obvious) approach used in the next commit seems to be more successful. * Defer type errors (second approach: SUCCESS) This approach modifies the `ParsedModule` which is passed to `GHC.typecheckedModule` by hie-core's `typecheckModule`. Type warning deferral is now observed at run time, and the tests pass. * TEST: Reinstate severity of type errors So far, type errors have been deferred and reported as warnings. The next step is to ensure that the deferred type errors are reported as errors rather than warnings, once again. This test fails until the implementation arrives in the next commit. * Upgrade severity of deferred Type Errors after typecheck ... and make the test pass again. * Hide helper functions in local scopes * Stop setting Opt_WarnDeferredTypeErrors ... and the tests still pass, thereby confirming @hsenag's hypothesis that this flag is not needed. * TEST: Check that typed holes are reported as errors * TEST: Downgrade severity of typed holes Error -> Warning This test fails, thereby falsifying the hypothesis that `Opt_DeferTypeErrors` implies `Opt_DeferTypedHoles`. * Defer typed holes ... and pass the failing test. * TEST: Reinstate severity of typed holes ... failing the test until the implementation catches up in the next commit. * Upgrade severity of deferred Typed Holes after typecheck ... and pass the test once again. * TEST: Degrade variable out of scope from Error to Warning ... test fails until next commit. * Defer out of scope variables ... passing the test which was changed in the last commit. * TEST: Reinstate severity of out of scope variables ... failing the test, and forcing the implementation to catch up. * Upgrade severity of deferred out of scope vars after typecheck ... passing the test once again. * Add explicit tests for deferrals * Add IdeOption for deferral switching * Improve documentation of optDefer * Add IdeDefer newtype
* TEST: Degrade type error to warning It will be upgraded again later, but for the time being we want to see whether the proposed mechanism for deferring type errors works at all. As it turns out the first, most obvious approach, does not work: this is documented in the next commit. A second approach was found that does work, and appears in the commit after the next. This test is failing until the second approach is implemented. * Defer type errors (first approach: FAILED) The idea is to set the `-fdefer-type-errors` and `-fwarn-deferred-type-errors` flags, by setting options programatically inside the `Ghc` monad. Deferral of type errors was not observed with this approach. The (less obvious) approach used in the next commit seems to be more successful. * Defer type errors (second approach: SUCCESS) This approach modifies the `ParsedModule` which is passed to `GHC.typecheckedModule` by hie-core's `typecheckModule`. Type warning deferral is now observed at run time, and the tests pass. * TEST: Reinstate severity of type errors So far, type errors have been deferred and reported as warnings. The next step is to ensure that the deferred type errors are reported as errors rather than warnings, once again. This test fails until the implementation arrives in the next commit. * Upgrade severity of deferred Type Errors after typecheck ... and make the test pass again. * Hide helper functions in local scopes * Stop setting Opt_WarnDeferredTypeErrors ... and the tests still pass, thereby confirming @hsenag's hypothesis that this flag is not needed. * TEST: Check that typed holes are reported as errors * TEST: Downgrade severity of typed holes Error -> Warning This test fails, thereby falsifying the hypothesis that `Opt_DeferTypeErrors` implies `Opt_DeferTypedHoles`. * Defer typed holes ... and pass the failing test. * TEST: Reinstate severity of typed holes ... failing the test until the implementation catches up in the next commit. * Upgrade severity of deferred Typed Holes after typecheck ... and pass the test once again. * TEST: Degrade variable out of scope from Error to Warning ... test fails until next commit. * Defer out of scope variables ... passing the test which was changed in the last commit. * TEST: Reinstate severity of out of scope variables ... failing the test, and forcing the implementation to catch up. * Upgrade severity of deferred out of scope vars after typecheck ... passing the test once again. * Add explicit tests for deferrals * Add IdeOption for deferral switching * Improve documentation of optDefer * Add IdeDefer newtype
* TEST: Degrade type error to warning It will be upgraded again later, but for the time being we want to see whether the proposed mechanism for deferring type errors works at all. As it turns out the first, most obvious approach, does not work: this is documented in the next commit. A second approach was found that does work, and appears in the commit after the next. This test is failing until the second approach is implemented. * Defer type errors (first approach: FAILED) The idea is to set the `-fdefer-type-errors` and `-fwarn-deferred-type-errors` flags, by setting options programatically inside the `Ghc` monad. Deferral of type errors was not observed with this approach. The (less obvious) approach used in the next commit seems to be more successful. * Defer type errors (second approach: SUCCESS) This approach modifies the `ParsedModule` which is passed to `GHC.typecheckedModule` by hie-core's `typecheckModule`. Type warning deferral is now observed at run time, and the tests pass. * TEST: Reinstate severity of type errors So far, type errors have been deferred and reported as warnings. The next step is to ensure that the deferred type errors are reported as errors rather than warnings, once again. This test fails until the implementation arrives in the next commit. * Upgrade severity of deferred Type Errors after typecheck ... and make the test pass again. * Hide helper functions in local scopes * Stop setting Opt_WarnDeferredTypeErrors ... and the tests still pass, thereby confirming @hsenag's hypothesis that this flag is not needed. * TEST: Check that typed holes are reported as errors * TEST: Downgrade severity of typed holes Error -> Warning This test fails, thereby falsifying the hypothesis that `Opt_DeferTypeErrors` implies `Opt_DeferTypedHoles`. * Defer typed holes ... and pass the failing test. * TEST: Reinstate severity of typed holes ... failing the test until the implementation catches up in the next commit. * Upgrade severity of deferred Typed Holes after typecheck ... and pass the test once again. * TEST: Degrade variable out of scope from Error to Warning ... test fails until next commit. * Defer out of scope variables ... passing the test which was changed in the last commit. * TEST: Reinstate severity of out of scope variables ... failing the test, and forcing the implementation to catch up. * Upgrade severity of deferred out of scope vars after typecheck ... passing the test once again. * Add explicit tests for deferrals * Add IdeOption for deferral switching * Improve documentation of optDefer * Add IdeDefer newtype
At present, all sorts of useful IDE featrues, such as diagnostics reporting and go-to-definition, stop working at the first sign of a type error. This PR attempts to fix this. The plan is:
TODO:
The current implementation breaks old behaviour by changing the text of type error messages to contain fully qualified type names, e.g:GHC.Types.Int
appears instead ofInt
.