zed/crates/language
Buyun Xu 6dee3fc755
project: Send diagnostic related information in code action requests (#62110)
Closes #62560.
Supersedes #62108, which was a subset of this one.
Overlaps #62400, see comments.

# Objective

Zed flattens the `relatedInformation` of a diagnostic into non-primary
entries of the same diagnostic group. Before this change it did not
retain the original related information on the primary diagnostic, so
code action requests were built from the entries intersecting the
requested range, with the primary diagnostic carrying no
`relatedInformation`.

This caused incomplete code actions from servers such as
`mlir-lsp-server`, which generates `expected-note` edits by walking the
related information of an error or warning diagnostic.

## Solution

Keep the related information the server published on the primary
diagnostic when the diagnostic comes in, next to `data`, and pass it
back when building the code action request.

Nothing is removed from `context.diagnostics`: the flattened entries are
still sent as before, so a diagnostic the server published on its own
and that Zed merged into a group as supporting information keeps being
sent with the severity the server gave it. What it does not recover is
that diagnostic's own `relatedInformation`: ingestion keeps only its
severity. Unchanged from `main`.

Reassembling it from the flattened entries instead, which is what the
first revision of this PR did, is neither faithful — ingestion trims
messages and drops entries with an empty message or pointing at another
file — nor cheap: diagnostics are not indexed by group, so every request
would scan all diagnostics of the buffer, once per server, on every
selection change.

One caveat: the stored ranges are the ones the server published rather
than anchors, so they do not follow edits made after the diagnostic
arrived, while the primary's range does. An edit in that window can put
a resolved insertion a few lines off — `mlir-lsp-server` places the
`expected-note` line at the note's own position. `data` has the same
property today. Anchoring them would mean carrying related information
through the anchor conversion, which I would rather do as a follow-up if
you consider it worth it.

The field is not carried over the proto conversion, as LSP requests are
only built by the peer that received the diagnostics from the language
server.

## Testing

New tests for:

- related information sent verbatim, including the cross-file and empty
entries that flattening drops;
- no related information;
- a flattened entry whose primary is outside the requested range;
- a server-published supporting diagnostic;
- two servers on the same buffer.

Verified on the repro from #62560 that `mlir-lsp-server` inserts both
the `expected-error` and the `expected-note` check
([screenshot](https://github.com/zed-industries/zed/issues/62560#issuecomment-5278476460)).

- `cargo test -p project`
- `cargo test -p language -p editor -p diagnostics`
- `cargo fmt --all -- --check`
- `./script/clippy -p project -p language`

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Fixed incomplete code actions from language servers that rely on the
related information of a diagnostic.
2026-08-17 16:40:29 +00:00
..
benches Extract language_core and grammars crates from language (#52238) 2026-03-25 23:41:09 +00:00
src project: Send diagnostic related information in code action requests (#62110) 2026-08-17 16:40:29 +00:00
build.rs
Cargo.toml git: Decode non-UTF-8 blobs for project diffs (#60821) 2026-08-17 01:47:11 +00:00
LICENSE-GPL