Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
20fdc50
Update dependencies from https://dev.azure.com/dnceng/internal/_git/d…
dotnet-maestro[bot] Aug 10, 2026
4a929f3
docs: update state-machine.md for changed workflow SHAs (#20234)
github-actions[bot] Aug 10, 2026
fa85b35
[main] Source code updates from dotnet/dotnet (#20214)
dotnet-maestro[bot] Aug 10, 2026
ab2e066
Localized file check-in by OneLocBuild Task: Build definition ID 499:…
dotnet-bot Aug 10, 2026
80b7e4e
Enable MSBuild node reuse defaults in eng/Build.ps1 and eng/build.sh …
T-Gro Aug 10, 2026
22a8a5d
Set the default F# language version to 11.0 (#20219)
T-Gro Aug 10, 2026
853c500
Fix spurious FS0410 for tuple patternInput bindings (#4161) (#19947)
KirtiRamchandani Aug 11, 2026
8111bff
Ignore lines starting with `#:` (RFC-1337) (#20212)
Martin521 Aug 11, 2026
4890294
feat(Async+Task+ValueTask): consistent helper modules (#19844)
bartelink Aug 11, 2026
51dd37e
Add hot reload baseline reading and recorded EnC state (#20026)
NatElkins Aug 11, 2026
23fa8d5
Optimizer: propagate NoDynamicInvocation (#20242)
auduchinok Aug 11, 2026
089835d
Support OverloadResolutionPriority and a most-concrete overload tiebr…
T-Gro Aug 11, 2026
c2b38d7
Remove always-on UseBindingValueDiscard language feature flag (#20162…
T-Gro Aug 11, 2026
afe45bf
Remove always-on WildCardInForLoop language feature flag (#20221)
T-Gro Aug 11, 2026
4990959
Remove always-on AndBang language feature flag (#20223)
T-Gro Aug 11, 2026
9f19d64
Remove always-on ImplicitYield language feature flag (#20230)
T-Gro Aug 11, 2026
623d80d
Import: Don't walk non-F# assemblies when labelling trait constraint …
auduchinok Aug 12, 2026
1852df8
chore(Async.RunSynchronouslyImmediate): Stragglers re #19804 (#20245)
bartelink Aug 12, 2026
840498e
Optimizer: fix accessing captured values when skipping inlining (#20089)
auduchinok Aug 12, 2026
ce9b62a
Parser: recover on unfinished abstract members (#20070)
auduchinok Aug 12, 2026
22e1934
Remove always-on SingleUnderscorePattern language feature flag (#20222)
T-Gro Aug 12, 2026
208b7b4
Add symbol and type highlighting to F# diagnostics (#20097)
auduchinok Aug 12, 2026
29718dd
Avoid per-instance lock object in InterruptibleLazy and DelayInitArra…
auduchinok Aug 12, 2026
ffa6ef1
Regression matrix: build unmodified repos against local FSharp.Core (…
T-Gro Aug 12, 2026
d3fab44
IL: add ILPreNamespace, make ILPreTypeDef creation lazy (#20092)
auduchinok Aug 12, 2026
1e94cc5
feat(Async): Add exception-unwrapping Await (#19785)
bartelink Aug 13, 2026
6ac056a
IL: fix leaking binary view (#20250)
auduchinok Aug 13, 2026
e09605c
IL: use empty tables for members when possible (#20249)
auduchinok Aug 13, 2026
5d6e4dc
Add regression test: #14454, IAsyncDisposable use in task CE in FSI (…
github-actions[bot] Aug 13, 2026
0640920
Teach compiler driver to ignore unknown warning codes (#20246)
Copilot Aug 13, 2026
d26c842
Remove always-on RelaxWhitespace language feature flag (#20226)
T-Gro Aug 13, 2026
6999595
[main] Update dependencies from dotnet/msbuild (#20073)
dotnet-maestro[bot] Aug 13, 2026
90767c7
[main] Source code updates from dotnet/dotnet (#20252)
dotnet-maestro[bot] Aug 13, 2026
7efd608
Restore legacy cross-assembly inline metadata (#20260)
T-Gro Aug 16, 2026
1928203
Ship FSharp.Core with a net10.0 target framework (#20229)
T-Gro Aug 17, 2026
492d417
Add nullness regression test for recursive inline SRTP memoization (#…
T-Gro Aug 17, 2026
f8287a1
Add generic print and println functions to FSharp.Core (#19265)
bbatsov Aug 18, 2026
c939fe3
Unpin MSBuild deps and flow to VS 18.11 (18.11.0-1.26417.9) (#20278)
T-Gro Aug 18, 2026
161c13d
feat(Async): StartTaskImmediate (#20258)
bartelink Aug 18, 2026
95ca590
[main] Update dependencies from dotnet/roslyn (#20100)
dotnet-maestro[bot] Aug 18, 2026
923796e
Add Unchecked.withNull for unconstrained C# nullable-generic interop …
T-Gro Aug 18, 2026
732b1cd
Add Chiron to the compiler regression-test matrix (#20281)
T-Gro Aug 19, 2026
344602c
Restore source-build overridable prop names for runtime packages (#20…
T-Gro Aug 19, 2026
1e0a6e7
Add regression test for #14596: type inference in task CE (#20257)
github-actions[bot] Aug 19, 2026
b413249
Add build step for Oxpecker_Solid (#20262)
Lanayx Aug 19, 2026
c01bfbd
IL: share ILCallingConv instances (#20254)
auduchinok Aug 19, 2026
26714c1
Make AI expert-review post file+line anchored inline comments, not a …
T-Gro Aug 19, 2026
d9fff57
Update dependencies from https://github.com/dotnet/arcade build 20260…
dotnet-maestro[bot] Aug 19, 2026
bc50d5e
IL: cache C# extension methods per CCU (#20256)
auduchinok Aug 19, 2026
d05075e
Parser: recover on missing 'when' conditions (#20071)
auduchinok Aug 19, 2026
24119c4
Export DOTNET_ROOT for repo-local runtime resolution in CLI build scr…
xperiandri Aug 19, 2026
1361727
Add FSI options tests (#19346)
bbatsov Aug 19, 2026
732b9eb
Retarget the NativeAOT test to net10 to dogfood the net10 FSharp.Core…
T-Gro Aug 19, 2026
8d995fa
feat(Task, Async): parallelLimit, parallelDoLimit
bartelink May 28, 2026
97fdfbe
tidy: Polish xmldoc
bartelink Aug 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .fantomasignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ src/Compiler/SyntaxTree/LexFilter.fs

src/FSharp.Core/array2.fs
src/FSharp.Core/array3.fs
src/FSharp.Core/fslib-extra-pervasives.fs
src/FSharp.Core/Linq.fs
src/FSharp.Core/local.fs
src/FSharp.Core/nativeptr.fs
Expand Down
2 changes: 1 addition & 1 deletion .github/agents/compiler-perf-investigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ These are **general investigation instructions** for this agent, a template for
### 1. Preparation
- **Setup:** Clone/generate repo/snippet/etc.
- **Clear old config:** Remove `global.json` unless needed.
- **Prepare local compiler:** Use `PrepareRepoForRegressionTesting.fsx` and absolute env paths.
- **Prepare local compiler:** Build via `dotnet fsi <fsharp-repo>/eng/scripts/BuildWithLocalFSharp.fsx --build-script '<cmd>'` (sets the local-compiler + FSharp.Core shim env).

### 2. Experiment Matrix

Expand Down
36 changes: 19 additions & 17 deletions .github/agents/expert-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -476,47 +476,49 @@ Execute review in five waves, each building on the previous.

### Wave 5: Deliver Review as Inline Comments

**This wave is mandatory.** Analysis without posting is worthless — the review MUST appear on the PR as posted inline comments at the correct file and line.
**This wave is mandatory.** Analysis without posting is worthless — the review MUST appear on the PR as inline comments anchored to the exact file and line. A prose review body is the failure this wave exists to prevent: the author wrote the diff, so narrating it back is noise. Every review body and every comment begins with the robot+detective disclosure `🤖🕵️`.

1. **Deduplicate first.** Check existing reviews to avoid duplicate content:
1. **Deduplicate first.**
```bash
gh api repos/{owner}/{repo}/pulls/{number}/reviews --jq 'length'
```
If reviews from automated accounts already exist, skip posting and apply the label only.

2. **Post findings as a review with inline comments** at the best-fitting file and line. Use the GitHub API to create a single review with all comments:
2. **Findings exist → one review, inline comments only.** Every finding — *including minor and "nice to have" ones* — is its own inline comment anchored to a file+line, so each becomes an independent, resolvable thread. Never collect findings into the body.
```bash
gh api repos/{owner}/{repo}/pulls/{number}/reviews \
--method POST \
--field event=COMMENT \
--field body='' \
--field 'body=🤖🕵️ AI review — verify independently.' \
--field 'comments=[
{"path":"src/Compiler/Checking/CheckDeclarations.fs","line":2750,"body":"**[Test Coverage]** This code path lacks a test. Add a test exercising this branch."},
{"path":"src/Compiler/CodeGen/IlxGen.fs","line":1234,"body":"**[IL Emission]** Call `stripTyEqns` before this match to handle type abbreviations."}
{"path":"src/Compiler/CodeGen/IlxGen.fs","line":1234,"body":"🤖🕵️ Type abbreviation slips past the match — wrong branch taken.\n```fsharp\ntype Alias = int\nlet f (x: Alias) = () // reaches this case, mishandled\n```"}
]'
```
Each comment needs:
- `path`: file path relative to repo root (from the diff)
- `line`: line number in the **new** version of the file (right side of diff)
- `body`: severity tag in `**[Dimension]**` format, the issue, and suggested fix
- Review **`body` = one short line**, the `🤖🕵️` disclosure. Never a summary, never a finding list.
- `path`: file path from the diff. `line`: line in the **new** file (right side of diff); use `start_line`+`line` for a range.
- Comment body: `🤖🕵️` + one fragment naming the **consequence** (what breaks), then a fenced **user-code** sample — the input/usage that triggers it, or the fix. Show how the problem looks in *user* code; do not restate the product diff.
- **Validated, not guessed.** If you have not run it and seen the result, drop the finding. "Would allocate" / "could box" / "may cancel" without a repro → drop.
- At most ~6–10 comments, ranked Behavioral > Quality > Nitpick.

3. **If no significant issues found**, post an approving review:
3. **No significant issues → approve.** Body is the disclosure plus, optionally, a collapsed list of what was covered — the ONE permitted multi-line body:
```bash
gh pr review {number} --repo {owner}/{repo} --approve --body "LGTM"
gh pr review {number} --repo {owner}/{repo} --approve \
--body $'🤖🕵️ LGTM ✅\n\n<details>\n<summary>Dimensions covered (expand)</summary>\n\n- IL emission\n- Binary compatibility\n- Concurrency\n</details>'
```
The `<details>` block is a bare list of the dimensions/subagents that ran — no prose, no per-dimension write-up.

4. **Apply the label and request human review:**
```bash
gh pr edit {number} --repo {owner}/{repo} --add-label AI-reviewed --add-reviewer T-Gro
```

**Delivery rules:**
- The review body MUST begin with an AI disclosure note (the `🤖` line above). This is non-negotiable — readers must know this is AI-generated, not human-written.
- At most 10 inline comments — prioritize Behavioral over Quality over Nitpick.
- Every comment must reference a specific file and line from the diff.
- Every review body and every inline comment begins with `🤖🕵️`. Non-negotiable — readers must know this is AI-generated.
- The review **body** is only ever: the one-line `🤖🕵️` disclosure (findings present), or `🤖🕵️ LGTM ✅` + the optional collapsed dimensions list (no findings). Anything else in the body — a summary, a numbered list of notes, praise, "two tiny things" — is a bug.
- Every finding is an inline comment anchored to a specific file+line from the diff. No exception for "minor" or "nice" notes: if it is worth saying, anchor it.
- Each comment carries a concrete **user-code** sample and describes **validated** behavior, not a guess.
- **Banned in any body or comment:** prose summary, restating what the PR does, `**[Dimension]**`/`file:LINE` as a text header in the body, hedge/filler ("consider", "might want to", "non-blocking nit", "for consistency"), and any finding lacking a file+line or a concrete code sample.
- Never post duplicate content if reviews already exist on the PR.
- If the PR is too large to review fully, note skipped areas in the review body.
- **NEVER write a wall-of-text review body.** The body is either `LGTM` (approve) or empty (with inline findings). All analysis stays in your context — only actionable findings get posted as inline comments. A review body longer than 10 characters (other than `LGTM`) is a bug.

## Folder Hotspot Mapping

Expand Down
4 changes: 2 additions & 2 deletions .github/docs/state-machine.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ gh-aw safe-output defaults (suppressed below): `target: "*"`, `noop.report-as-is
| `labelops-pr-maintenance` | `add-comment` | 5 | hide-older-comments: true |
| `labelops-pr-maintenance` | `add-labels` | 3 | allowed: AI-needs-CI-fix-input |
| `labelops-pr-maintenance` | `dispatch-workflow` | 3 | workflows: labelops-flake-fix |
| `labelops-pr-security-scan` | `add-labels` | 50 | allowed: 10 labels (⚠️ Affects-* family + Scanned-Clean + Bypassed) |
| `labelops-pr-security-scan` | `add-labels` | 50 | allowed: 11 labels (⚠️ Affects-* family + Suspicious-Prompting + Scope-Review-Needed + Scanned-Clean + Bypassed) |
| `labelops-pr-security-scan` | `add-comment` | 25 | hide-older-comments: true |
| `msbuild-quality-review` | `create-issue` | 1 | title `[msbuild-quality] `, labels: automation+Area-ProjectsAndBuild |
| `msbuild-quality-review` | `create-pull-request` | 1 | draft: true, title `[msbuild-quality] `, protected-files: fallback-to-issue |
Expand Down Expand Up @@ -372,4 +372,4 @@ gh-aw safe-output defaults (suppressed below): `target: "*"`, `noop.report-as-is

---

> generator-version: f107bba1a1cd61dc · source-shas: 06e56c52,149f0bbe,1af951a0,36b2b857,3775b51d,49b2989b,5e54b0e6,5e9a1344,7dca5b8f,9285c8a0,98d92f32,a5296399,acf12bdf,b5c04ea8,ec5fa486,f107bba1,
> generator-version: f107bba1a1cd61dc · source-shas: 06e56c52,149f0bbe,1af951a0,36b2b857,3775b51d,420b9d6e,49b2989b,5e9a1344,7dca5b8f,9285c8a0,98d92f32,acf12bdf,b5c04ea8,d3e496db,ec5fa486,f107bba1,
17 changes: 17 additions & 0 deletions .github/instructions/EngVersioning.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
applyTo:
- "eng/Packages.props"
- "eng/Versions.props"
- "eng/Version.Details.xml"
- "eng/Version.Details.props"
---

These files feed the VMR source-build. The `System.*` dotnet/runtime packages marked *"Necessary for source-build"* in `eng/Version.Details.xml` are overridden at build time by the VMR's generated `PackageVersions.fsharp.props`, which replaces the darc-named `$(System*Version)` properties (e.g. `$(SystemCollectionsImmutableVersion)`) with the live source-built runtime version.

Rules:

- Consume those packages in `eng/Packages.props` through `$(System*Version)` **directly**. Never route them through a renamed or computed alias (e.g. a `$(System*CentralVersion)`) or a version floor — source-build overrides the darc-named property, and a renamed/eagerly-computed intermediate freezes the value so the override never reaches CPM, causing prebuilt packages and `NU1109` downgrades in the source-only build.
- When a transitive consumer (MSBuild, Roslyn) requires a higher minimum than the flowed baseline, raise the declared version in `eng/Version.Details.{xml,props}` instead of adding a floor. Source-build overrides it back down to the live runtime version; product/PR restore uses the declared value.
- fsharp PR/CI does **not** run the VMR source-only prebuilt gate (`SB_CentOSStream10_Online_MsftSdk_x64`), so a green PR restore does not prove source-build correctness. Reason about these edits against source-build.

See `docs/postmortems/regression-sourcebuild-cpm-runtime-version-floor.md` for why.
7 changes: 7 additions & 0 deletions .github/instructions/TypedTreePickle.instructions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
applyTo:
- "src/Compiler/TypedTree/TypedTreePickle.{fs,fsi}"
- "src/Compiler/TypedTree/TypedTree.{fs,fsi}"
- "src/Compiler/Driver/CompilerImports.{fs,fsi}"
---

Expand All @@ -21,6 +22,12 @@ This means:
2. **Additions must be invisible to old readers.** New data goes in stream B, where readers that don't know about it get `0` (the default sentinel) past end-of-stream. New readers detect presence via a tag byte they write unconditionally.
3. **Tag values are forever.** Once a byte value means something in a reader's `match`, that meaning cannot change. Old DLLs encode that value with the old semantics.

## Flag Enums: Reinterpreting a Tag Breaks Old Binaries

The `ValFlags`, `EntityFlags`, and `TyparFlags` types in `TypedTree.fs` pack enum cases into bit patterns exposed as `PickledBits` and serialized verbatim. Adding a case to such an enum must **not** reuse a bit pattern that already exists in shipped metadata with different semantics. Normalizing the new case on the *write* side protects only future binaries — an older compiler already emitted the old pattern into DLLs that exist permanently. If you reuse a pattern, add matching *read*-side normalization (see `ValFlags.OfPickledBits`) that maps the legacy pattern back to its original meaning; otherwise prefer an unused pattern.

For a detailed example of what goes wrong when a serialized flag pattern is reinterpreted, see `docs/postmortems/regression-legacy-inline-metadata-dynamic-invocation.md`.

## Reading and Writing Must Be Perfectly Aligned

The format uses two parallel byte streams. Every `p_*` (write) function has a corresponding `u_*` (read) function. They must produce and consume the **exact same byte sequence** under **every possible code path** — including paths gated by feature flags, language versions, or target frameworks that your current build may not exercise.
Expand Down
2 changes: 2 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
Cannot live in eng/TargetFrameworks.props because it's imported before Arcade. -->
<PropertyGroup Condition="'$(DotNetBuildSourceOnly)' == 'true'">
<FSharpNetCoreProductTargetFramework>$(NetCurrent)</FSharpNetCoreProductTargetFramework>
<!-- Source-build targets only $(NetCurrent); collapse the shipped-net pin to it (its ref pack is always present). -->
<FSharpCoreShippedNetTargetFramework>$(NetCurrent)</FSharpCoreShippedNetTargetFramework>
</PropertyGroup>

<!-- It's important we set TFM before this, since FSharpTests.Directory.Build.props uses it.
Expand Down
7 changes: 7 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
<NoWarn>$(NoWarn);NU1507</NoWarn>
</PropertyGroup>

<!-- net10.0 ships in the FSharp.Core package only; in-repo .NET consumers keep binding netstandard2.1. -->
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(Configuration)' != 'Proto'">
<ProjectReference Update="@(ProjectReference)">
<SetTargetFramework Condition="'%(ProjectReference.Filename)' == 'FSharp.Core' and '%(ProjectReference.SetTargetFramework)' == ''">TargetFramework=netstandard2.1</SetTargetFramework>
</ProjectReference>
</ItemGroup>

<!-- Disable R2R when building source-only and not targeting the current SDK bundled TFM. -->
<PropertyGroup>
<PublishReadyToRun Condition="'$(DotNetBuildSourceOnly)' == 'true' and
Expand Down
23 changes: 17 additions & 6 deletions FSharpBuild.Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,23 @@
</ItemGroup>
</Target>

<!-- SDK targets override -->
<PropertyGroup Condition="'$(Configuration)' != 'Proto' AND '$(DisableCompilerRedirection)'!='true' AND Exists('$(ProtoOutputPath)')">
<FSharpBuildAssemblyFileOverride>$(ProtoOutputPath)\fsc\FSharp.Build.dll</FSharpBuildAssemblyFileOverride>
</PropertyGroup>
<UsingTask TaskName="FSharpEmbedResourceText" AssemblyFile="$(FSharpBuildAssemblyFileOverride)" Override="true" Condition="'$(Configuration)' != 'Proto' AND '$(DisableCompilerRedirection)'!='true' AND Exists('$(ProtoOutputPath)')" />
<UsingTask TaskName="FSharpEmbedResXSource" AssemblyFile="$(FSharpBuildAssemblyFileOverride)" Override="true" Condition="'$(Configuration)' != 'Proto' AND '$(DisableCompilerRedirection)'!='true' AND Exists('$(ProtoOutputPath)')" />
<!-- SDK targets override: the SDK's released FSharp.Build cannot generate the classified resource
accessors FSComp.txt is compiled with, so the tasks come from the Bootstrap, or from this repo's own
build for projects opting in - FSharp.Build itself cannot, its FSBuild.txt would need its own output
before it is built. No Exists check, so a missing assembly is an error rather than a silent fallback
to the SDK's. TaskHostFactory keeps the node from locking what it loads. -->
<PropertyGroup>
<FSharpBuildTasksAssembly Condition="'$(Configuration)' != 'Proto' AND '$(DisableCompilerRedirection)' != 'true' AND Exists('$(ProtoOutputPath)')">$(ProtoOutputPath)\fsc\FSharp.Build.dll</FSharpBuildTasksAssembly>
<FSharpBuildTasksAssembly Condition="'$(FSharpBuildTasksAssembly)' == '' AND '$(UseBootstrappedFSharpBuildTasks)' == 'true'">$(ArtifactsDir)bin\FSharp.Build\$(Configuration)\netstandard2.0\FSharp.Build.dll</FSharpBuildTasksAssembly>
</PropertyGroup>
<UsingTask TaskName="FSharpEmbedResourceText" AssemblyFile="$(FSharpBuildTasksAssembly)" Override="true" TaskFactory="TaskHostFactory" Condition="'$(FSharpBuildTasksAssembly)' != ''" />
<UsingTask TaskName="FSharpEmbedResXSource" AssemblyFile="$(FSharpBuildTasksAssembly)" Override="true" TaskFactory="TaskHostFactory" Condition="'$(FSharpBuildTasksAssembly)' != ''" />

<Target Name="BuildFSharpBuildForResourceGeneration"
BeforeTargets="GenerateFSharpTextResources"
Condition="'$(UseBootstrappedFSharpBuildTasks)' == 'true' AND '$(FSharpBuildTasksAssembly)' != '' AND !Exists('$(FSharpBuildTasksAssembly)')">
<MSBuild Projects="$(RepoRoot)src\FSharp.Build\FSharp.Build.fsproj" RemoveProperties="TargetFramework" />
</Target>


<Target Name="BeforeResGen"
Expand Down
Loading