Show diagnostic context notes in language server diagnostics
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 72/100
- issue の種類
- 機能追加
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- rust
調査の方向性
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.
索引モデルが issue の本文から書いたものです。
説明
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.
- 主要言語
- Rust
- スター
- 118
- フォーク
- 12
- 平均マージ
- 7時間 23分
- マージ済み PR(30日)
- 100
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
purefunctor/purescript-iris のほかの issue
-
Instance matching treats unknown types as apart from every instance再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンchecking diagnostics
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
purefunctor/purescript-iris#654 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
ideas
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
purefunctor/purescript-iris#620 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
purefunctor/purescript-iris#613 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
purefunctor/purescript-iris#560 ·
メンテナーはふだん 1 日以内に返信
-
tooling
難易度 4/5 3〜5日 初心者へのやさしさ 58/100
purefunctor/purescript-iris#507 ·
メンテナーはふだん 1 日以内に返信
purefunctor/purescript-iris の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
adorsys/status-list-server#698 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
nannou-org/egui_graph#92 ·
メンテナーはふだん 1 日以内に返信
-
documentation good first issue
難易度 2/5 半日 初心者へのやさしさ 72/100
sujithputta02/Esapay#13 ·
-
Deduplicate normalized_f64_bits (hash_table.rs and bloom_filter.rs)対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
tursodatabase/turso#10002 ·
メンテナーはふだん 1 日以内に返信
-
needs triage
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
topgrade-rs/topgrade#2419 ·
メンテナーはふだん 1 日以内に返信