Skip to content

Restore legacy cross-assembly inline metadata - #20260

Open
T-Gro wants to merge 14 commits into
dotnet:mainfrom
T-Gro:t-gro-fix-cross-assembly-srtp-release
Open

Restore legacy cross-assembly inline metadata#20260
T-Gro wants to merge 14 commits into
dotnet:mainfrom
T-Gro:t-gro-fix-cross-assembly-srtp-release

Conversation

@T-Gro

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

Copy link
Copy Markdown
Member

Fixes #20253

F# 4.7 and earlier encoded required inline values with flag bits now used by InlinedDefinition, causing newer compilers to emit calls to dynamic-invocation stubs. Normalize legacy flags while importing metadata.

T-Gro and others added 10 commits August 13, 2026 20:25
Regression fixture: LegacyInline.dll built with .NET SDK 10.0.105
(F# compiler without ValInline.InlinedDefinition). That compiler used
the pre-InlinedDefinition encoding where ValInline.Always = 0x00 bits.

The current compiler reads 0x00 as InlinedDefinition (ShouldInline=false).
With --optimize-, crossAssemblyOpt() returns false and ShouldInline=false,
so the body is never fetched; the optimizer emits a direct IL call instead
of the inlined form expected for an `inline` function.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Replace the arithmetic-only `increment` fixture with a cross-assembly
inline SRTP function whose compiled (non-inlined) fallback body is the
compiler-generated "Dynamic invocation of Invoke is not supported"
placeholder, matching the shape of the real-world regression (issue
20253, Aether's op_HatEquals). LegacyInline.dll is regenerated from the
updated LegacyInline.fs with the official .NET SDK 10.0.105 F# compiler.

The test now exercises Release/optimized codegen (withOptimize) and
compiles+runs the consumer, asserting no direct call to the placeholder
remains in the imported IL.

Note: exhaustive testing against SDK 10.0.100/10.0.105/10.0.203/10.0.301
shows none of these official compilers actually emit the ambiguous
zero-bit ValInline encoding for this shape (SRTP trait resolution and
witness-passing both resolve the call at the consumer's type-check time,
independent of the ShouldInline metadata bit), so this fixture does not
currently reproduce a failing run against HEAD. It does correctly
validate the cross-assembly SRTP import path and regresses if a future
change reintroduces a direct call to the placeholder body.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Build LegacyInline.dll with the official .NET SDK 3.1.100 F# compiler (10.7.0.0 for F# 4.7), which predates witness metadata and preserves the legacy inline encoding.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Refactor Issue 20253 test to focus on IL verification, removing runtime
execution that doesn't contribute to the regression contract. The test
now compiles as a library and verifies that the legacy inline metadata
from LegacyInline.dll is properly inlined, preventing the direct call
to LegacyInline.Library::invoke from appearing in the emitted IL.

This change:
- Simplifies Consumer module from EntryPoint program to library function
- Removes runtime execution verification (run | shouldSucceed | verifyOutputContains)
- Retains compile success verification (shouldSucceed)
- Maintains IL regression assertion (verifyILNotPresent [ "LegacyInline.Library::invoke" ])

The IL assertion is the actual regression contract for this issue.

Co-authored-by: Copilot <copilot@example.com>
u_ValData deserialized ValFlags directly from the pickled int64, so
DLLs written by compilers <= 4.7 (pre-witness), which encoded
PseudoVal/Always inline info as all-zero inline bits, were imported as
ValInline.InlinedDefinition after PR dotnet#19548 repurposed the same 0x00
bits for that case. Add ValFlags.OfPickledBits, mirroring the
InlinedDefinition -> Always normalization PickledBits already applies
on write, and use it in u_ValData so legacy zero-bit values import as
Always (ShouldInline=true) regardless of which compiler wrote them.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Compile the Issue 20253 consumer out-of-process via runFscProcess
instead of CompilerAssert.CompileRaw in-process. The in-process path
can mutate shared compiler/import state across tests sharing the same
process, so keep this legacy pre-witness FSharp.Core regression check
at the IL boundary without touching the test host's own state.

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

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

T-Gro and others added 3 commits August 13, 2026 22:14
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d9bb5fd2-ae26-4369-934d-1bae177a1266
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d9bb5fd2-ae26-4369-934d-1bae177a1266
@T-Gro

T-Gro commented Aug 14, 2026

Copy link
Copy Markdown
Member Author

cc @auduchinok

@T-Gro
T-Gro requested review from abonie and auduchinok August 14, 2026 10:52
@T-Gro
T-Gro marked this pull request as ready for review August 14, 2026 10:53
@T-Gro
T-Gro requested a review from a team as a code owner August 14, 2026 10:53
@github-actions github-actions Bot added the ⚠️ Affects-Compiler-Output Tooling check: PR touches IL emission or codegen label Aug 14, 2026
@github-actions

This comment has been minimized.

@auduchinok

Copy link
Copy Markdown
Member

@T-Gro Thanks for fixing it!

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

Copilot-Session: d9bb5fd2-ae26-4369-934d-1bae177a1266
@github-actions github-actions Bot added the ⚠️ Affects-Agent-Config Tooling check: PR modifies AI agent instructions or workflows label Aug 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Tooling Safety Check — Affects-Agent-Config, Affects-Compiler-Output
Affects-Agent-Config: modifies .github/instructions/TypedTreePickle.instructions.md
Affects-Compiler-Output: changes metadata import flag normalization in TypedTree/TypedTreePickle

Generated by PR Tooling Safety Check · opus46 3.1M ·

@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚠️ Affects-Agent-Config Tooling check: PR modifies AI agent instructions or workflows ⚠️ Affects-Compiler-Output Tooling check: PR touches IL emission or codegen

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

SDK 10.0.400 regression: cross-assembly inline SRTP call throws in Release

3 participants