Skip to content

Fix TypeLoadException in .NET 11 Preview 7 with DotNext threading - #134460

Merged
VSadov merged 4 commits into
mainfrom
copilot/fix-dotnet-11-preview7-typeloadexception
Sep 24, 2026
Merged

VSadov merged 4 commits into
mainfrom
copilot/fix-dotnet-11-preview7-typeloadexception

Conversation

Copilot AI commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Fixes a TypeLoadException ("does not have an implementation") thrown when loading a concrete type whose base hierarchy contains an abstract covariant Task → Task<T> override (the DotNext.Threading failure reported in the issue).

Root cause

For a covariant Task → Task<T> virtual override, MethodTableBuilder::EnumerateClassMethods synthesizes a third MethodDesc — a return-dropping thunk — whose void-returning signature MethodImpl-overrides the base's void-returning async variant. All three MethodDescs share the same metadata token, and MethodDesc::GetAttrs() reads attributes straight from metadata. When the covariant override is declared abstract, the synthesized thunk therefore also reports mdAbstract, even though EmitReturnDroppingThunk always emits a body (CALLVIRT to the T-returning async variant + POP + RET).

A concrete derived type's own Task<T> override matches the abstract declaration exactly, so no MethodImpl and no additional variant is created for it — nothing ever implements the inherited "abstract" thunk slot, and VerifyVirtualMethodsImplemented fails the type load.

Fix

MethodDesc::GetAttrs() now masks off mdAbstract for return-dropping thunks. Patching the single choke point keeps the VM, JIT (CORINFO_FLG_ABSTRACT), MayHaveNativeCode()/MayHavePrecode() and default-interface-method resolution consistent. Async variants are filtered out of reflection, so the adjusted attributes are not observable from managed code.

  • Analyze the issue and identify the root cause
  • Baseline build (./build.sh clr+libs -lc release -rc checked) + Core_Root layout
  • Reproduce the failure with a standalone repro (abstract covariant override fails, non-abstract passes)
  • Minimal VM fix in MethodDesc::GetAttrs()
  • Add regression test to src/tests/async/covariant-return/covariant-returns.cs (abstract covariant method override + abstract covariant property override, the get_Task shape from the issue)
  • Verify new tests fail without the fix (both throw the reported TypeLoadException)
  • Verify new tests pass with the fix and no async tests regress (144 passed / 0 failed)

Not verified: only linux-x64 Checked was built/tested; no test trees outside src/tests/async were run; parallel_validation produced no signal (code-review binary missing in the environment, CodeQL skipped both cpp and csharp for database size). The NativeAOT/crossgen2 path models this differently (CompilerTypeSystemContext.Async.cs wraps the resolved implementation in a ReturnDroppingAsyncThunk) and appears unaffected, but was reasoned about rather than tested; interface/DIM variants of this shape are likewise untested.

Resolves #132971

Note

This pull request description was generated by GitHub Copilot.

@azure-pipelines

azure-pipelines Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.

@VSadov
VSadov marked this pull request as ready for review September 22, 2026 23:39
Copilot AI lite review requested due to automatic review settings September 22, 2026 23:39
@VSadov

VSadov commented Sep 22, 2026

Copy link
Copy Markdown
Member

@copilot - does NativeAOT needs a separate fix for the same issue/test?

@VSadov

VSadov commented Sep 22, 2026

Copy link
Copy Markdown
Member

@copilot - the original repro mentions _ = typeof(DotNext.Threading.AsyncAutoResetEvent).Assembly.GetTypes();

can we have an additional repro scenario with a shape similar to that?
(make sure it fails on base and works with the fix)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Interface/default-interface-method coverage or justification remains unresolved.

Review effort: Lite
Findings: None

What changed in this PR

Fixes a CoreCLR TypeLoadException involving abstract covariant Task overrides.

Changes:

  • Masks mdAbstract on return-dropping thunks.
  • Adds method and property regression tests.
File Summary
src/​tests/​async/​covariant-return/​covariant-returns.cs Adds abstract covariant override coverage.
src/​coreclr/​vm/​method.cpp Corrects synthesized thunk attributes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

CoreCLR dispatch behavior and the reported assembly-enumeration path remain insufficiently covered.

Review effort: Balanced
Findings: None

Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 23, 2026 00:11

Copilot AI commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor Author

@copilot - does NativeAOT needs a separate fix for the same issue/test?

No separate NativeAOT fix is needed. NativeAOT resolves the async slot to the concrete override first and then wraps that resolved implementation in ReturnDroppingAsyncThunk, rather than inheriting CoreCLR’s synthesized abstract thunk slot. I also built and ran the full covariant-return test as a standalone NativeAOT executable; it passed with exit code 100.

@copilot - the original repro mentions _ = typeof(DotNext.Threading.AsyncAutoResetEvent).Assembly.GetTypes();

can we have an additional repro scenario with a shape similar to that?
...

Added typeof(Program).Assembly.GetTypes() coverage in commit 468102c. The filtered test fails without the VM fix with ReflectionTypeLoadException/TypeLoadException (“Method 'M1' ... does not have an implementation”) and passes with the fix. The full test also passes under CoreCLR and NativeAOT.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

A critical interface thunk layout issue remains unresolved and requires additional coverage.

Review effort: Balanced
Findings: 1 High severity

Open (1)

Comment thread src/coreclr/vm/method.cpp
Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 23, 2026 15:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The unresolved moderate consistency concern and limited validation warrant final human review.

Review effort: Balanced
Findings: 1 High severity

Open (1)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The low-level runtime change had limited platform and scenario validation.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@VSadov VSadov changed the title [WIP] Fix TypeLoadException in .NET 11 Preview 7 with DotNext threading Fix TypeLoadException in .NET 11 Preview 7 with DotNext threading Sep 23, 2026
@VSadov

VSadov commented Sep 23, 2026

Copy link
Copy Markdown
Member

@jakobbotsch - could you take a look at this PR

@VSadov
VSadov merged commit f3fc53d into main Sep 24, 2026
117 of 120 checks passed
@VSadov
VSadov deleted the copilot/fix-dotnet-11-preview7-typeloadexception branch September 24, 2026 16:24
@VSadov

VSadov commented Sep 25, 2026

Copy link
Copy Markdown
Member

/backport to release/11.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/11.0 (link to workflow run)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET 11 Preview 7 Unexpectedly Throws TypeLoadException

4 participants