Skip to content

Fix InvalidProgramException from Seq.collect over a struct seq materialised with List.ofSeq/Seq.toList/Seq.toArray - #20227

Open
T-Gro wants to merge 3 commits into
mainfrom
fix/issue-20203
Open

Fix InvalidProgramException from Seq.collect over a struct seq materialised with List.ofSeq/Seq.toList/Seq.toArray#20227
T-Gro wants to merge 3 commits into
mainfrom
fix/issue-20203

Conversation

@T-Gro

@T-Gro T-Gro commented Aug 6, 2026

Copy link
Copy Markdown
Member

Fixes #20203

open System.Collections.Immutable
// ImmutableArray<_> is a struct that implements seq<'T>
let xs = ImmutableArray.Create(1, 2, 3)
let result = [ yield! xs ]   // or List.ofSeq (Seq.collect id ...)
// before (Release only): System.InvalidProgramException at runtime
// after: works

The comprehension lowering fed a struct (value-type) sub-collection straight into ListCollector/ArrayCollector.AddMany, which expects a reference seq<'T>, and typed the generated try/finally with the original struct body type. That produced invalid IL — a value type where a reference IEnumerable was expected, plus a spurious ldnull stored into a struct local. The struct sub-collection is now coerced (boxed) to seq<'T> and the try/finally result type is unit.

Copilot and others added 3 commits August 6, 2026 15:28
…aterialised with List.ofSeq/Seq.toList/Seq.toArray (#20203)

Two codegen defects in LowerComputedListOrArraySeqExpr only manifested when the inner sub-collection is a value type implementing seq<'T> (e.g. ImmutableArray<_>), since a struct is never implicitly upcast:

1. The arbitrary sub-collection was passed to ListCollector.AddMany/AddManyAndClose(seq<'T>) with no coercion, emitting invalid IL (value type where a ref IEnumerable is expected). Now coerced to the collector's seq<'T> element type (GenCoerce emits box; unbox.any for structs, nothing for reference upcasts).

2. SeqUsing/SeqForEach/SeqTryFinally built mkTryFinally with the original (possibly struct) body type as the try/finally result type instead of unit, so the optimizer emitted ldnull; stloc <struct> - invalid IL. Now uses g.unit_ty.

Adds hermetic execution regression tests under optimizations.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nbox.any for #20203

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

github-actions Bot commented Aug 6, 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:

Warning

No PR link found in some release notes, please consider adding it.

Change path Release notes path Description
`src/Compiler` docs/release-notes/.FSharp.Compiler.Service/11.0.100.md No current pull request URL (#20227) found, please consider adding it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

Release-only InvalidProgramException: Seq.collect over a struct collection (ImmutableArray) materialised with List.ofSeq

1 participant