Show diagnostic context notes in language server diagnostics
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 72/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- rust
- Ambito
- backend-api-design, devtools, testing-qa
Direzione di ricerca
Start with iris-diagnostics/src/render.rs and to_lsp_diagnostic in iris-analysis/src/diagnostics.rs; compare the existing trivia rendering in format_rich_with_path with the LSP conversion. Add an LSP fixture covering the listed checking diagnostics, then run just t lsp and just t compiler and review the snapshots. Done when LSP diagnostic messages include trivia in the recommended plain text layout and compiler snapshots remain unchanged.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Problem
Editors don't see the context notes that the CLI prints under a diagnostic. The compiler attaches these notes as Diagnostic::trivia, and the CLI prints them in a "while" block, but the language server sends only Diagnostic::message. For some diagnostics the dropped notes hold the information the user needs to fix the error.
For example, the 1772567700_givens_scoped compiler fixture has this code:
class Given a where
consume :: a -> a
testGiven :: forall a. Given a => a -> a
testGiven a = consume a
where
c :: Int
c = consume 42
The CLI reports the error with the given constraint that is in scope:
Error! · [NoInstanceFound] · Main.purs:13:7
•
│
• No instance found for: Given Int
│
│ c = consume 42
│ ╰─────────
• while
│
│ Given a is in scope
•
An editor receives only the first line. A temporary -- diagnostics LSP fixture with the same code produced this message:
9:6..9:16 analyzer/checking [NoInstanceFound] No instance found for: Given Int
How diagnostics reach editors
iris_diagnostics::collect_diagnosticsbuildsDiagnosticvalues. Each one has amessage, a list ofrelatednotes that point at other spans, and a list oftrivianotes that have no span.iris_analysis::diagnostics::implementationconverts each one withto_lsp_diagnostic.iris-lsp-workspacesends the result withtextDocument/publishDiagnostics. Iris only pushes diagnostics and does not implement pull diagnostics (textDocument/diagnostic).
to_lsp_diagnostic copies message into the LSP message field and turns related into relatedInformation, but it never reads trivia. The CLI and the compiler fixture snapshots use format_rich_with_path, which prints the trivia, so the compiler fixtures show context that editors never get.
Affected diagnostics
All current trivia is attached at the end of ToDiagnostics for CheckingError in iris-diagnostics/src/convert.rs.
| Diagnostic | Notes the editor doesn't see |
|---|---|
NoInstanceFound |
<given> is in scope, once for each given constraint |
OverlappingInstances |
<instance> is matching, once for each matching instance |
TermHole, TypeHole |
<name> :: <type> is in scope, for up to five bindings in scope |
CannotGeneraliseRecursiveFunction |
The inferred type was: <type> and Try adding a type signature. |
MissingInstanceMembers |
<member> is not implemented, once for each missing member |
The gap is worst for MissingInstanceMembers, where the editor message is only "Instance is missing class members" and doesn't say which members are missing. Typed holes lose the list of bindings that fit the hole, and CannotGeneraliseRecursiveFunction loses the inferred type that the user would add as a signature.
Planned work that isn't on main yet adds matching 'A' with 'B' trivia to CannotUnify for the outer types of a failed unification, so the gap will grow.
The diagnostics answer in iris-watch-query also copies only message, so it has the same gap outside the language server.
Options
1. Append the notes to the plain text message
The LSP message field is a string, and it can contain newlines. Iris already sends multi-line messages for code generation errors, as the 1788269400_backend_diagnostics LSP fixture shows. The NoInstanceFound example would become:
No instance found for: Given Int
while
Given a is in scope
Editors show the full message in hovers, popups, and problem lists. Some inline displays show only the first line, which would still be the main message. The approach works in every client and needs no capability checks. The notes stay plain text, so editors can't style or link them.
2. Send each note as relatedInformation
Each relatedInformation entry needs a location, and trivia has none, so every entry would repeat the primary range. Editors show related information as references to code, e.g. VS Code lists each entry with a file and position under the diagnostic, so the notes would look like links to other code when they only point back at the error. The client also has to advertise textDocument.publishDiagnostics.relatedInformation. Iris doesn't check that capability today and sends related information to every client. Option 2 is not recommended.
3. Send the message as Markdown
LSP 3.18 allows MarkupContent in the diagnostic message, which would let editors show types as code. The capability for it, textDocument.diagnostic.markupMessageSupport, is defined on the pull diagnostics client capabilities. Iris only pushes diagnostics, so it's unclear whether a client that sets the flag accepts Markdown in pushed diagnostics, and client support is new. Iris would still need option 1 as the plain text fallback, so option 3 could follow option 1 later.
4. Give notes a location where one exists
Some notes refer to code that has a location. Matching instances in OverlappingInstances have declarations, and hole bindings have binding sites. Sending those notes as related would let editors jump to them. The checking errors would need to carry those source locations, and notes without a location, such as the inferred type or the planned CannotUnify notes, would still need option 1. Option 4 is a possible follow-up and doesn't replace option 1.
Recommendation
Use option 1. Add one plain text formatter in iris-diagnostics that writes the message followed by the trivia, and call it from to_lsp_diagnostic. The formatter should use the same "while" layout as format_rich_with_path, so the CLI and the editor present the notes the same way and any change to the wording applies to both. iris-watch-query could use the same formatter, either in the same change or in a separate one.
Keep relatedInformation for notes that have a span, which is how it is used today. Consider options 3 and 4 as separate follow-ups.
Tests
- Add an LSP fixture with
-- diagnosticsthat coversNoInstanceFoundwith a given constraint, a typed hole,CannotGeneraliseRecursiveFunction, andMissingInstanceMembers. The two existing-- diagnosticsfixtures only cover code generation errors, so no LSP fixture covers checking errors today. - The LSP fixture harness prints the message, which is enough for option 1. It doesn't print
relatedInformation, so existing related notes such as "First imported here" are also not covered by LSP fixtures. Printing it would show everything the editor receives. - Run
just t lspandjust t compilerand review the snapshot changes. The compiler snapshots should not change.
- Lingua principale
- Rust
- Stelle
- 118
- Fork
- 12
- Merge medio
- 7h 23m
- PR unite (30g)
- 100
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di purefunctor/purescript-iris
-
Instance matching treats unknown types as apart from every instanceForse già presa @purefunctor l’ha presa 2 giorni fa. Apertachecking diagnostics
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
purefunctor/purescript-iris#654 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
ideas
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
purefunctor/purescript-iris#620 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
purefunctor/purescript-iris#613 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
purefunctor/purescript-iris#560 ·
I maintainer di solito rispondono entro 1 giorno
-
tooling
Difficoltà 4/5 3-5 giorni Idoneità per principianti 58/100
purefunctor/purescript-iris#507 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di purefunctor/purescript-iris
Issue simili
-
RUSTSEC-2026-0348: Brotli certificate decompression can allocate up to 1 GiB before authenticationAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 60/100
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 62/100
-
core: Amount::from_str panics on values above 21M BTC instead of returning an errorForse già presa @bhuvan-somisetty l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
crate: spate-s3
Difficoltà 2/5 Mezza giornata Idoneità per principianti 62/100
I maintainer di solito rispondono entro 1 giorno
-
write_iceberg ignores the table's write.parquet.compression-codec propertyForse già presa @YuangGao l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
Eventual-Inc/Daft#7606 ·
I maintainer di solito rispondono entro 1 giorno