Repository navigation
Fix intermittent FS0073 under parallel optimization: leave type definitions untouched in TLR pass 5 - #20879
Open
majocha wants to merge 3 commits into
Open
Fix intermittent FS0073 under parallel optimization: leave type definitions untouched in TLR pass 5#20879majocha wants to merge 3 commits into
majocha wants to merge 3 commits into
Conversation
… bounds TLR pass 5 (RecreateUniqueBounds) runs copyImplFile with OnlyCloneExprVals. In that mode copyTycon returns each tycon itself, yet copyAndRemapAndBindTyconsAndVals still rebound its typars and rewrote entity_typars, then entity_tycon_repr and the rest, in place. Under parallel optimization, file i's TLR runs while file i+1's first optimization loop reads file i's types. A reader between the two writes saw new typars next to field types over the old ones, so tyOfExpr of a field get could not substitute them and leaked the declaration's typar into a member body. IlxGen then reported FS0073 "Undefined or unsolved type variable", or, since the GenTypeAux fallback, silently emitted the typar as obj. Under OnlyCloneExprVals the tycons are no longer rewritten; only the module type is re-pointed at copied vals. Fixes dotnet#20812
T-Gro
self-requested a review
November 2, 2026 12:23
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #20812.
Cause
Lambda lifting ends with pass 5,
RecreateUniqueBounds=copyImplFile g OnlyCloneExprVals. In that modecopyTyconreturns each tycon itself, yetcopyAndRemapAndBindTyconsAndValsstill rebound the tycon's typars and rewrote it in place:entity_typarsfirst, thenentity_tycon_repr, the augmentation, attributes, abbreviation and exception info in separate writes.Under parallel optimization, node (file i, phase p) waits only for (i, p-1) and (i-1, p), so file i's TLR runs while file i+1's first optimization loop reads file i's types. A reader between the two writes sees
SeqOps<'C#new>whose field still has typeseq<int> -> 'C#old.tyOfExprofops.OfSeqcannot substitute'C, the declaration's typar ends up in anExpr.Apptype of the member body, and IlxGen does not find it in the method'sTypeReprEnv:FS0073 Undefined or unsolved type variable: 'C.GenTypeAuxfallback (Fix internal error FS0073 w/nested inline SRTP and multiple overloads #19710), reached from closure generic arguments since Ship FSharp.Core with a net10.0 target framework #20229, defaults it toobjand emits wrong IL with no error. It is visible with--warnon:3559as FS3559 at the declaration of'C.Under
OnlyCloneExprValsthe rewrite has no purpose, since tycons and member/module vals are not copied. Its only effect was to swap the declaration's typars for copies on an object every later file references.Change
Under
OnlyCloneExprValsthe tycons are left untouched; only the module type is re-pointed at copied vals, as before. The other copy modes are unchanged.As a side effect,
FSharpCheckProjectResults.GetOptimizedAssemblyContents()with--optimize+no longer rewrites the checked entities that FCS symbols hold.Testing
New FCS test
Issue 20812 - optimization leaves the type parameters of checked type definitions untouched(ExprTests): it runs single-threaded and needs no timing. It fails before the change and passes after.A repro in the shape of the issue (a chain of 12 generic contract classes over a record of functions,
--optimize+ --deterministic+), compiled in a loop on the same base commit:Sequential output is unchanged.
With the SDK 10.0.403 compiler, isolating each parallel stage: graph checking alone failed 0 of 100 builds, parallel optimization alone failed 6 of 51.
After a clean
Build.cmd -c Release: ComponentTests EmittedIL 1660/1660 (3 skipped), optimizer tests 36/36,DeterministicTests26/26,ExprTests114/114.Not in this PR
This is one instance of later optimizer phases mutating typed-tree objects that other files' concurrent phases can read. Follow-ups worth considering:
GenTypeAuxfallback to the codegen-fresh inference typars of Internal error FS0073 "Undefined or unsolved type variable" with nested inline SRTP and multiple overloads #19709, so this class of bug fails with an internal error again instead of silently producing wrong IL.🤖 Generated with Claude Code