Skip to content

Add ResetCompilerGeneratedNameState to compiler-generated name generators#20017

Merged
T-Gro merged 1 commit into
dotnet:mainfrom
NatElkins:fix-generated-name-counter-reset
Jul 9, 2026
Merged

Add ResetCompilerGeneratedNameState to compiler-generated name generators#20017
T-Gro merged 1 commit into
dotnet:mainfrom
NatElkins:fix-generated-name-counter-reset

Conversation

@NatElkins

@NatElkins NatElkins commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an internal ResetCompilerGeneratedNameState method to the compiler-generated name generators (NiceNameGenerator, StableNiceNameGenerator, and an aggregate on CompilerGlobalState) that restores the fresh-process generated-name layout.

Why

Compiler-generated occurrence names (name@line-N) are allocated from counters on CompilerGlobalState that accumulate across compilations. When a warm checker re-emits the same project in-process, an unchanged closure gets a different occurrence suffix than the previous emit (for example data@10 in one emit and data@10-3 in the next). Consumers that need to align generated names across successive compilations then cannot match them.

The concrete consumer is F# hot reload (#19941): Edit-and-Continue delta emission from a warm checker needs each emit to lay out generated names exactly as a fresh process would, otherwise unchanged closures appear renamed and the delta mapping fails. Measured in the hot reload spike: a one-method edit produced an ambiguous synthesized-type mapping purely because of this drift.

There is intentionally no in-tree caller in this PR; the caller lands with the hot reload emit path in #19941. This PR carries the primitive plus tests so it can be reviewed on its own.

What

  • NiceNameGenerator.ResetCompilerGeneratedNameState() clears the per-(name, file) occurrence counters.
  • StableNiceNameGenerator.ResetCompilerGeneratedNameState() clears the cached stable names and the inner generator's counters.
  • CompilerGlobalState.ResetCompilerGeneratedNameState() resets all three generator fields.
  • Callers must ensure no compilation is concurrently generating names (documented on the aggregate).

Tests

CompilerGlobalStateTests.fs (new): proves names drift across repeated generation without reset; that replaying the same call sequence after reset reproduces the exact original names; that the stable-name cache itself is cleared (same (name, uniq) re-queried with a different range is recomputed, not served stale); and that the aggregate reset reaches all three generators.

Verified locally: FSharp.Compiler.Service.fsproj builds clean, the new test class passes 3/3, fantomas --check clean.

Sequencing

This PR is part of splitting the F# hot reload work (#19941) into small, independently reviewable PRs. The planned order:

  1. Wave 1 (independent of each other, no cross dependencies): Add ResetCompilerGeneratedNameState to compiler-generated name generators #20017 (generated-name counter reset), Add Roslyn-format EnC CustomDebugInformation codec and portable PDB method CDI emission #20018 (EnC CustomDebugInformation codec and method CDI emission), Add ECMA-335 EnC metadata delta writer #20019 (EnC metadata delta writer), plus two upcoming slices: stable synthesized-name replay and the typed-tree differ with rude-edit classification.
  2. Wave 2: baseline reading and recorded CDI state (depends on Add Roslyn-format EnC CustomDebugInformation codec and portable PDB method CDI emission #20018 and the naming slice).
  3. Wave 3: the delta emitter and symbol matcher.
  4. Wave 4: the hot reload session, FCS surface, and the --test:HotReloadDeltas capture hook (F# hot reload: Edit-and-Continue delta emission behind --test:HotReloadDeltas #19941 in its final, much smaller form).
  5. Last, explicitly experimental: Add an experimental flag-gated in-process compile path for hot reload sessions #20031 (the flag-gated in-process compile perf path).

Each slice is rebased on current main, carries its own tests, and is flag-off zero-cost. Everything stays draft until reviewed in order.
Role in the train: warm-checker re-emission must produce fresh-process generated names; the hot reload session resets name counters before each in-process delta compile.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

❗ Release notes required

You can open this PR in browser to add release notes: open in github.dev


✅ Found changes and release notes in following paths:

Change path Release notes path Description
src/Compiler docs/release-notes/.FSharp.Compiler.Service/11.0.100.md

NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 1, 2026
…ethod CDI emission

Adds an internal AbstractIL module implementing, byte for byte, the three Portable PDB
CustomDebugInformation blob formats Roslyn persists per method for Edit and Continue
(EnC Local Slot Map, EnC Lambda and Closure Map, EnC State Machine State Map), with
serializers, deserializers, a portable PDB read-back helper, and an occurrence-key
packing helper for deterministic syntax-offset slots.

Plumbs an optional methodCustomDebugInfoRows side channel through the IL binary writer
options into the portable PDB generator so a compilation can attach CDI rows to named
methods. Names that do not identify exactly one method row are dropped. All existing
writer call sites pass an empty map, so emitted PDBs are byte-identical to before.

No in-tree caller populates the map yet; the consumer is the F# hot reload work in
dotnet#19941, following the same pattern as dotnet#20017 (land isolated, test-covered
infrastructure first, wire the feature later).

Tests: blob round-trips, Roslyn golden-byte encodings, cross-validation against
CDI blobs emitted by a real Roslyn compilation, fail-closed occurrence-key packing
(including an int32-overflow regression where a wrapped negative key previously
escaped the bound check), and end-to-end synthetic PDB emission proving correct
MethodDef parenting, zero rows for an empty map, and no rows for absent or
ambiguous names.
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 1, 2026
Adds an internal, standalone ECMA-335 Edit-and-Continue metadata delta writer to
AbstractIL: delta #- table stream and heap construction (DeltaMetadataTables,
DeltaMetadataSerializer, DeltaTableLayout, DeltaIndexSizing), ECMA-335 II.24.2.6
coded-index encoding (DeltaMetadataEncoding), EncLog/EncMap emission, generation GUID
chaining, user-string and standalone-signature token calculators (IlxDeltaStreams),
and the coordinating writer (FSharpDeltaMetadataWriter) over a plain row-description
input model (DeltaMetadataTypes, ILDeltaHandles, ILMetadataHeaps).

The writer's inputs are row records (names, tokens, signatures, RVAs) plus heap
offsets; it has no dependency on any semantic diffing or session machinery. It
compiles with no in-tree consumer by design: the consumer is the F# hot reload work
in dotnet#19941, following the same upstreaming pattern as dotnet#20017 and dotnet#20018
(land isolated, test-covered infrastructure first, wire the feature in a later PR).

One line of ilwrite.fsi is touched to expose the pre-existing markerForUnicodeBytes
so the delta writer reuses the exact string-marker logic of the full writer. No
behavior change for any existing code path.

Tests (130): coded-index encodings asserted against the production definitions and
ECMA-335 II.24.2.6 order, System.Reflection.Metadata reader parity over emitted
deltas, EncLog/EncMap correctness, stream layout, heap and index sizing,
multi-generation heap-offset chaining asserted against computed expected values,
standalone-signature rows asserted at baseline+1 from a real seeded baseline, and
serializer failure paths.
@NatElkins

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Commenter does not have sufficient privileges for PR 20017 in repo dotnet/fsharp

NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 2, 2026
Per-edit hot reload currently requires an external 'dotnet build -t:Compile' to
refresh the obj assembly the delta emitter reads, making every edit pay a full
MSBuild+fsc invocation on top of the in-process check (measured ~7s/edit vs
~4.7s for a plain build). This adds an experimental, flag-gated path that
produces the same on-disk obj DLL and PDB in-process from the checked project
the session already has, collapsing the two compiles into one (spike-measured
~3.0s/edit with a correct one-method delta).

- FSharpChecker.CompileFromCheckedProject (internal): emits the assembly from
  cached typecheck results (finalize CCU, dedupe QualifiedNameOfFile, optimize,
  IlxGen, write DLL + portable PDB to the requested path), adapted from the
  dotnet#19267 prototype. Before codegen it clears leaked hot-reload
  closure-name state and resets the compiler-generated-name counters
  (ResetCompilerGeneratedNameState) so the emit lays out generated names exactly
  like a fresh-process build; without this an unchanged closure drifts to a new
  occurrence suffix and the delta mapping degenerates.
- FSharpCheckProjectResults.CompilationData and TcImports.NormalizeAssemblyRef
  (internal) supply the compilation inputs, from the same prototype.
- ResetCompilerGeneratedNameState on the name generators, matching
  dotnet#20017 so the branch converges with main when that PR lands.
- Session wiring: when FSHARP_HOTRELOAD_INPROCESS_COMPILE is truthy,
  EmitHotReloadDelta runs the in-process compile after session-active
  validation and before the output freshness pipeline, failing closed as
  DeltaEmissionFailed on any compile error. With the flag unset the code path
  is unchanged beyond a single environment read. The external build remains
  the default; dotnet-watch integration opts in separately.
- The emitted portable PDB keeps the sibling-PDB freshness contract: sequence
  points for line-shifted, unedited methods come from the new compile, not a
  stale external-build PDB (regression-tested; the test fails without the PDB
  emission).

Verified: service HotReload suite 414 passed 0 failed (including the new
flag on/off contract test asserting one updated method with no external
rebuild, a +1 LineUpdate for an unedited shifted method, and the unchanged
stale-output refusal with the flag off); component HotReload suite 229 passed
0 failed (flag-off neutrality).
@NatElkins
NatElkins force-pushed the fix-generated-name-counter-reset branch 2 times, most recently from 40b666b to 35cce81 Compare July 2, 2026 22:03
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 2, 2026
…ethod CDI emission

Adds an internal AbstractIL module implementing, byte for byte, the three Portable PDB
CustomDebugInformation blob formats Roslyn persists per method for Edit and Continue
(EnC Local Slot Map, EnC Lambda and Closure Map, EnC State Machine State Map), with
serializers, deserializers, a portable PDB read-back helper, and an occurrence-key
packing helper for deterministic syntax-offset slots.

Plumbs an optional methodCustomDebugInfoRows side channel through the IL binary writer
options into the portable PDB generator so a compilation can attach CDI rows to named
methods. Names that do not identify exactly one method row are dropped. All existing
writer call sites pass an empty map, so emitted PDBs are byte-identical to before.

No in-tree caller populates the map yet; the consumer is the F# hot reload work in
dotnet#19941, following the same pattern as dotnet#20017 (land isolated, test-covered
infrastructure first, wire the feature later).

Tests: blob round-trips, Roslyn golden-byte encodings, cross-validation against
CDI blobs emitted by a real Roslyn compilation, fail-closed occurrence-key packing
(including an int32-overflow regression where a wrapped negative key previously
escaped the bound check), and end-to-end synthetic PDB emission proving correct
MethodDef parenting, zero rows for an empty map, and no rows for absent or
ambiguous names.
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 2, 2026
Adds an internal, standalone ECMA-335 Edit-and-Continue metadata delta writer to
AbstractIL: delta #- table stream and heap construction (DeltaMetadataTables,
DeltaMetadataSerializer, DeltaTableLayout, DeltaIndexSizing), ECMA-335 II.24.2.6
coded-index encoding (DeltaMetadataEncoding), EncLog/EncMap emission, generation GUID
chaining, user-string and standalone-signature token calculators (IlxDeltaStreams),
and the coordinating writer (FSharpDeltaMetadataWriter) over a plain row-description
input model (DeltaMetadataTypes, ILDeltaHandles, ILMetadataHeaps).

The writer's inputs are row records (names, tokens, signatures, RVAs) plus heap
offsets; it has no dependency on any semantic diffing or session machinery. It
compiles with no in-tree consumer by design: the consumer is the F# hot reload work
in dotnet#19941, following the same upstreaming pattern as dotnet#20017 and dotnet#20018
(land isolated, test-covered infrastructure first, wire the feature in a later PR).

One line of ilwrite.fsi is touched to expose the pre-existing markerForUnicodeBytes
so the delta writer reuses the exact string-marker logic of the full writer. No
behavior change for any existing code path.

Tests (130): coded-index encodings asserted against the production definitions and
ECMA-335 II.24.2.6 order, System.Reflection.Metadata reader parity over emitted
deltas, EncLog/EncMap correctness, stream layout, heap and index sizing,
multi-generation heap-offset chaining asserted against computed expected values,
standalone-signature rows asserted at baseline+1 from a real seeded baseline, and
serializer failure paths.
@NatElkins
NatElkins force-pushed the fix-generated-name-counter-reset branch from 35cce81 to 61aee61 Compare July 7, 2026 14:22
@T-Gro
T-Gro marked this pull request as ready for review July 8, 2026 14:40
@T-Gro
T-Gro requested a review from a team as a code owner July 8, 2026 14:40
@github-actions github-actions Bot added the AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files label Jul 8, 2026
…tors

Compiler-generated occurrence names (name@line-N) are allocated from process-wide
counters on CompilerGlobalState that accumulate across compilations. When a warm
checker re-emits the same project in-process, an unchanged closure therefore gets a
different occurrence suffix than the previous emit, so consumers that align generated
names across compilations (Edit-and-Continue delta emission, dotnet#19941)
cannot match them.

Add an internal ResetCompilerGeneratedNameState to NiceNameGenerator (clears the
per-(name, file) occurrence counters), StableNiceNameGenerator (clears the cached
stable names and the inner counters), and an aggregate on CompilerGlobalState that
resets all three generators, restoring the fresh-process name layout. Callers must
ensure no compilation is concurrently generating names.

No in-tree caller yet; the consumer is the hot reload emit path in dotnet#19941.
Covered by unit tests proving drift without reset, exact replay after reset, and that
the stable-name cache itself is cleared.
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 8, 2026
Adds an internal, standalone ECMA-335 Edit-and-Continue metadata delta writer to
AbstractIL: delta #- table stream and heap construction (DeltaMetadataTables,
DeltaMetadataSerializer, DeltaTableLayout, DeltaIndexSizing), ECMA-335 II.24.2.6
coded-index encoding (DeltaMetadataEncoding), EncLog/EncMap emission, generation GUID
chaining, user-string and standalone-signature token calculators (IlxDeltaStreams),
and the coordinating writer (FSharpDeltaMetadataWriter) over a plain row-description
input model (DeltaMetadataTypes, ILDeltaHandles, ILMetadataHeaps).

The writer's inputs are row records (names, tokens, signatures, RVAs) plus heap
offsets; it has no dependency on any semantic diffing or session machinery. It
compiles with no in-tree consumer by design: the consumer is the F# hot reload work
in dotnet#19941, following the same upstreaming pattern as dotnet#20017 and dotnet#20018
(land isolated, test-covered infrastructure first, wire the feature in a later PR).

One line of ilwrite.fsi is touched to expose the pre-existing markerForUnicodeBytes
so the delta writer reuses the exact string-marker logic of the full writer. No
behavior change for any existing code path.

Tests (130): coded-index encodings asserted against the production definitions and
ECMA-335 II.24.2.6 order, System.Reflection.Metadata reader parity over emitted
deltas, EncLog/EncMap correctness, stream layout, heap and index sizing,
multi-generation heap-offset chaining asserted against computed expected values,
standalone-signature rows asserted at baseline+1 from a real seeded baseline, and
serializer failure paths.
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 8, 2026
…ethod CDI emission

Adds an internal AbstractIL module implementing, byte for byte, the three Portable PDB
CustomDebugInformation blob formats Roslyn persists per method for Edit and Continue
(EnC Local Slot Map, EnC Lambda and Closure Map, EnC State Machine State Map), with
serializers, deserializers, a portable PDB read-back helper, and an occurrence-key
packing helper for deterministic syntax-offset slots.

Plumbs an optional methodCustomDebugInfoRows side channel through the IL binary writer
options into the portable PDB generator so a compilation can attach CDI rows to named
methods. Names that do not identify exactly one method row are dropped. All existing
writer call sites pass an empty map, so emitted PDBs are byte-identical to before.

No in-tree caller populates the map yet; the consumer is the F# hot reload work in
dotnet#19941, following the same pattern as dotnet#20017 (land isolated, test-covered
infrastructure first, wire the feature later).

Tests: blob round-trips, Roslyn golden-byte encodings, cross-validation against
CDI blobs emitted by a real Roslyn compilation, fail-closed occurrence-key packing
(including an int32-overflow regression where a wrapped negative key previously
escaped the bound check), and end-to-end synthetic PDB emission proving correct
MethodDef parenting, zero rows for an empty map, and no rows for absent or
ambiguous names.
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 8, 2026
…ethod CDI emission

Adds an internal AbstractIL module implementing, byte for byte, the three Portable PDB
CustomDebugInformation blob formats Roslyn persists per method for Edit and Continue
(EnC Local Slot Map, EnC Lambda and Closure Map, EnC State Machine State Map), with
serializers, deserializers, a portable PDB read-back helper, and an occurrence-key
packing helper for deterministic syntax-offset slots.

Plumbs an optional methodCustomDebugInfoRows side channel through the IL binary writer
options into the portable PDB generator so a compilation can attach CDI rows to named
methods. Names that do not identify exactly one method row are dropped. All existing
writer call sites pass an empty map, so emitted PDBs are byte-identical to before.

No in-tree caller populates the map yet; the consumer is the F# hot reload work in
dotnet#19941, following the same pattern as dotnet#20017 (land isolated, test-covered
infrastructure first, wire the feature later).

Tests: blob round-trips, Roslyn golden-byte encodings, cross-validation against
CDI blobs emitted by a real Roslyn compilation, fail-closed occurrence-key packing
(including an int32-overflow regression where a wrapped negative key previously
escaped the bound check), and end-to-end synthetic PDB emission proving correct
MethodDef parenting, zero rows for an empty map, and no rows for absent or
ambiguous names.
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 8, 2026
Adds an internal, standalone ECMA-335 Edit-and-Continue metadata delta writer to
AbstractIL: delta #- table stream and heap construction (DeltaMetadataTables,
DeltaMetadataSerializer, DeltaTableLayout, DeltaIndexSizing), ECMA-335 II.24.2.6
coded-index encoding (DeltaMetadataEncoding), EncLog/EncMap emission, generation GUID
chaining, user-string and standalone-signature token calculators (IlxDeltaStreams),
and the coordinating writer (FSharpDeltaMetadataWriter) over a plain row-description
input model (DeltaMetadataTypes, ILDeltaHandles, ILMetadataHeaps).

The writer's inputs are row records (names, tokens, signatures, RVAs) plus heap
offsets; it has no dependency on any semantic diffing or session machinery. It
compiles with no in-tree consumer by design: the consumer is the F# hot reload work
in dotnet#19941, following the same upstreaming pattern as dotnet#20017 and dotnet#20018
(land isolated, test-covered infrastructure first, wire the feature in a later PR).

One line of ilwrite.fsi is touched to expose the pre-existing markerForUnicodeBytes
so the delta writer reuses the exact string-marker logic of the full writer. No
behavior change for any existing code path.

Tests (130): coded-index encodings asserted against the production definitions and
ECMA-335 II.24.2.6 order, System.Reflection.Metadata reader parity over emitted
deltas, EncLog/EncMap correctness, stream layout, heap and index sizing,
multi-generation heap-offset chaining asserted against computed expected values,
standalone-signature rows asserted at baseline+1 from a real seeded baseline, and
serializer failure paths.
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 8, 2026
…ethod CDI emission

Adds an internal AbstractIL module implementing, byte for byte, the three Portable PDB
CustomDebugInformation blob formats Roslyn persists per method for Edit and Continue
(EnC Local Slot Map, EnC Lambda and Closure Map, EnC State Machine State Map), with
serializers, deserializers, a portable PDB read-back helper, and an occurrence-key
packing helper for deterministic syntax-offset slots.

Plumbs an optional methodCustomDebugInfoRows side channel through the IL binary writer
options into the portable PDB generator so a compilation can attach CDI rows to named
methods. Names that do not identify exactly one method row are dropped. All existing
writer call sites pass an empty map, so emitted PDBs are byte-identical to before.

No in-tree caller populates the map yet; the consumer is the F# hot reload work in
dotnet#19941, following the same pattern as dotnet#20017 (land isolated, test-covered
infrastructure first, wire the feature later).

Tests: blob round-trips, Roslyn golden-byte encodings, cross-validation against
CDI blobs emitted by a real Roslyn compilation, fail-closed occurrence-key packing
(including an int32-overflow regression where a wrapped negative key previously
escaped the bound check), and end-to-end synthetic PDB emission proving correct
MethodDef parenting, zero rows for an empty map, and no rows for absent or
ambiguous names.
@NatElkins
NatElkins force-pushed the fix-generated-name-counter-reset branch from 61aee61 to 39616ae Compare July 8, 2026 18:02

@T-Gro T-Gro left a comment

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 am wondering if a "reset" higher up would not make more sense, but I will revisit that once I see the integration with rest of the code.

@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Jul 9, 2026
@T-Gro
T-Gro merged commit 60d315a into dotnet:main Jul 9, 2026
50 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in F# Compiler and Tooling Jul 9, 2026
@majocha

majocha commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

It seems this state should really be kept per-project, maybe even cached by Transparent Compiler.

NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 17, 2026
…ethod CDI emission

Adds an internal AbstractIL module implementing, byte for byte, the three Portable PDB
CustomDebugInformation blob formats Roslyn persists per method for Edit and Continue
(EnC Local Slot Map, EnC Lambda and Closure Map, EnC State Machine State Map), with
serializers, deserializers, a portable PDB read-back helper, and an occurrence-key
packing helper for deterministic syntax-offset slots.

Plumbs an optional methodCustomDebugInfoRows side channel through the IL binary writer
options into the portable PDB generator so a compilation can attach CDI rows to named
methods. Names that do not identify exactly one method row are dropped. All existing
writer call sites pass an empty map, so emitted PDBs are byte-identical to before.

No in-tree caller populates the map yet; the consumer is the F# hot reload work in
dotnet#19941, following the same pattern as dotnet#20017 (land isolated, test-covered
infrastructure first, wire the feature later).

Tests: blob round-trips, Roslyn golden-byte encodings, cross-validation against
CDI blobs emitted by a real Roslyn compilation, fail-closed occurrence-key packing
(including an int32-overflow regression where a wrapped negative key previously
escaped the bound check), and end-to-end synthetic PDB emission proving correct
MethodDef parenting, zero rows for an empty map, and no rows for absent or
ambiguous names.
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 17, 2026
Adds an internal, standalone ECMA-335 Edit-and-Continue metadata delta writer to
AbstractIL: delta #- table stream and heap construction (DeltaMetadataTables,
DeltaMetadataSerializer, DeltaTableLayout, DeltaIndexSizing), ECMA-335 II.24.2.6
coded-index encoding (DeltaMetadataEncoding), EncLog/EncMap emission, generation GUID
chaining, user-string and standalone-signature token calculators (IlxDeltaStreams),
and the coordinating writer (FSharpDeltaMetadataWriter) over a plain row-description
input model (DeltaMetadataTypes, ILDeltaHandles, ILMetadataHeaps).

The writer's inputs are row records (names, tokens, signatures, RVAs) plus heap
offsets; it has no dependency on any semantic diffing or session machinery. It
compiles with no in-tree consumer by design: the consumer is the F# hot reload work
in dotnet#19941, following the same upstreaming pattern as dotnet#20017 and dotnet#20018
(land isolated, test-covered infrastructure first, wire the feature in a later PR).

One line of ilwrite.fsi is touched to expose the pre-existing markerForUnicodeBytes
so the delta writer reuses the exact string-marker logic of the full writer. No
behavior change for any existing code path.

Tests (130): coded-index encodings asserted against the production definitions and
ECMA-335 II.24.2.6 order, System.Reflection.Metadata reader parity over emitted
deltas, EncLog/EncMap correctness, stream layout, heap and index sizing,
multi-generation heap-offset chaining asserted against computed expected values,
standalone-signature rows asserted at baseline+1 from a real seeded baseline, and
serializer failure paths.
T-Gro pushed a commit that referenced this pull request Jul 22, 2026
* Add ResetCompilerGeneratedNameState to compiler-generated name generators (#20017)

Compiler-generated occurrence names (name@line-N) are allocated from process-wide
counters on CompilerGlobalState that accumulate across compilations. When a warm
checker re-emits the same project in-process, an unchanged closure therefore gets a
different occurrence suffix than the previous emit, so consumers that align generated
names across compilations (Edit-and-Continue delta emission, #19941)
cannot match them.

Add an internal ResetCompilerGeneratedNameState to NiceNameGenerator (clears the
per-(name, file) occurrence counters), StableNiceNameGenerator (clears the cached
stable names and the inner counters), and an aggregate on CompilerGlobalState that
resets all three generators, restoring the fresh-process name layout. Callers must
ensure no compilation is concurrently generating names.

No in-tree caller yet; the consumer is the hot reload emit path in #19941.
Covered by unit tests proving drift without reset, exact replay after reset, and that
the stable-name cache itself is cleared.

* Update dependencies from https://github.com/dotnet/msbuild build 20260709.10 (#20051)

On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-preview-26358-03 -> To Version 18.10.0-1.26359.10

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>

* Update dependencies from https://github.com/dotnet/arcade build 20260719.1
On relative base path root
Microsoft.DotNet.Arcade.Sdk From Version 11.0.0-beta.26330.1 -> To Version 11.0.0-beta.26369.1

* [main] Update dependencies from dotnet/msbuild (#20055)

* Update dependencies from https://github.com/dotnet/msbuild build 20260710.4
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26360.4

* Update dependencies from https://github.com/dotnet/msbuild build 20260713.4
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26363.4

* Update dependencies from https://github.com/dotnet/msbuild build 20260714.11
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26364.11

* Update dependencies from https://github.com/dotnet/msbuild build 20260715.6
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26365.6

* Update dependencies from https://github.com/dotnet/msbuild build 20260716.8
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26366.8

* Update dependencies from https://github.com/dotnet/msbuild build 20260717.5
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26367.5

* Update dependencies from https://github.com/dotnet/msbuild build 20260719.1
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26369.1

* Update dependencies from https://github.com/dotnet/msbuild build 20260720.18
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26370.18

---------

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>

* [main] Update dependencies from dotnet/roslyn (#20052)

* Update dependencies from https://github.com/dotnet/roslyn build 20260709.4
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26359.4

* Fix NU1605 package downgrades from Roslyn 5.10.0-1.26359.4 bump

The new Roslyn build adds a net472 dependency on Microsoft.VisualStudio.SDK
18.9.496-Preview and bumps its runtime deps to 10.0.8, causing package
downgrade errors:
- System.Collections.Immutable / System.Reflection.Metadata / System.Composition
  now required >= 10.0.8 (were pinned to 10.0.2)
- VS interops (OLE/Shell/TextManager.Interop) required >= 18.9.438
- Microsoft.VisualStudio.Threading required >= 18.7.19

The three interop packages are decoupled from the shared shell package
version since the VS SDK pins them newer than the other shell packages.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix MSB3277 assembly conflicts from new Roslyn VS SDK 18.9 deps

The new Roslyn Microsoft.CodeAnalysis.ExternalAccess.FSharp (net472) now
depends on Microsoft.VisualStudio.SDK 18.9.496 and its coherent 18.9.x VS
package set, pulling newer transitive assemblies than fsharp's 18.0.x Shell
packages. This caused MSB3277 (assembly version conflicts) across the
vsintegration projects for:
- System.Diagnostics.DiagnosticSource (10.0.2 vs 10.0.8)
- Microsoft.VisualStudio.Validation (17.13 vs 18.7.1)
- StreamJsonRpc (2.23 vs 2.26.5)
- Microsoft.ServiceHub.Framework (4.9 vs 4.10.128)
- Microsoft.VisualStudio.RpcContracts (17.15.25 vs 18.9.453)

Bump DiagnosticSource to 10.0.8 (coherent with the other runtime deps) and
pin the four remaining transitive packages to the exact versions Roslyn
pulls, so all vsintegration projects resolve them coherently.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix runtime VS assembly load failures in legacy VS unit tests

The Roslyn 5.10.0-1.26359.4 bump pulls Microsoft.VisualStudio.SDK 18.9.496 which transitively upgrades the editor assemblies (Microsoft.VisualStudio.Text.*, .Editor) to 18.9.123 and Shell.15.0 to 18.9.x. Two runtime-only breaks remained after the earlier NU1605/MSB3277 build-time fixes, both surfacing as a ReflectionTypeLoadException in the VsMocks MEF catalog that failed all ~1959 legacy VS unit tests:

1. Microsoft.VisualStudio.Platform.VSEditor is not pulled transitively, so it stayed pinned at 18.0.404-preview and its implementation types no longer bind against the newer Text.Internal 18.9.123 interfaces. Pin VSEditor to 18.9.123 to match.

2. Shell.15.0 18.9.x references Microsoft.VisualStudio.SolutionPersistence at runtime without declaring it as a NuGet dependency; deploy it next to the VS unit-test host (scoped to test projects to keep it out of the VSIX).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix flaky AOT CI build: pass -ci to disable UpdateXlfOnBuild

The Build_And_Test_AOT_Windows job runs '.\Build.cmd -pack' without -ci, so ContinuousIntegrationBuild is not set. Arcade then enables UpdateXlfOnBuild, which flakily fails with 'MSB4057: The target UpdateXlf does not exist' on FSharp.Core (the classic_metadata leg failed while the identical compressed_metadata leg passed). Every other CI job builds via CIBuildNoPublish.cmd/cibuild.sh, which pass -ci. Add -ci here for consistency so ContinuousIntegrationBuild=true and UpdateXlfOnBuild stays disabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update dependencies from https://github.com/dotnet/roslyn build 20260709.5
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26359.5

* Update dependencies from https://github.com/dotnet/roslyn build 20260713.9
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26363.9

* Update dependencies from https://github.com/dotnet/roslyn build 20260714.9
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26364.9

* Update dependencies from https://github.com/dotnet/roslyn build 20260715.2
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26365.2

* Update dependencies from https://github.com/dotnet/roslyn build 20260715.3
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26365.3

---------

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Localized file check-in by OneLocBuild Task: Build definition ID 499: Build ID 3013177 (#20023)

Co-authored-by: Copilot <copilot@github.com>

* Re-trigger CI (transient SignTool file-lock in WindowsCompressedMetadata_Desktop Batch1)

The prior build failed only in Batch1 with a SignTool 'file used by another
process' lock on FSharp.Compiler.Service...nupkg; the identical build+pack+sign
steps in Batch2 and Batch3 succeeded, so this is a transient signing race in the
Arcade SignTool, not a code regression.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Align System.* package versions with Maestro flow to fix NU1605

The main->feature/net11-scouting merge bumped Roslyn to 5.10.0-1.26365.3,
whose packages transitively require System.Collections.Immutable,
System.Composition and System.Reflection.Metadata >= 10.0.8. eng/Versions.props
re-pinned those (plus System.Diagnostics.DiagnosticSource) to 10.0.2 via
SystemPackagesVersion, overriding the 10.0.8 values that flow from dotnet/runtime
through Maestro in eng/Version.Details.props. Because that override is imported
after Version.Details.props, it won, producing 'Detected package downgrade ...
10.0.8 to 10.0.2' NU1605 errors across 36 projects and failing the build.

Remove the stale override so the Maestro-managed versions (10.0.8) are the single
source of truth, matching how main handles these packages.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Nat Elkins <nat@nelknet.com>
Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: dotnet bot <dotnet-bot@dotnetfoundation.org>
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 22, 2026
…ethod CDI emission

Adds an internal AbstractIL module implementing, byte for byte, the three Portable PDB
CustomDebugInformation blob formats Roslyn persists per method for Edit and Continue
(EnC Local Slot Map, EnC Lambda and Closure Map, EnC State Machine State Map), with
serializers, deserializers, a portable PDB read-back helper, and an occurrence-key
packing helper for deterministic syntax-offset slots.

Plumbs an optional methodCustomDebugInfoRows side channel through the IL binary writer
options into the portable PDB generator so a compilation can attach CDI rows to named
methods. Names that do not identify exactly one method row are dropped. All existing
writer call sites pass an empty map, so emitted PDBs are byte-identical to before.

No in-tree caller populates the map yet; the consumer is the F# hot reload work in
dotnet#19941, following the same pattern as dotnet#20017 (land isolated, test-covered
infrastructure first, wire the feature later).

Tests: blob round-trips, Roslyn golden-byte encodings, cross-validation against
CDI blobs emitted by a real Roslyn compilation, fail-closed occurrence-key packing
(including an int32-overflow regression where a wrapped negative key previously
escaped the bound check), and end-to-end synthetic PDB emission proving correct
MethodDef parenting, zero rows for an empty map, and no rows for absent or
ambiguous names.
NatElkins added a commit to NatElkins/fsharp that referenced this pull request Jul 22, 2026
Adds an internal, standalone ECMA-335 Edit-and-Continue metadata delta writer to
AbstractIL: delta #- table stream and heap construction (DeltaMetadataTables,
DeltaMetadataSerializer, DeltaTableLayout, DeltaIndexSizing), ECMA-335 II.24.2.6
coded-index encoding (DeltaMetadataEncoding), EncLog/EncMap emission, generation GUID
chaining, user-string and standalone-signature token calculators (IlxDeltaStreams),
and the coordinating writer (FSharpDeltaMetadataWriter) over a plain row-description
input model (DeltaMetadataTypes, ILDeltaHandles, ILMetadataHeaps).

The writer's inputs are row records (names, tokens, signatures, RVAs) plus heap
offsets; it has no dependency on any semantic diffing or session machinery. It
compiles with no in-tree consumer by design: the consumer is the F# hot reload work
in dotnet#19941, following the same upstreaming pattern as dotnet#20017 and dotnet#20018
(land isolated, test-covered infrastructure first, wire the feature in a later PR).

One line of ilwrite.fsi is touched to expose the pre-existing markerForUnicodeBytes
so the delta writer reuses the exact string-marker logic of the full writer. No
behavior change for any existing code path.

Tests (130): coded-index encodings asserted against the production definitions and
ECMA-335 II.24.2.6 order, System.Reflection.Metadata reader parity over emitted
deltas, EncLog/EncMap correctness, stream layout, heap and index sizing,
multi-generation heap-offset chaining asserted against computed expected values,
standalone-signature rows asserted at baseline+1 from a real seeded baseline, and
serializer failure paths.
T-Gro pushed a commit that referenced this pull request Jul 24, 2026
…ethod CDI emission (#20018)

* Add Roslyn-format EnC CustomDebugInformation codec and portable PDB method CDI emission

Adds an internal AbstractIL module implementing, byte for byte, the three Portable PDB
CustomDebugInformation blob formats Roslyn persists per method for Edit and Continue
(EnC Local Slot Map, EnC Lambda and Closure Map, EnC State Machine State Map), with
serializers, deserializers, a portable PDB read-back helper, and an occurrence-key
packing helper for deterministic syntax-offset slots.

Plumbs an optional methodCustomDebugInfoRows side channel through the IL binary writer
options into the portable PDB generator so a compilation can attach CDI rows to named
methods. Names that do not identify exactly one method row are dropped. All existing
writer call sites pass an empty map, so emitted PDBs are byte-identical to before.

No in-tree caller populates the map yet; the consumer is the F# hot reload work in
#19941, following the same pattern as #20017 (land isolated, test-covered
infrastructure first, wire the feature later).

Tests: blob round-trips, Roslyn golden-byte encodings, cross-validation against
CDI blobs emitted by a real Roslyn compilation, fail-closed occurrence-key packing
(including an int32-overflow regression where a wrapped negative key previously
escaped the bound check), and end-to-end synthetic PDB emission proving correct
MethodDef parenting, zero rows for an empty map, and no rows for absent or
ambiguous names.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants