Intermittent FS1116/FS1118 "Failed to inline the value 'Source'" for cross-assembly overloaded inline members under parallel compilation
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 144
Description
Intermittent, non-deterministic FS1116 + FS1118 ("Failed to inline the value 'Source'") when compiling code that consumes an **overloaded `inline` member defined in a referenced assembly**, on **identical inputs and identical compiler bits**. The optimizer intermittently fails to find the cross-assembly optimization data for the inline value, treats it as `UnknownValue`, and errors out.
This looks like the same family as the closed parallel-compilation determinism issues #19969 (same entity checked into separate identities under parallel compilation) and #19928.
**Repro steps**
Not reliably reproducible on demand — it is a timing-sensitive race that so far reproduces only on Windows CI agents. Observed environment:
1. Build the F# compiler for `net11.0` (running the compiler itself on the .NET 11 runtime).
2. With that compiler, `dotnet build -c Release` [FsToolkit.ErrorHandling](https://github.com/demystifyfp/FsToolkit.ErrorHandling) at commit `a7119caabe329817bee49d7094610c45db7725c1`.
3. Compiling `tests/FsToolkit.ErrorHandling.Tests/TaskValidationCE.fs` (line 60, `Async.singleton …` flowing through the builder's overloaded `inline` SRTP `Source` members defined in the referenced `FsToolkit.ErrorHandling.dll`) intermittently fails:
```
TaskValidationCE.fs(60,56): error FS1116: The value 'Source' was marked inline but was not bound in the optimization environment
TaskValidationCE.fs(60,56): error FS1118: Failed to inline the value 'Source'
```
**Evidence that this is non-determinism (not a code defect in the input):**
- Two CI builds on the **identical merge commit** produced different results: one **succeeded**, the next **failed** with the above. Same pinned FsToolkit commit, same compiler artifacts.
- The failure is **Release-only** — the Debug leg and the referenced-library build succeeded in both runs.
- Reproduced 0/55 times locally on macOS (40 consumer-only rebuilds + 15 clean full-`Release` rebuilds), consistent with a Windows core-count/scheduler timing race.
**Expected behavior**
Compilation is deterministic: given identical inputs and compiler bits, a cross-assembly overloaded `inline` member resolves its optimization data every time, or fails every time — never intermittently.
**Actual behavior**
The optimizer intermittently cannot find the cross-assembly optimization data for the overloaded `inline` value and raises FS1116/FS1118.
**Analysis / likely mechanism**
- Cross-assembly inline lookup goes through `Optimizer.GetInfoForNonLocalVal` → `TryGetInfoForNonLocalEntityRef` → `ValInfos.TryFind`, which keys on physical value identity (`ValHash` by `Val.Stamp`). A miss yields `UnknownValInfo` → `UnknownValue`; for a `ShouldInline` value that is FS1116 (warning) + FS1118 (fatal) at the consumer.
- The default compiler pipeline runs Graph-based (parallel) type-checking, parallel optimization and parallel IlxGen. Under parallel scheduling, an overloaded `inline` member (`Source`) can end up with a different physical `Val` identity between the type-checked reference and the imported optimization data, so the stamp-keyed lookup intermittently misses. This matches the identity-mismatch root cause fixed in #19969.
- The optimizer code path here is unchanged from `main`; the .NET 11 upgrade (compiler running on the net11 runtime) only perturbs scheduling enough to expose the latent race, which is why it currently shows up only on that configuration's regression leg.
**Known workarounds**
Re-running the compilation succeeds (the failure is rare). Forcing sequential compilation (`--parallelcompilation-`) is the expected mitigation and would also confirm the parallel-pipeline root cause.
**Related information**
- OS where observed: Windows (CI agents). Not reproduced on macOS.
- .NET Runtime kind: .NET (compiler hosted on the .NET 11 runtime).
- Related: #19969, #19928; diagnostics FS1113/FS1114/FS1116/FS1118 (see also #1565).
Contributor guide
Research direction
Start with Optimizer.GetInfoForNonLocalVal, TryGetInfoForNonLocalEntityRef, and ValInfos.TryFind, then reproduce the failure by building FsToolkit.ErrorHandling and compiling tests/FsToolkit.ErrorHandling.Tests/TaskValidationCE.fs. Compare parallel compilation with --parallelcompilation- and investigate whether the overloaded Source value gets different identities. Done means identical inputs produce deterministic results without FS1116/FS1118.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fsharp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100