Skip to content

[Repo Assist] perf: remove global mutable FSharpDisplayContext in DocumentationFormatter#1529

Draft
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/fix-issue-692-remove-global-display-context-2b2fc3df32ab03f7
Draft

[Repo Assist] perf: remove global mutable FSharpDisplayContext in DocumentationFormatter#1529
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/fix-issue-692-remove-global-display-context-2b2fc3df32ab03f7

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 This PR was created by Repo Assist, an automated AI assistant.

Closes #692

Root Cause

DocumentationFormatter held a module-level mutable lastDisplayContext: FSharpDisplayContext = FSharpDisplayContext.Empty. This was set in getTooltipDetailsFromSymbolUse on every hover request but never cleared. Because FSharpDisplayContext holds internal references to FCS type-checking state, it was pinning memory across requests indefinitely — visible as unusually high memory attributed to FSharpDisplayContext in heap snapshots.

Fix

  • Remove the global mutable lastDisplayContext field entirely.
  • Add an explicit displayContext: FSharpDisplayContext parameter to getTooltipDetailsFromSymbol (the only function that actually read the mutable — getTooltipDetailsFromSymbolUse already used symbol.DisplayContext directly throughout its body, making the assignment vestigial).
  • Update the one call-site in ParseAndCheckResults.TryGetFormattedDocumentationForSymbol to pass FSharpDisplayContext.Empty. This matches the pre-existing behaviour for cold starts (before any hover call set the mutable), and is appropriate because this code path searches AssemblySymbol entities resolved from the project's assembly references — not from a live type-check — so no richer context is available there.

Trade-offs

  • The getTooltipDetailsFromSymbol signature is a breaking API change for any downstream consumers of DocumentationFormatter (outside this repo). However, DocumentationFormatter is an internal module (no .fsi signature file), so this should only affect code that references the module directly.
  • FSharpDisplayContext.Empty formats generic parameters with default/anonymous names, which is the same behaviour as before for the cold-start case. Signatures formatted for documentation lookup (the fsharp/documentationForSymbol endpoint) were already using whatever context happened to be cached, which is not necessarily related to the current symbol — so Empty is no worse.

Test Status

dotnet build src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj -f net8.0 — succeeded (0 warnings, 0 errors)
dotnet build src/FsAutoComplete/FsAutoComplete.fsproj -f net8.0 — succeeded (0 warnings, 0 errors)
dotnet fantomas — no reformatting needed

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a

…atter

Eliminates the module-level mutable lastDisplayContext from
DocumentationFormatter, fixing a memory retention issue where
FSharpDisplayContext (and the FCS references it holds) was kept
alive indefinitely between documentation requests.

- Remove mutable lastDisplayContext field entirely
- Add explicit displayContext parameter to getTooltipDetailsFromSymbol
- Remove the now-redundant lastDisplayContext assignment in
  getTooltipDetailsFromSymbolUse (which already used symbol.DisplayContext
  directly for all its formatting)
- Update ParseAndCheckResults caller to pass FSharpDisplayContext.Empty
  (matches previous behaviour when no prior hover call had been made)

Closes #692

Co-authored-by: Copilot <[email protected]>
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.

Keeping FSharpDisplayContext in memory is expensive

0 participants