Skip to content

Parallel compilation fix for TP SDK - #20102

Open
Thorium wants to merge 1 commit into
dotnet:mainfrom
Thorium:parallel-compilation-fix
Open

Parallel compilation fix for TP SDK#20102
Thorium wants to merge 1 commit into
dotnet:mainfrom
Thorium:parallel-compilation-fix

Conversation

@Thorium

@Thorium Thorium commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Description

This is a ported from https://github.com/fsprojects/FSharp.TypeProviders.SDK

Fixes #20060

@Thorium

Thorium commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

As far as I understand this goes under "tests" so there is nothing to release, for "release notes".

@github-actions github-actions Bot added the AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files label Jul 30, 2026

@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.

🤖 This review was generated by AI (@expert-reviewer agent). Findings may contain inaccuracies — please verify independently.

This is a faithful port of the parallel-compilation fixes from FSharp.TypeProviders.SDK into the test-data type provider. Overall it looks correct. I traced the new two-lock design and believe it is deadlock-free: typeTablesLock is only ever held for table lookups and target-type shell creation (never while realizing members), while member realization takes realizationLock first and only then reaches into typeTablesLock via convMemberDefToTgt. So the acquisition order is consistently realizationLock → typeTablesLock. Two low-severity observations below — neither is blocking.

type ILPropertyDefs(larr: Lazy<ILPropertyDef[]>) =
let lmap = lazy (
let d = Dictionary<string, ILPropertyDef>()
for p in larr.Force() do d.[p.Name] <- p

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.

Behavioral change worth confirming: the new dictionary-based TryFindByName uses last-wins (d.[p.Name] <- p), whereas the previous Entries |> Array.tryFind (fun md -> md.Name = name) returned the first matching entry. For IL properties this differs when a type has name-overloaded members (e.g. an indexer Item with multiple index-parameter signatures): GetPropertyImpl(name, ...) will now resolve to the last such property instead of the first. The same first→last shift applies to the analogous field/event/nested-type dict lookups. In practice fields/events/nested types can't share a name, so only overloaded properties are affected; likely harmless for the test providers here, but flagging in case any test relies on the previously-returned member.

// same type's realization on the same thread is fine. The queue writers (AddMember et al.) stay
// unlocked by design: they run either during provider construction, before the compiler observes
// the type, or from a delayed factory that already holds this lock via realization.
let realizationLock = obj()

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.

The correctness of this two-lock scheme depends on a strict acquisition order: realizationLock (this per-type lock) must always be taken before the context-wide typeTablesLock, never the reverse. That invariant holds today because typeTablesLock is only held for table lookups and target-type shell creation, and the getFreshMethods/GetMembersFromCursor factories acquire the source type's realizationLock before calling convMemberDefToTgt (which reaches typeTablesLock). Worth a short comment recording this ordering invariant, since a future edit that realizes members (e.g. calls getMembers/GetMethods) while holding typeTablesLock would introduce an AB–BA deadlock under ParallelCompilation.

@T-Gro
T-Gro self-requested a review August 3, 2026 19:18
@T-Gro T-Gro added the AI-reviewed PR reviewed by AI review council label Aug 3, 2026

@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.

Approving as this is just porting reality to our copy in tests.

@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Aug 13, 2026
@T-Gro
T-Gro enabled auto-merge (squash) August 13, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-reviewed PR reviewed by AI review council AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

The new dotnet SDK ParallelCompilation=true causing issues in TypeProviders

2 participants