Skip to content
1 change: 1 addition & 0 deletions eng/reference-scanner/known-domains.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ github.com/dotnet/dotnet
github.com/dotnet/dotnet-api-docs
github.com/dotnet/dotnet-docker
github.com/dotnet/efcore
github.com/dotnet/fsharp
github.com/dotnet/maui
github.com/dotnet/msbuild
github.com/dotnet/roslyn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: >
NOT for writing new programs.
USE FOR: upgrading TargetFramework from net10.0 to net11.0, fixing build errors
after updating the .NET 11 SDK, resolving source-breaking and behavioral changes
in .NET 11 runtime, C# 15 compiler, and EF Core 11, adapting to updated minimum
in .NET 11 runtime, C# 15 / F# 11 compiler, and EF Core 11, adapting to updated minimum
hardware requirements (x86-64-v2, Arm64 LSE), and updating CI/CD pipelines and
Dockerfiles for .NET 11.
DO NOT USE FOR: .NET Framework migrations, upgrading from .NET 9 or earlier,
Expand All @@ -26,7 +26,8 @@ Migrate a .NET 10 project or solution to .NET 11, systematically resolving all b
- Resolving build errors or new warnings after updating the .NET 11 SDK
- Adapting to behavioral changes in .NET 11 runtime, ASP.NET Core 11, or EF Core 11
- Updating CI/CD pipelines, Dockerfiles, or deployment scripts for .NET 11
- Fixing C# 15 compiler breaking changes after SDK upgrade
- Fixing C# 15 compiler breaking changes after SDK upgrade (see the C#-specific “Common patterns” list in Step 3)
- Fixing F# 11 compiler breaking changes after SDK upgrade (see the F# 11 “What’s new” documentation at https://learn.microsoft.com/dotnet/fsharp/whats-new/fsharp-11)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Fixing C# 15 compiler breaking changes after SDK upgrade (see the C#-specific “Common patterns” list in Step 3)
- Fixing F# 11 compiler breaking changes after SDK upgrade (see the F# 11 “What’s new” documentation at https://learn.microsoft.com/dotnet/fsharp/whats-new/fsharp-11)
- Fixing C# 15 and F# 11 compiler breaking changes after SDK upgrade.

I pulled out all docs links because they added tokens for no benefit. It can find docs. And the extra text here is surely not necessary

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied in e95247e — combined both bullets into a single line and removed the docs link.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pulled out all docs links because they added tokens for no benefit. It can find docs. And the extra text here is surely not necessary

Are you sure on that? I assume that without the link, the LLM will not always initiate a web_fetch call. In other words, doesn't the omission of the links make the process less deterministic?


## When Not to Use

Expand All @@ -39,7 +40,7 @@ Migrate a .NET 10 project or solution to .NET 11, systematically resolving all b

| Input | Required | Description |
|-------|----------|-------------|
| Project or solution path | Yes | The `.csproj`, `.sln`, or `.slnx` entry point to migrate |
| Project or solution path | Yes | The `.csproj`, `.fsproj`, `.sln`, or `.slnx` entry point to migrate |
| Build command | No | How to build (e.g., `dotnet build`, a repo build script). Auto-detect if not provided |
| Test command | No | How to run tests (e.g., `dotnet test`). Auto-detect if not provided |
| Project type hints | No | Whether the project uses ASP.NET Core, EF Core, Cosmos DB, etc. Auto-detect from PackageReferences and SDK attributes if not provided |
Expand All @@ -52,7 +53,7 @@ Migrate a .NET 10 project or solution to .NET 11, systematically resolving all b

### Step 1: Assess the project

1. Identify how the project is built and tested. Look for build scripts, `.sln`/`.slnx` files, or individual `.csproj` files.
1. Identify how the project is built and tested. Look for build scripts, `.sln`/`.slnx` files, or individual `.csproj`/`.fsproj` files.
2. Run `dotnet --version` to confirm the .NET 11 SDK is installed. If it is not, stop and inform the user.
3. Determine which technology areas the project uses by examining:
- **SDK attribute**: `Microsoft.NET.Sdk.Web` → ASP.NET Core; `Microsoft.NET.Sdk.WindowsDesktop` with `<UseWPF>` or `<UseWindowsForms>` → WPF/WinForms
Expand All @@ -67,7 +68,7 @@ Migrate a .NET 10 project or solution to .NET 11, systematically resolving all b

### Step 2: Update the Target Framework

1. In each `.csproj` (or `Directory.Build.props` if centralized), change:
1. In each `.csproj`/`.fsproj` (or `Directory.Build.props` if centralized), change:
```xml
<TargetFramework>net10.0</TargetFramework>
```
Expand All @@ -89,7 +90,8 @@ Load reference documents based on the project's technology areas:

| Reference file | When to load |
|----------------|-------------|
| `references/csharp-compiler-dotnet10to11.md` | Always (C# 15 compiler breaking changes) |
| `references/csharp-compiler-dotnet10to11.md` | Project uses C# (C# 15 compiler breaking changes) |
| `references/fsharp-compiler-dotnet10to11.md` | Project uses F# (F# 11 compiler breaking changes) |
Comment thread
ViktorHofer marked this conversation as resolved.
Outdated
| `references/core-libraries-dotnet10to11.md` | Always (applies to all .NET 11 projects) |
| `references/sdk-msbuild-dotnet10to11.md` | Always (SDK and build tooling changes) |
| `references/efcore-dotnet10to11.md` | Project uses Entity Framework Core (especially Cosmos DB provider) |
Expand Down Expand Up @@ -185,7 +187,8 @@ The `references/` folder contains detailed breaking change information organized

| Reference file | When to load |
|----------------|-------------|
| `references/csharp-compiler-dotnet10to11.md` | Always (C# 15 compiler breaking changes) |
| `references/csharp-compiler-dotnet10to11.md` | Project uses C# (C# 15 compiler breaking changes) |
| `references/fsharp-compiler-dotnet10to11.md` | Project uses F# (F# 11 compiler breaking changes) |
| `references/core-libraries-dotnet10to11.md` | Always (applies to all .NET 11 projects) |
| `references/sdk-msbuild-dotnet10to11.md` | Always (SDK and build tooling changes) |
| `references/efcore-dotnet10to11.md` | Project uses Entity Framework Core (especially Cosmos DB provider) |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# F# 11 Compiler Breaking Changes (.NET 11)

These breaking changes affect F# projects targeting `net11.0` (which uses F# 11 by default). F# 11 ships with the .NET 11 SDK.

> **Note:** .NET 11 is in preview. This covers changes through Preview 1. Additional breaking changes may be introduced in later previews.

## Source-Incompatible Changes

### ML compatibility removal

**Impact: Medium.** F# 11 removes all remaining ML/OCaml compatibility constructs that the compiler has carried since F#'s origins as an OCaml dialect. This is a significant cleanup (~7,000 lines of legacy code removed).

The following are **removed**:
- **Source file extensions:** `.ml` and `.mli` files are no longer recognized as F# source files.
- **Directives:** `#light` and `#indent` directives are removed. (Whitespace-sensitive syntax has been the default for many years.)
- **Compiler flags:** `--mlcompatibility`, `--light`, `--indentation-syntax`, `--no-indentation-syntax`, and `--ml-keywords` are all removed.
- **Reserved keywords released:** `asr`, `land`, `lor`, `lsl`, `lsr`, and `lxor` — previously reserved for ML compatibility — are now available as regular identifiers.

```fsharp
// BREAKS — .ml file extension
// Rename MyModule.ml → MyModule.fs
// Rename MyModule.mli → MyModule.fsi

// BREAKS — #light directive
#light "off" // error: directive no longer recognized

// FIX — simply remove the directive (whitespace-sensitive syntax is the default)
```

**Fix:**
1. Rename any `.ml` files to `.fs` and `.mli` files to `.fsi`.
2. Remove all `#light` and `#indent` directives from source files.
3. Remove `--mlcompatibility` and related flags from project files, build scripts, and CI configurations.
4. If you used `asr`, `land`, `lor`, `lsl`, `lsr`, or `lxor` as escaped identifiers (e.g., `` ``asr`` ``), you can now use them as plain identifiers.

See also: [dotnet/fsharp#19143](https://github.com/dotnet/fsharp/pull/19143)

## Performance Improvements (non-breaking)

### Parallel compilation enabled by default

Parallel compilation (preview in F# 10) is now enabled by default for all projects. This includes parallel reference resolution, graph-based type checking, parallel optimizations, and parallel IL code generation.

If you encounter issues, opt out with the `--parallelcompilation-` compiler flag.

### Faster compilation of computation expression-heavy code

The compiler's stack-overflow prevention mechanism (`StackGuard`) has been replaced with `RuntimeHelpers.TryEnsureSufficientExecutionStack()`, significantly reducing thread creation for deeply nested computation expressions (e.g., `task { }`, `async { }`).
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: migrate-dotnet8-to-dotnet9
description: >
Migrate a .NET 8 project to .NET 9 and resolve all breaking changes.
USE FOR: upgrading TargetFramework from net8.0 to net9.0, fixing build errors
after updating the .NET 9 SDK, resolving behavioral changes in .NET 9 / C# 13 /
after updating the .NET 9 SDK, resolving behavioral changes in .NET 9 / C# 13 / F# 9 /
ASP.NET Core 9 / EF Core 9, replacing BinaryFormatter (now always throws),
resolving SYSLIB0054-SYSLIB0057, adapting to params span overload resolution,
fixing C# 13 compiler changes, updating HttpClientFactory for SocketsHttpHandler,
fixing C# 13 / F# 9 compiler changes, updating HttpClientFactory for SocketsHttpHandler,
and resolving EF Core 9 migration/Cosmos DB changes.
DO NOT USE FOR: .NET Framework migrations, upgrading from .NET 7 or earlier,
greenfield .NET 9 projects, or cosmetic modernization unrelated to the upgrade.
Expand Down Expand Up @@ -35,7 +35,7 @@ Migrate a .NET 8 project or solution to .NET 9, systematically resolving all bre

| Input | Required | Description |
|-------|----------|-------------|
| Project or solution path | Yes | The `.csproj`, `.sln`, or `.slnx` entry point to migrate |
| Project or solution path | Yes | The `.csproj`, `.fsproj`, `.sln`, or `.slnx` entry point to migrate |
| Build command | No | How to build (e.g., `dotnet build`, a repo build script). Auto-detect if not provided |
| Test command | No | How to run tests (e.g., `dotnet test`). Auto-detect if not provided |
| Project type hints | No | Whether the project uses ASP.NET Core, EF Core, WinForms, WPF, containers, etc. Auto-detect from PackageReferences and SDK attributes if not provided |
Expand All @@ -48,7 +48,7 @@ Migrate a .NET 8 project or solution to .NET 9, systematically resolving all bre

### Step 1: Assess the project

1. Identify how the project is built and tested. Look for build scripts, `.sln`/`.slnx` files, or individual `.csproj` files.
1. Identify how the project is built and tested. Look for build scripts, `.sln`/`.slnx` files, or individual `.csproj`/`.fsproj` files.
2. Run `dotnet --version` to confirm the .NET 9 SDK is installed. If it is not, stop and inform the user.
3. Determine which technology areas the project uses by examining:
- **SDK attribute**: `Microsoft.NET.Sdk.Web` → ASP.NET Core; `Microsoft.NET.Sdk.WindowsDesktop` with `<UseWPF>` or `<UseWindowsForms>` → WPF/WinForms
Expand All @@ -63,7 +63,7 @@ Migrate a .NET 8 project or solution to .NET 9, systematically resolving all bre

### Step 2: Update the Target Framework

1. In each `.csproj` (or `Directory.Build.props` if centralized), change:
1. In each `.csproj`/`.fsproj` (or `Directory.Build.props` if centralized), change:
```xml
<TargetFramework>net8.0</TargetFramework>
```
Expand All @@ -87,7 +87,8 @@ Work through compilation errors and new warnings systematically. Load the approp

| If the project uses… | Load reference |
|-----------------------|----------------|
| Any .NET 9 project | `references/csharp-compiler-dotnet8to9.md` |
| C# project | `references/csharp-compiler-dotnet8to9.md` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this duplicates the "when to load" at the end. I don't remember doing that-- maybe I forgot? But seems one should be deleted.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the duplicate Step 3 table in e95247e. The Reference Documents section at the bottom is now the single source of truth. Step 3 just says to load from that table. Applied to all three skills.

| F# project | `references/fsharp-compiler-dotnet8to9.md` |
| Any .NET 9 project | `references/core-libraries-dotnet8to9.md` |
| Any .NET 9 project | `references/sdk-msbuild-dotnet8to9.md` |
| ASP.NET Core | `references/aspnet-core-dotnet8to9.md` |
Expand Down Expand Up @@ -219,7 +220,8 @@ The `references/` folder contains detailed breaking change information organized

| Reference file | When to load |
|----------------|-------------|
| `references/csharp-compiler-dotnet8to9.md` | Always (C# 13 compiler breaking changes — InlineArray on records, iterator safe context, collection expression overloads) |
| `references/csharp-compiler-dotnet8to9.md` | Project uses C# (C# 13 compiler breaking changes — InlineArray on records, iterator safe context, collection expression overloads) |
| `references/fsharp-compiler-dotnet8to9.md` | Project uses F# (F# 9 compiler breaking changes) |
| `references/core-libraries-dotnet8to9.md` | Always (applies to all .NET 9 projects) |
| `references/sdk-msbuild-dotnet8to9.md` | Always (SDK and build tooling changes) |
| `references/aspnet-core-dotnet8to9.md` | Project uses ASP.NET Core |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# F# 9 Compiler Breaking Changes (.NET 9)

These breaking changes affect F# projects targeting `net9.0` (which uses F# 9 by default). F# 9 ships with the .NET 9 SDK.

## Source-Incompatible Changes

### Auto-generated `.Is*` properties on discriminated unions

**Impact: Medium.** F# 9 auto-generates `.Is*` properties for each case of a discriminated union. If you already defined custom `Is*` properties or members with the same names, a conflict will occur.

```fsharp
// BREAKS — custom property conflicts with auto-generated one
type Shape =
| Circle of radius: float
| Rectangle of width: float * height: float
member this.IsCircle = // now conflicts with auto-generated IsCircle
match this with Circle _ -> true | _ -> false
```

**Fix:** Remove the custom `Is*` members — the compiler-generated versions provide the same functionality.

### Struct unions with overlapping fields and reflection

**Impact: Low–Medium.** In FSharp.Core 9.0, struct unions with overlapping fields now generate detailed internal mappings to support correct reading via reflection. Code or libraries using `FSharpValue.GetUnionFields` or similar reflection APIs on struct unions may see different behavior or exceptions if they relied on the previous incomplete mapping.

**Fix:** Update libraries that reflect over struct unions. The new mapping is more complete and correct.

### `ArgumentOutOfRangeException` for collection index out-of-bounds

**Impact: Low.** Accessing an out-of-bounds index in FSharp.Core collections (e.g., `Array`, `List`) now throws `System.ArgumentOutOfRangeException` instead of `System.ArgumentException` in some cases. If your exception-handling code specifically catches `ArgumentException` and not `ArgumentOutOfRangeException`, update it.

```fsharp
// Before: threw ArgumentException in some cases
// After: throws ArgumentOutOfRangeException
try
let _ = [1; 2; 3].[10]
()
with
| :? System.ArgumentOutOfRangeException -> () // update catch patterns
```

## New Language Features (non-breaking but relevant)

### Nullable reference type support (opt-in)

F# 9 adds support for nullable reference types, but this is **off by default**. Enable with `<Nullable>enable</Nullable>` in the `.fsproj` file. Enabling this may surface new warnings about null usage in existing code.

### `_.Property` shorthand for member access in lambdas

F# 9 introduces `_.Property` shorthand syntax in pipelines:
```fsharp
customers |> List.map _.Name
```

This is purely additive and does not break existing code.
36 changes: 19 additions & 17 deletions plugins/dotnet-upgrade/skills/migrate-dotnet9-to-dotnet10/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ description: >
Migrate a .NET 9 project or solution to .NET 10 and resolve all breaking changes.
USE FOR: upgrading TargetFramework from net9.0 to net10.0, fixing build errors
after updating the .NET 10 SDK, resolving source and behavioral changes in
.NET 10 / C# 14 / ASP.NET Core 10 / EF Core 10, updating Dockerfiles for
Debian-to-Ubuntu base images, resolving obsoletion warnings
(SYSLIB0058-SYSLIB0062), adapting to SDK/NuGet changes (NU1510,
PrunePackageReference), migrating System.Linq.Async to built-in
AsyncEnumerable, fixing OpenApi v2 API changes, cryptography renames, and
C# 14 compiler changes (field keyword, extension keyword, span overloads).
.NET 10 / C# 14 / F# 10 / ASP.NET Core 10 / EF Core 10, updating Dockerfiles,
resolving obsoletion warnings (SYSLIB0058-SYSLIB0062), SDK/NuGet changes
(NU1510, PrunePackageReference), System.Linq.Async to built-in
AsyncEnumerable, OpenApi v2 API changes, cryptography renames,
C# 14 compiler changes (field keyword, extension keyword, span overloads),
and F# 10 compiler changes.
DO NOT USE FOR: .NET Framework migrations, upgrading from .NET 8 or earlier
(use migrate-dotnet8-to-dotnet9 first), greenfield .NET 10 projects, or
cosmetic modernization.
LOADS REFERENCES: csharp-compiler, core-libraries, sdk-msbuild (always);
(use migrate-dotnet8-to-dotnet9 first), or greenfield .NET 10 projects.
LOADS REFERENCES: csharp-compiler (C#), fsharp-compiler (F#),
core-libraries, sdk-msbuild (always);
aspnet-core, efcore, cryptography, extensions-hosting,
serialization-networking, winforms-wpf, containers-interop (selective).
---
Expand Down Expand Up @@ -41,7 +41,7 @@ Migrate a .NET 9 project or solution to .NET 10, systematically resolving all br

| Input | Required | Description |
|-------|----------|-------------|
| Project or solution path | Yes | The `.csproj`, `.sln`, or `.slnx` entry point to migrate |
| Project or solution path | Yes | The `.csproj`, `.fsproj`, `.sln`, or `.slnx` entry point to migrate |
| Build command | No | How to build (e.g., `dotnet build`, a repo build script). Auto-detect if not provided |
| Test command | No | How to run tests (e.g., `dotnet test`). Auto-detect if not provided |
| Project type hints | No | Whether the project uses ASP.NET Core, EF Core, WinForms, WPF, containers, etc. Auto-detect from PackageReferences and SDK attributes if not provided |
Expand All @@ -54,7 +54,7 @@ Migrate a .NET 9 project or solution to .NET 10, systematically resolving all br

### Step 1: Assess the project

1. Identify how the project is built and tested. Look for build scripts, `.sln`/`.slnx` files, or individual `.csproj` files.
1. Identify how the project is built and tested. Look for build scripts, `.sln`/`.slnx` files, or individual `.csproj`/`.fsproj` files.
2. Run `dotnet --version` to confirm the .NET 10 SDK is installed. If it is not, stop and inform the user.
3. Determine which technology areas the project uses by examining:
- **SDK attribute**: `Microsoft.NET.Sdk.Web` → ASP.NET Core; `Microsoft.NET.Sdk.WindowsDesktop` with `<UseWPF>` or `<UseWindowsForms>` → WPF/WinForms
Expand All @@ -68,7 +68,7 @@ Migrate a .NET 9 project or solution to .NET 10, systematically resolving all br

### Step 2: Update the Target Framework

1. In each `.csproj` (or `Directory.Build.props` if centralized), change:
1. In each `.csproj`/`.fsproj` (or `Directory.Build.props` if centralized), change:
```xml
<TargetFramework>net9.0</TargetFramework>
```
Expand All @@ -89,11 +89,12 @@ Migrate a .NET 9 project or solution to .NET 10, systematically resolving all br

### Step 3: Resolve build errors and source-incompatible changes

Work through compilation errors and new warnings systematically. Load the appropriate reference documents based on the project type:
Work through compilation errors and new warnings systematically. Load the appropriate reference documents based on what your solution contains:

| If the project uses… | Load reference |
|-----------------------|----------------|
| Any .NET 10 project | `references/csharp-compiler-dotnet9to10.md` |
| If your solution contains… | Load reference |
|----------------------------|----------------|
| C# projects | `references/csharp-compiler-dotnet9to10.md` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment about duplicating when to load table below

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e95247e — same approach as dotnet8-to-dotnet9.

| F# projects | `references/fsharp-compiler-dotnet9to10.md` |
| Any .NET 10 project | `references/core-libraries-dotnet9to10.md` |
Comment thread
ViktorHofer marked this conversation as resolved.
Outdated
| Any .NET 10 project | `references/sdk-msbuild-dotnet9to10.md` |
| ASP.NET Core | `references/aspnet-core-dotnet9to10.md` |
Expand Down Expand Up @@ -261,7 +262,8 @@ The `references/` folder contains detailed breaking change information organized

| Reference file | When to load |
|----------------|-------------|
| `references/csharp-compiler-dotnet9to10.md` | Always (C# 14 compiler breaking changes — field keyword, extension keyword, span overloads) |
| `references/csharp-compiler-dotnet9to10.md` | Project uses C# (C# 14 compiler breaking changes — field keyword, extension keyword, span overloads) |
| `references/fsharp-compiler-dotnet9to10.md` | Project uses F# (F# 10 compiler breaking changes) |
| `references/core-libraries-dotnet9to10.md` | Always (applies to all .NET 10 projects) |
| `references/sdk-msbuild-dotnet9to10.md` | Always (SDK and build tooling changes) |
| `references/aspnet-core-dotnet9to10.md` | Project uses ASP.NET Core |
Expand Down
Loading