Skip to content

Pyrefly: surface secondary annotations as LSP DiagnosticRelatedInformation#4191

Open
anushamukka-dev wants to merge 1 commit into
facebook:mainfrom
anushamukka-dev:export-D111240436
Open

Pyrefly: surface secondary annotations as LSP DiagnosticRelatedInformation#4191
anushamukka-dev wants to merge 1 commit into
facebook:mainfrom
anushamukka-dev:export-D111240436

Conversation

@anushamukka-dev

Copy link
Copy Markdown
Contributor

Summary:
Pyrefly attaches secondary annotations to type errors (e.g. labeling both operands of an unsupported binary operation with their types), and these already render in the CLI's source snippets. In the language server, however, Error::to_diagnostic() dropped them entirely — a lingering TODO noted that mapping them to DiagnosticRelatedInformation required constructing a Url from the module path, "which may not always succeed."

Secondary annotations always live in the same file as the primary error, so we can reuse the error's own module path for their locations. This maps each SecondaryAnnotation to a DiagnosticRelatedInformation — its label becomes the message and Module::to_lsp_range converts the span — and populates Diagnostic::related_information. LSP clients can now show the extra context (e.g. "has type int | str") alongside the diagnostic and let users jump to each labeled span.

Url::from_file_path requires an absolute path and can fail; when it does (or when there are no annotations) we leave related_information as None rather than dropping the diagnostic, so nothing regresses for modules without a materializable on-disk path.

Addresses #105

Differential Revision: D111240436

…ation

Summary:
Pyrefly attaches secondary annotations to type errors (e.g. labeling both operands of an unsupported binary operation with their types), and these already render in the CLI's source snippets. In the language server, however, `Error::to_diagnostic()` dropped them entirely — a lingering TODO noted that mapping them to `DiagnosticRelatedInformation` required constructing a `Url` from the module path, "which may not always succeed."

Secondary annotations always live in the same file as the primary error, so we can reuse the error's own module path for their locations. This maps each `SecondaryAnnotation` to a `DiagnosticRelatedInformation` — its label becomes the message and `Module::to_lsp_range` converts the span — and populates `Diagnostic::related_information`. LSP clients can now show the extra context (e.g. "has type `int | str`") alongside the diagnostic and let users jump to each labeled span.

`Url::from_file_path` requires an absolute path and can fail; when it does (or when there are no annotations) we leave `related_information` as `None` rather than dropping the diagnostic, so nothing regresses for modules without a materializable on-disk path.

Addresses facebook#105

Differential Revision: D111240436
@meta-cla meta-cla Bot added the cla signed label Jul 17, 2026
@meta-codesync

meta-codesync Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

@anushamukka-dev has exported this pull request. If you are a Meta employee, you can view the originating Diff in D111240436.

@github-actions

Copy link
Copy Markdown

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant