Skip to content

Target .NET 10 only and host FSharp.Analyzers.SDK 0.41 - #1566

Merged
nojaf merged 4 commits into
ionide:mainfrom
nojaf:bump-fcs-and-analyzer-sdk
Oct 23, 2026
Merged

nojaf merged 4 commits into
ionide:mainfrom
nojaf:bump-fcs-and-analyzer-sdk

Conversation

@nojaf

@nojaf nojaf commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

FSharp.Analyzers.SDK targets .NET 10 since 0.38, and FSAC hosts the analyzers in its own process, so the server, its libraries and the tests now target net10.0 alone. The SDK only loads analyzers built against its own major.minor version: FSAC hosted 0.37 and skipped the current Ionide.Analyzers (0.20) and G-Research.FSharp.Analyzers (0.26) releases, which are built on 0.41.

FSharp.Analyzers.SDK, FSharp.Compiler.Service (43.12.402) and with it FSharp.Core (10.1.402) are pinned to exact versions. FCS is not binary compatible between releases, so the analyzer ecosystem has to align on one FCS version anyway. Code changes for the new versions:

  • RunAnalyzersSafely is RunAnalyzers, and its results carry AnalyzerMessage, which wraps the Message.
  • GetUsesOfSymbolInFile takes its cancellation token by name, and FSharpType.BasicQualifiedName is an option.
  • FCS reports IsFunctionType through an abbreviation now, so a value of a function type alias keeps rendering as a val.
  • FCS no longer reports the synthetic Invoke member of a delegate, so the highlighting tests expect no Method token there.

Projects that FSAC loads can still target net8.0 or net9.0 and pin the .NET 8 or 9 SDK in global.json: FSAC then loads the MSBuild of that SDK into its .NET 10 process. A new test starts FSAC as a separate process in a project that pins SDK 8 and checks that it type checks the project. The test host cannot cover this in-process, because it registers MSBuild only once.

An SDK older than 10 cannot install a net10.0-only tool and fails with "Settings file 'DotnetToolSettings.xml' was not found in the package". The tool package now also carries a small net8.0 placeholder (FsAutoComplete.ToolStub) that such an SDK installs instead. It says to install the .NET 10 SDK, on stderr and as the error of the initialize request, which editors show. The .NET 10 SDK installs the server.

CI runs one runtime leg per OS and compiler instead of three, and the analyze job, release workflow, build.fsx pipelines, global.json (now .NET 10, which also stops it from picking up a .NET 11 RC), docs and editor configs follow. The repository's own analyzer run moves to fsharp-analyzers 0.41.0 and Ionide.Analyzers 0.20.0, with the same findings as before. The README now states the requirement and why.

nojaf and others added 4 commits October 23, 2026 17:28
FSharp.Analyzers.SDK targets .NET 10 since 0.38, and FSAC hosts the
analyzers in its own process, so the server, its libraries and the
tests now target net10.0 alone. The SDK only loads analyzers built
against its own major.minor version: FSAC hosted 0.37 and skipped the
current Ionide.Analyzers (0.20) and G-Research.FSharp.Analyzers (0.26)
releases, which are built on 0.41.

FSharp.Analyzers.SDK, FSharp.Compiler.Service (43.12.402) and with it
FSharp.Core (10.1.402) are pinned to exact versions. FCS is not binary
compatible between releases, so the analyzer ecosystem has to align on
one FCS version anyway. Code changes for the new versions:
- RunAnalyzersSafely is RunAnalyzers, and its results carry
  AnalyzerMessage, which wraps the Message.
- GetUsesOfSymbolInFile takes its cancellation token by name, and
  FSharpType.BasicQualifiedName is an option.
- FCS reports IsFunctionType through an abbreviation now, so a value of
  a function type alias keeps rendering as a val.
- FCS no longer reports the synthetic Invoke member of a delegate, so
  the highlighting tests expect no Method token there.

Projects that FSAC loads can still target net8.0 or net9.0 and pin the
.NET 8 or 9 SDK in global.json: FSAC then loads the MSBuild of that SDK
into its .NET 10 process. A new test starts FSAC as a separate process
in a project that pins SDK 8 and checks that it type checks the
project. The test host cannot cover this in-process, because it
registers MSBuild only once.

An SDK older than 10 cannot install a net10.0-only tool and fails with
"Settings file 'DotnetToolSettings.xml' was not found in the package".
The tool package now also carries a small net8.0 placeholder
(FsAutoComplete.ToolStub) that such an SDK installs instead. It says to
install the .NET 10 SDK, on stderr and as the error of the initialize
request, which editors show. The .NET 10 SDK installs the server.

CI runs one runtime leg per OS and compiler instead of three, and the
analyze job, release workflow, build.fsx pipelines, global.json (now
.NET 10, which also stops it from picking up a .NET 11 RC), docs and
editor configs follow. The repository's own analyzer run moves to
fsharp-analyzers 0.41.0 and Ionide.Analyzers 0.20.0, with the same
findings as before. The README now states the requirement and why.

Co-authored-by: Tuomas Hietanen <thorium@iki.fi>
A `let rec` inside a `task` cannot compile to a state machine, which
the Release build of CI reports as FS3511, an error with
TreatWarningsAsErrors. The loop that answers the server until it
publishes diagnostics is now a top-level function.
FsAutoComplete now runs on .NET 10 and hosts FSharp.Analyzers.SDK 0.41.
A breaking change before 1.0 bumps the minor version.
On Windows the test timed out without seeing diagnostics for
Program.fs, and its failure message had nothing to go on. FSAC turns
the URI of an opened file into a path and back, which can change the
case of the drive letter, and the test compared the URIs as text. It
now compares the paths, ignoring case on Windows.

When the test fails, it also lists the last messages FSAC sent, and
FSAC runs with --verbose, so the tail of its log shows what it did.
@nojaf
nojaf merged commit 5fe09b5 into ionide:main Oct 23, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant