-
Notifications
You must be signed in to change notification settings - Fork 377
Add F# support to migrate-dotnet* skills #406
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
34f2544
ecb9aa9
3a1a37f
6f20f81
4138ea3
793f6f3
e95247e
aba457b
9409400
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 |
|---|---|---|
|
|
@@ -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. | ||
|
|
@@ -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 | | ||
|
|
@@ -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 | ||
|
|
@@ -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> | ||
| ``` | ||
|
|
@@ -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` | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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` | | ||
|
|
@@ -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 | | ||
|
|
||
| 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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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). | ||
| --- | ||
|
|
@@ -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 | | ||
|
|
@@ -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 | ||
|
|
@@ -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> | ||
| ``` | ||
|
|
@@ -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` | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment about duplicating when to load table below
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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` | | ||
|
ViktorHofer marked this conversation as resolved.
Outdated
|
||
| | Any .NET 10 project | `references/sdk-msbuild-dotnet9to10.md` | | ||
| | ASP.NET Core | `references/aspnet-core-dotnet9to10.md` | | ||
|
|
@@ -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 | | ||
|
|
||
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?