Skip to content

Commit 4e0b232

Browse files
T-GroCopilot
andcommitted
Merge branch 'main' into agentics/state-machine-cleanup
PR #19909 (docs: update state-machine diagram for security scan pagination + date filter) touched the same file but against the prior short auto-generated version. Resolved by keeping our fully regenerated version, which already covers the security-scan changes in compact form: - line 243: 'paginate PRs (newest-first, skip isDraft, cutoff 2026-05-12)' - line 27 glossary: '2026-05-12 cutoff is the date the scanner went live' - line 248: 'state.json sha == current headRefOid?' (memory check) Verified: 584 lines, 86 pipes, 0 long edges, 6/6 mermaid blocks render. All readability budgets satisfied. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2 parents 8b85ece + 14c4ced commit 4e0b232

184 files changed

Lines changed: 10359 additions & 3059 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
applyTo:
3+
- "src/Compiler/**/*.{fs,fsi}"
4+
- "vsintegration/src/**/*.{fs,fsi}"
5+
- "tests/FSharp.Compiler.ComponentTests/**/*.fs"
6+
- "tests/FSharp.Compiler.Service.Tests/**/*.fs"
7+
- "vsintegration/tests/**/*.fs"
8+
---
9+
10+
# Code Style: No Bloat
11+
12+
Reviewers read code, not prose. Add bytes only when they pay for themselves.
13+
14+
## Comments
15+
16+
Good names **always** beat comments. Before writing a comment, ask: *can I rename a value, extract a function, or use an active pattern so the comment becomes unnecessary?* If yes, do that instead.
17+
18+
- **Do not** restate what the code says (variable name, type name, attribute name, function signature).
19+
- **Do not** narrate the algorithm step-by-step. The diff is the algorithm.
20+
- **Do not** justify design decisions inline ("we chose X over Y because…"). Put rationale in the commit message or PR body.
21+
- **Do not** leave war-story comments ("previously we did Z, but…", "counter-example: …"). The history is in `git log`.
22+
- **Do not** write multi-line `///` doc comments for internal helpers whose body is one expression.
23+
24+
Acceptable comments answer **why**, not **what**, and only when the *why* is non-obvious and cannot be expressed by renaming:
25+
- Workarounds for compiler/runtime bugs (link the bug).
26+
- Performance constraints invisible from the code shape ("inner loop runs 50M times per typecheck").
27+
- Cross-file invariants the code itself can't enforce.
28+
29+
If you are tempted to write `// This is intentional`, change the code so the intent is structural, not decorative.
30+
31+
## Code shape
32+
33+
- Compact, idiomatic F#: pattern matching over `if`/`elif` ladders; active patterns where they remove duplication.
34+
- Low cyclomatic complexity per function. Extract helpers — even one-line ones — when a name clarifies a step.
35+
- Prefer module-level `let` over big bodies with nested locals.
36+
- New file > bloating an existing 5000-line file when adding a self-contained concept.
37+
38+
## Test code
39+
40+
Tests get a touch more leeway for explanation, but the same rules largely apply:
41+
42+
- One parametrized test (`[<Theory>]`, `[<InlineData>]`, or a `for/yield` over inputs) > five copy-pasted tests.
43+
- Module-level constants for shared paths (`Path.Combine` for OS neutrality), shared source strings, and shared expected outputs.
44+
- Helpers like `parseAndCheck code` over reinventing the setup per test.
45+
- Don't reinvent an entire `.fs` file inside each test when one shared module-level binding will do.
46+
47+
## PR scope
48+
49+
**Not paid by LOC.** Large PRs are typically shitty PRs. If the diff has 1000+ lines, split it.
50+
- Cleanup commits separate from feature commits.
51+
- No "phase tag" / "transitional measure" / "follow-up" comments left behind — either do it now in a follow-up commit, or file an issue. Don't leave breadcrumbs in the code.
52+
53+
## When in doubt
54+
55+
Delete the comment, rename the value, and re-read. If the code is still unclear, *that* is what needs fixing — not the comment.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
name: pr-description
3+
description: Use when drafting, proposing, creating, or editing prose for a dotnet/fsharp GitHub PR or issue — body, title, comment, review summary, edits — including bare asks like "open a PR", "ship this", "write up what I did", "summarise the change", "reply on the PR", "edit the issue body", "gh pr create", "gh pr comment", "gh pr edit --body", "gh issue comment", "gh pr review --body". Primary use case is PR descriptions; same rules apply to PR/issue comments and review summaries. Not for labels, reviewers, merging, or code-review findings (just the prose write-up of them).
4+
---
5+
6+
# Authoring GitHub Prose for dotnet/fsharp
7+
8+
Reviewers can already see the Files tab, the commit log, and the issue thread. Say what behavior changed and why, in as few words as possible.
9+
10+
## Rules
11+
12+
Rules 1, 2, 4, 5 are defaults; if the user insists, push back once then comply. Rule 3 is non-negotiable — `-b "..."` ships broken markdown (see PR #19866).
13+
14+
1. **No change inventory.** No file/module/method/test lists. No `## Changes`/`## Implementation` section. Mention an identifier only when it *is* the user-visible behavior. Whatever the reader already has (Files tab for PRs, commit log for follow-up comments, issue history for issue edits) — don't re-list it.
15+
2. **No LLM slop, no justification scaffolding.** No emoji headers, no "TL;DR" above a 3-line body, no Motivation/Background/Approach/Testing sections, no re-stating the title or the comment you're replying to. No "matching the X norm", no "preventing the Y failure (PR #ZZZZ)", no stats, no links to past PRs as proof. The diff is the proof.
16+
3. **Body via `--body-file`, built without shell expansion.** Write the file with your file-creation/edit tool (it writes bytes verbatim — no `$`/backtick evaluation, no delimiter collisions, OS-agnostic). Never `-b "..."` / `--body "..."` — backticks and `$` get shell-evaluated and the render breaks. If you build the file in a shell, use a pwsh verbatim here-string `@'...'@` (cross-platform; single-quoted is mandatory). Applies to `gh pr create/edit/comment/review`, `gh issue create/edit/comment`.
17+
4. **`Fixes #N` to close issues.** Use only when the PR actually closes #N (auto-closes on merge). It is the highest-value line in most PR bodies — never omit it when valid. No "Related to" / speculative links. Preserve existing trailers (`Co-authored-by:`, `Signed-off-by:`, `Reverts #N`); don't invent them.
18+
5. **Title:** imperative, ≤72 chars, no trailing period, no `fix:`/`feat:` prefix. Name the behavior, not the file. A specific title lets the body shrink to `Fixes #N` + one sentence.
19+
20+
## PR-body shapes (pick the smallest that carries the signal)
21+
22+
**One-liner** for bumps / mechanical fixes:
23+
~~~
24+
Update .NET SDK from 10.0.202 to 10.0.204.
25+
~~~
26+
27+
**Title carries the construct + issue link** — preferred when the title is specific:
28+
~~~
29+
Fixes #18009
30+
31+
Wrong colorization when a qualified type name with generic parameters
32+
is used in a static member access expression.
33+
~~~
34+
35+
**Issue link + 1-sentence why** — the most common non-trivial shape:
36+
~~~
37+
Fixes #19751
38+
39+
`--refout` MVIDs were unstable because hashing relied on per-process
40+
string randomization. Switched to a deterministic hash.
41+
~~~
42+
43+
**Before/After code block** — when prose loses information; ≤15 lines, language tag:
44+
~~~markdown
45+
Fixes #15803
46+
47+
```fsharp
48+
let f (x: int) = x <- 1
49+
// before: FS0027 suggested `let mutable x = expression` (illegal for parameters)
50+
// after: FS0027 suggests `let mutable x = x` shadow or `byref<_>`
51+
```
52+
~~~
53+
54+
**Behavior-changes bullet list** — for genuinely multi-behavior PRs. 3–5 bullets naming *behaviors*, never files/modules; if bullets map 1:1 to files, collapse to prose or split the PR:
55+
~~~
56+
Fixes #19710
57+
Fixes #19720
58+
59+
- `match x with null` now preserves type aliases.
60+
- FS0027 on parameters suggests `let mutable x = x` shadow / `byref<_>`.
61+
- `let _ = &expr` compiles like `let x = &expr`.
62+
~~~
63+
64+
Prefer inline backticks for short identifiers over a fenced block. Fenced blocks are the exception — use only when prose loses information.
65+
66+
**Comments / review summaries:** same rules, no title. Usually 1–3 sentences. Quote-reply only the line you're responding to; don't restate it.
67+
68+
## Workflow
69+
70+
Show the title + body (or comment text) in chat first. **Do not run `gh` until the user approves.** Then:
71+
72+
1. **Write the body to a file** with your file-creation tool (bytes verbatim, OS-agnostic, avoids every shell-quoting trap). Or in pwsh:
73+
74+
```powershell
75+
@'
76+
Fix false-positive FS3261 when nullness narrowing leaks across iterations
77+
of seq/list/array comprehensions.
78+
79+
Fixes #19644
80+
'@ | Set-Content -NoNewline pr-body.md
81+
```
82+
83+
2. **Post** with exactly one:
84+
85+
```
86+
gh pr create --title "<imperative title>" --body-file pr-body.md
87+
gh pr edit <N> --body-file pr-body.md # REPLACES body — read first if extending
88+
gh pr comment <N> --body-file pr-body.md
89+
gh pr review <N> --body-file pr-body.md --comment # or --approve / --request-changes
90+
gh issue create --title "<t>" --body-file pr-body.md
91+
gh issue edit <N> --body-file pr-body.md
92+
gh issue comment <N> --body-file pr-body.md
93+
```
94+
95+
To extend without losing the existing body:
96+
`gh pr view <N> --json body -q .body > pr-body.md` → edit → `gh pr edit <N> --body-file pr-body.md`.
97+
98+
3. **Verify** the live render — fetch the body and compare to the file with your view/diff tool. Fail loudly if `gh` fetch errors (a piped failure prints an "all-deleted" diff that misreads as "GitHub mangled it").

.github/workflows/check_release_notes.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,6 @@ jobs:
174174
RELEASE_NOTES_MESSAGE_DETAILS+=$'**If you believe that release notes are not necessary for this PR, please add <kbd>NO_RELEASE_NOTES</kbd> label to the pull request.**'
175175
RELEASE_NOTES_MESSAGE_DETAILS+=$'\n'
176176
RELEASE_NOTES_MESSAGE_DETAILS+=$'\n'
177-
RELEASE_NOTES_MESSAGE_DETAILS+=$"**You can open this PR in browser to add release notes: [open in github.dev](https://github.dev/dotnet/fsharp/pull/${PR_NUMBER})**"
178-
RELEASE_NOTES_MESSAGE_DETAILS+=$'\n'
179-
RELEASE_NOTES_MESSAGE_DETAILS+=$'\n'
180177
RELEASE_NOTES_MESSAGE_DETAILS+='| Change path | Release notes path | Description |'
181178
RELEASE_NOTES_MESSAGE_DETAILS+=$'\n'
182179
RELEASE_NOTES_MESSAGE_DETAILS+='| ---------------- | ------------------ | ----------- |'
@@ -218,6 +215,8 @@ jobs:
218215
RELEASE_NOTES_MESSAGE+=$'## :white_check_mark: No release notes required\n\n'
219216
else
220217
RELEASE_NOTES_MESSAGE+=$'## :heavy_exclamation_mark: Release notes required\n\n'
218+
RELEASE_NOTES_MESSAGE+=$"**You can open this PR in browser to add release notes: [open in github.dev](https://github.dev/dotnet/fsharp/pull/${PR_NUMBER})**"
219+
RELEASE_NOTES_MESSAGE+=$'\n\n'
221220
RELEASE_NOTES_MESSAGE+=$RELEASE_NOTES_MESSAGE_DETAILS
222221
fi
223222

azure-pipelines-PR.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ stages:
796796
continueOnError: true
797797
condition: always()
798798
- job: ILVerify
799+
timeoutInMinutes: 120
799800
pool:
800801
name: $(DncEngPublicBuildPool)
801802
demands: ImageOverride -equals $(_WindowsMachineQueueName)

azure-pipelines.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ extends:
124124
zipSources: false
125125

126126
variables:
127-
- group: DotNet-Symbol-Server-Pats
128127
- group: DotNet-DevDiv-Insertion-Workflow-Variables
129128
- name: _SignType
130129
value: Real

docs/release-notes/.FSharp.Compiler.Service/11.0.100.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
### Fixed
22

3+
* Fix inner mutually-recursive `let rec ... and ...` functions under `--realsig+` not being lifted to top-level static methods (TLR), causing `FSharpFunc` closure allocations and loss of `tail.` opcodes — the large struct-mutual-recursion perf regression reported in [Issue #17607](https://github.com/dotnet/fsharp/issues/17607). ([PR #19882](https://github.com/dotnet/fsharp/pull/19882))
4+
* Fix `TypeLoadException` ("Specialize tried to implicitly override a method with weaker type parameter constraints") and the related CLR crash with constrained inline calls by stripping constraints from closure-class typars in `EraseClosures.convIlxClosureDef`. ([Issue #14492](https://github.com/dotnet/fsharp/issues/14492), [Issue #19075](https://github.com/dotnet/fsharp/issues/19075), [PR #19882](https://github.com/dotnet/fsharp/pull/19882))
5+
36
* Suppress hover/symbol resolution for wildcard `_` patterns inside `member _.…` bodies that incorrectly showed `val _: T` tooltip. ([PR #19760](https://github.com/dotnet/fsharp/pull/19760))
47
* Deduplicate format specifier locations in computation expressions so editor tooling no longer reports duplicate entries for the same `%` specifier. ([Issue #16419](https://github.com/dotnet/fsharp/issues/16419), [PR #19791](https://github.com/dotnet/fsharp/pull/19791))
58
* Reject non-function bindings for single-case and partial active pattern names with FS1209, matching the existing multi-case behavior. ([PR #19763](https://github.com/dotnet/fsharp/pull/19763))
69
* Fix FS0421 "The address of the variable cannot be used at this point" incorrectly raised for the discard pattern `let _ = &expr` when `let x = &expr` compiles. ([Issue #18841](https://github.com/dotnet/fsharp/issues/18841), [PR #19811](https://github.com/dotnet/fsharp/pull/19811))
710
* Honor `--nowarn` and `--warnaserror` for warnings emitted during command-line option parsing ([Issue #19576](https://github.com/dotnet/fsharp/issues/19576), [PR #19776](https://github.com/dotnet/fsharp/pull/19776))
811
* Fix `[<return: X>]` prefix attributes being silently dropped on class members, and fix false-positive `AllowMultiple=false` errors when `[<X>]` and `[<return: X>]` are applied to the same binding. ([Issue #17904](https://github.com/dotnet/fsharp/issues/17904), [Issue #19020](https://github.com/dotnet/fsharp/issues/19020), [PR #19738](https://github.com/dotnet/fsharp/pull/19738))
12+
913
* Preserve type abbreviations (`string`, user-defined aliases) in the refined type of bindings introduced after a `| null` pattern in a `match` expression. ([Issue #19646](https://github.com/dotnet/fsharp/issues/19646), [PR #19745](https://github.com/dotnet/fsharp/pull/19745))
1014
* Fix attributes on return type of unparenthesized tuple methods being silently dropped from IL. ([Issue #462](https://github.com/dotnet/fsharp/issues/462), [PR #19714](https://github.com/dotnet/fsharp/pull/19714))
1115
* Fix false-positive nullness warning (FS3261) when pattern matching narrows nullness inside seq/list/array comprehensions. ([Issue #19644](https://github.com/dotnet/fsharp/issues/19644), [PR #19743](https://github.com/dotnet/fsharp/pull/19743))
@@ -73,14 +77,17 @@
7377
* Reference assembly MVIDs are now deterministic across compiler invocations. Previously, `--refout` / `<ProduceReferenceAssembly>true</ProduceReferenceAssembly>` produced a different MVID every build because the implied signature hash used .NET's randomized `String.GetHashCode()`. ([Issue #19751](https://github.com/dotnet/fsharp/issues/19751), [PR #19801](https://github.com/dotnet/fsharp/pull/19801))
7478
* Parser: recover on unfinished if and binary expressions
7579
([PR #19724](https://github.com/dotnet/fsharp/pull/19724))
80+
* Warn FS3888 when a compiler-semantic attribute on a value/member or type/module is present in the `.fs` but missing from the `.fsi`. Such attributes were previously ignored at the consumer side. Under the `ErrorOnMissingSignatureAttribute` preview language feature, FS3888 is an error. ([Issue #19560](https://github.com/dotnet/fsharp/issues/19560), [PR #19880](https://github.com/dotnet/fsharp/pull/19880))
7681
* Emit debug points at a stack-empty position ([PR #19877](https://github.com/dotnet/fsharp/pull/19877))
7782
* Fix spurious XmlDoc warnings (unknown parameter / no documentation for parameter) under `--warnon:3390` when a get/set property documents the full parameter set across both accessors. ([Issue #13684](https://github.com/dotnet/fsharp/issues/13684), [PR #19884](https://github.com/dotnet/fsharp/pull/19884))
83+
* Quotations of `match s with "" -> _` no longer leak the `s <> null && s.Length = 0` lowering; the empty-string optimization moved from pattern-match compilation to the optimizer so quoted expressions keep `op_Equality(s, "")`. ([Issue #19873](https://github.com/dotnet/fsharp/issues/19873))
7884

7985
### Added
8086

8187
* Added warning FS3884 when a function or delegate value is used as an interpolated string argument. ([PR #19289](https://github.com/dotnet/fsharp/pull/19289))
8288
* Symbols: add ObsoleteDiagnosticInfo ([PR #19359](https://github.com/dotnet/fsharp/pull/19359))
8389
* Add `#version;;` directive to F# Interactive to display version and environment information. ([Issue #13307](https://github.com/dotnet/fsharp/issues/13307), [PR #19332](https://github.com/dotnet/fsharp/pull/19332))
90+
* Debug: rework for expressions stepping ([PR #19894](https://github.com/dotnet/fsharp/pull/19894))
8491

8592
### Changed
8693

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### Fixed
22

3+
* Mirror compiler-semantic attributes (e.g. `[<NoDynamicInvocation>]`, `[<Experimental>]`) in `.fsi` signature files to match `.fs` implementations. ([Issue #19560](https://github.com/dotnet/fsharp/issues/19560), [PR #19880](https://github.com/dotnet/fsharp/pull/19880))
34
* Fix `Array.exists2` documentation examples to use equal-length arrays; the previous examples would throw `ArgumentException` at runtime instead of returning the documented `false`/`true` values. ([PR #19672](https://github.com/dotnet/fsharp/pull/19672))
45
* Move `Async.StartChild` to the "Starting Async Computations" docs category alongside `Async.StartChildAsTask`. ([Issue #19667](https://github.com/dotnet/fsharp/issues/19667))
56
* Add `InlineIfLambda` to `Array.init` ([PR #19869](https://github.com/dotnet/fsharp/pull/19869))

docs/release-notes/.Language/preview.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* Warn (FS3884) when a function or delegate value is used as an interpolated string argument, since it will be formatted via `ToString` rather than being applied. ([PR #19289](https://github.com/dotnet/fsharp/pull/19289))
44
* Added `MethodOverloadsCache` language feature (preview) that caches overload resolution results for repeated method calls, significantly improving compilation performance. ([PR #19072](https://github.com/dotnet/fsharp/pull/19072))
5+
* Added `ErrorOnMissingSignatureAttribute` preview language feature: makes FS3888 (compiler-semantic attribute on the `.fs` but not on the `.fsi`) an error instead of a warning. ([Issue #19560](https://github.com/dotnet/fsharp/issues/19560), [PR #19880](https://github.com/dotnet/fsharp/pull/19880))
56

67
### Fixed
78

docs/release-notes/.VisualStudio/18.vNext.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### Added
2+
3+
* Code-fixes for FS3888 (compiler-semantic attribute on the `.fs` but not the `.fsi`): copy the attribute into the `.fsi`, or remove it from the `.fs`. ([Issue #19560](https://github.com/dotnet/fsharp/issues/19560), [PR #19880](https://github.com/dotnet/fsharp/pull/19880))
4+
15
### Fixed
26

37
* Fixed Rename incorrectly renaming `get` and `set` keywords for properties with explicit accessors. ([Issue #18270](https://github.com/dotnet/fsharp/issues/18270), [PR #19252](https://github.com/dotnet/fsharp/pull/19252))

0 commit comments

Comments
 (0)