Skip to content

Intern provided namespaces to fix parallel-compilation resolution race#20021

Open
T-Gro wants to merge 2 commits into
dotnet:mainfrom
T-Gro:t-gro-intern-provided-namespaces
Open

Intern provided namespaces to fix parallel-compilation resolution race#20021
T-Gro wants to merge 2 commits into
dotnet:mainfrom
T-Gro:t-gro-intern-provided-namespaces

Conversation

@T-Gro

@T-Gro T-Gro commented Jul 2, 2026

Copy link
Copy Markdown
Member

Fixes #20020

Under graph-based (parallel) type checking, the namespace entities on a
provided type's path were appended non-atomically and deduplicated with a
racy check-then-act, so concurrent linking from multiple files could build
disjoint namespace subtrees and strand provided types (spurious FS0001 /
FS0039). Namespace entities are now interned and appended with the same
lock-free CAS design already used for provided-type entities.

The compute-once ConcurrentDictionary<_, Lazy<_>> idiom the interning
relies on is factored into a shared GetOrAddLazy helper and reused by the
existing name-generation and codegen caches.

@github-actions

github-actions Bot commented Jul 2, 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

@github-actions github-actions Bot added ⚠️ Affects-Design-Time Tooling check: PR touches type providers or dependency manager ⚠️ Affects-Compiler-Output Tooling check: PR touches IL emission or codegen labels Jul 2, 2026
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🔍 Tooling Safety Check — Affects-Compiler-Output, Affects-Design-Time
Affects-Compiler-Output: modifies TypedTree type resolution and NonLocalEntityRef paths
Affects-Design-Time: changes type provider namespace injection infrastructure

Generated by PR Tooling Safety Check · opus46 5M ·

Follow-up to dotnet#19969, which interned provided *type* entities behind a
lock-free CAS append + entitiesVersion design. The namespace entities on a
provided type's path never got the same treatment: AddModuleOrNamespaceByMutation
appended non-atomically (losing updates that race AddProvidedTypeEntity's CAS
append) and the two namespace-materialization sites deduped with a non-atomic
check-then-act, so two threads could each build a disjoint namespace subtree and
strand the provided types interned under the orphan (spurious FS0001/FS0039).

Make the namespace append atomic (shared AppendEntityByMutation CAS loop) and
add GetOrInternNamespaceEntity, reusing the single providedEntitiesByMangledName
intern table (one mangled name -> one entity per parent). Its factory reuses any
pre-existing module/namespace of that name before creating, so a provider
extending a real namespace no longer forks a duplicate. Both injection sites route
through it. modulesByDemangledNameCache is now version-stamped since namespace
appends can run concurrently with ModulesAndNamespacesByDemangledName reads.

Fixes dotnet#20020

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@T-Gro T-Gro force-pushed the t-gro-intern-provided-namespaces branch from b9d2f04 to 7986396 Compare July 2, 2026 12:47
…o sites

The provided-entity interning added for dotnet#20020 hand-rolled the
ConcurrentDictionary<_, Lazy<_>> + GetOrAdd(key, fun _ -> lazy f).Value
compute-once idiom that already recurs in StableNiceNameGenerator,
AnonTypeGenerationTable and the FSI xmlDoc cache. Factor it into a single
GetOrAddLazy extension in illib and route all four sites through it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@T-Gro T-Gro requested a review from abonie July 3, 2026 09:13
@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚠️ Affects-Compiler-Output Tooling check: PR touches IL emission or codegen ⚠️ Affects-Design-Time Tooling check: PR touches type providers or dependency manager

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Provided types under a provided namespace intermittently fail to resolve under parallel compilation

2 participants