-
-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support structured diagnostics 2 #4433
base: master
Are you sure you want to change the base?
Support structured diagnostics 2 #4433
Conversation
All failures in the jobs of e651d41 seem to be spurious (except for the stylish-haskell formatting failure). |
I think the remaining failures are not caused by this PR. Are these kinds of spurious failures common in HLS? Also, I would really like to get this merged before the next release, because I want to develop a VS Code extension which uses these diagnostic numbers. |
Yes, they unfortunately are |
Some errors in ghc |
You're right. Can anyone give me some tips on how to profile HLS to see where these timeouts are coming from? |
@noughtmare Profiling is likely not necessary, I think the tests are waiting for an LSP message that never arrives, and then just wait for 60s and time out. Use |
Ah, I was thinking there was some inefficiency somewhere that only GHC 9.6 and later could properly optimize. However, I think you're suggesting an alternative explanation: that one of the conditional CPP blocks contains an actual correctness issue. Perhaps I could just visually inspect those first; I don't think that would be that much work. Edit: no obvious loops or anything, so perhaps some tracing would indeed be better. |
I've decided to make the tests ignore all error codes on GHC 9.4. I think some errors already have codes in 9.4, so we could do a bit more, but I don't think it is worth the effort. |
The remaining MacOS failure seems like a compiler bug. The linker is throwing an error. Edit: https://gitlab.haskell.org/ghc/ghc/-/issues/24648 Adding the compiler flag |
@fendor do you think we could try setting the |
Oh, I see we already have that exact workaround in some places. I'll just copy that to the hlint plugin. |
Yay, it has finally passed CI! Should I squash the commits? I'm not sure what to write in the message as I don't really know the details of what exactly Dylan did. |
7773572
to
469d8a7
Compare
We're leaving the TODOs for either later in this PR or in another PR
Thank you for the reviews! I hope I have addressed all feedback appropriately. Is there anything more I can do to speed up the process of merging this? |
Probably not, except for regularly pinging on this thread to make sure we get enough reviews, soon :) We need two approvals, considering the importance of this change, we shouldn't rush merging it without proper review time. However, I hope we can merge it within the next two weeks (hopefully a pessimistic timeframe, but I don't really want to give any time estimate at all :D ). |
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.
Just a question, other places look good to me.
ping |
In the last HLS meeting, we discussed this PR and what we want from it, for transparency, these are the notes https://docs.google.com/document/d/1zqRhA3uoiYgA_Q8eDpIEG0OiFcofGqkVP7N4ODDmikM/edit?tab=t.0 In short, I will review soon and try to make use of the structured diagnostics in 1 or 2 of the plugins, to demonstrate how we can use them in the future and to make sure this PR takes the right directions. |
I'm fine with pushing directly to my branch if that is possible. Do I need to give you special permissions? |
I don't know, I will just try to push at some point and ping you if I have any trouble :) |
This reverts commit 0776c65.
Implement 'rangesOverlap' function which checks whether two 'Range's overlap in any way. Implement two new plugin utility functions which allow to conveniently get all currently displayed diagnostics for a given 'Range'.
48e1288
to
af550e3
Compare
Add compatibility module for GHC's structured error messages. Introduce 'Prism's and 'Lens's to easily access nested structures. Expand documentation for 'StructuredMessage'
af550e3
to
f4d5c24
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.
It took me long enough, but I am happy with the PR now.
I still have to address my own comments, and likely I have to revert any changes to the plugins and split these commits off into a separate PR.
#if MIN_VERSION_ghc(9,5,0) | ||
throwE $ diagFromErrMsgs sourceParser dflags errors | ||
#else | ||
throwE $ diagFromSDocErrMsgs sourceParser dflags errors | ||
#endif |
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.
Note to myself, check whether we can hide this CPP in a function such as diagFromGhcErrorMessage
with appropriate #if
s and typedefs to avoid the CPP statements here.
@@ -157,6 +158,7 @@ data TcModuleResult = TcModuleResult | |||
-- ^ Which modules did we need at runtime while compiling this file? | |||
-- Used for recompilation checking in the presence of TH | |||
-- Stores the hash of their core file | |||
, tmrWarnings :: WarningMessages |
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.
Note to self, add docs for this.
#if MIN_VERSION_ghc(9,5,0) | ||
type ErrMsg = MsgEnvelope GhcMessage | ||
type WarnMsg = MsgEnvelope GhcMessage | ||
#else | ||
type ErrMsg = MsgEnvelope DecoratedSDoc | ||
type WarnMsg = MsgEnvelope DecoratedSDoc | ||
#endif |
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.
Note to self, this feels like the wrong direction, we should have type defs for backwards compatibility, i.e.
#if !MIN_VERSION_ghc(9,5,0)
type GhcMessage = DecoratedSDoc
```endif
which allows us to write code conforming to the latest GHC API.
I think it is more confusing and less maintainable in the long run, if we add type defs to maintain the previous API.
{- | ||
NOTE on withWarnings and its dangers |
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.
Note to self, improper GHC Note syntax
@noughtmare Is there anythign else you need or want from this PR? |
I personally just wanted access to the diagnostic codes. So I'm more than satisfied! |
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.
LGTM, Just two questions
@@ -80,23 +86,25 @@ addMethodPlaceholders _ state _ param@AddMinimalMethodsParams{..} = do | |||
-- This implementation is ad-hoc in a sense that the diagnostic detection mechanism is | |||
-- sensitive to the format of diagnostic messages from GHC. | |||
codeAction :: Recorder (WithPriority Log) -> PluginMethodHandler IdeState Method_TextDocumentCodeAction | |||
codeAction recorder state plId (CodeActionParams _ _ docId _ context) = do | |||
codeAction recorder state plId (CodeActionParams _ _ docId caRange _) = do |
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.
If I understand correctly, now we are getting the diags from diags store in ShakeExtra
instead of CodeActionContext
.
Two questions:
- Does it mean diags in
ShakeExtra
contains more information than the one in theCodeActionContext
now ? - Do these two places' diags always in sync (e.g., is there additional filters for diags in the
CodeActionContext
, but those filters not in diags store inShakeExtra
)?
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.
Indeed, that's exactly what we are doing :)
Re 1., I think ShakeExtra
also contains Diagnostics which are not displayed to the user, see the docs for ShowDiagnostic
:
-- | Defines whether a particular diagnostic should be reported
-- back to the user.
--
-- One important use case is "missing signature" code lenses,
-- for which we need to enable the corresponding warning during
-- type checking. However, we do not want to show the warning
-- unless the programmer asks for it (#261).
data ShowDiagnostic
= ShowDiag -- ^ Report back to the user
| HideDiag -- ^ Hide from user
deriving (Eq, Ord, Show)
This means, we may have more diagnostics available.
Re 2., I confidently, but without evidence, claim that the diagnostics sent by the client and the diagnostics we store in StoreExtras
may be out of sync, but it has no noticeable negative effect for the user experience.
However, why are we doing this? Primarily due to the docs of CodeActionContext
:
/**
* An array of diagnostics known on the client side overlapping the range
* provided to the `textDocument/codeAction` request. They are provided so
* that the server knows which errors are currently presented to the user
* for the given range. There is no guarantee that these accurately reflect
* the error state of the resource. The primary parameter
* to compute code actions is the provided range.
*/
diagnostics: Diagnostic[];
Which tells us that we cannot rely on the diagnostics provided by the CodeActionContext
.
I will add this crucial bit of information to the documentation of activeDiagnostics...
function.
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.
Thanks, adding it to the docs helps for the future reviewers.:)
<+> pretty (show (getOccString cls) <> ":") -- 'show' is used here to add quotes around the class name | ||
<+> pretty methods | ||
<+> pretty (showSDocUnsafe $ ppr methods) |
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.
Are we safe with showSDocUnsafe
?
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 think that's fine for logging, unsafe
doesn't mean it might crash, but rather we use default DynFlags
which may be missing some information, such as import paths, packages in scope, etc... So, the displayed names may be inaccurate. However, I can double-check what we do in other locations
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.
Maybe we should get the more exact DynFlags
from rule like GetModSummary
, but, I agree, for logging, it should be fine as long as it won't crash.
This is my attempt at finishing the work of @dylan-thinnes on !4311.
Addresses #2014
Should hopefully enable #3246
These are two things Dylan listed as work for future PRs:
Some future work discovered in reviews of this PR:
requireDiagnostic
could take a more structured error code query type as argument. See Support structured diagnostics 2 #4433 (comment)requireDiagnostics
and related functions use explicit error codes if possible