Skip to content

[naot] [Runtime async] Support for covariant override of Task -> Task<T>#126768

Merged
eduardo-vp merged 18 commits intodotnet:mainfrom
eduardo-vp:asyncCov-naot
Apr 21, 2026
Merged

[naot] [Runtime async] Support for covariant override of Task -> Task<T>#126768
eduardo-vp merged 18 commits intodotnet:mainfrom
eduardo-vp:asyncCov-naot

Conversation

@eduardo-vp
Copy link
Copy Markdown
Member

Mirrors work in #125900 for Native AOT.

Fixes #126685.

Copilot AI review requested due to automatic review settings April 10, 2026 21:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Mirrors the CoreCLR runtime-async fix for covariant overrides (Task base overridden by Task<T> derived) into the NativeAOT type system by introducing a return-dropping async thunk and wiring it into virtual/interface resolution, and re-enables the previously NativeAOT-disabled test.

Changes:

  • Add ReturnDroppingAsyncThunk and a corresponding IL stub emitter that calls the T-returning async variant and discards the result.
  • Update NativeAOT async-aware virtual/interface method resolution to select the return-dropping thunk when the async slot is void-returning but the resolved override is T-returning.
  • Re-enable the covariant-return async test project for NativeAOT.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/tests/async/covariant-return/covariant-returns.csproj Re-enables building the test under NativeAOT.
src/coreclr/vm/asyncthunks.cpp Adds a comment noting parity with the managed type system emitter.
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncThunks.cs Adds IL emission for the return-dropping async thunk.
src/coreclr/tools/Common/TypeSystem/IL/NativeAotILProvider.cs Routes ReturnDroppingAsyncThunk to the new IL emitter.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.cs Wraps resolved async variants with a return-dropping thunk for Task -> Task<T> async-slot mismatches; adds caching.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.Mangling.cs Adds prefix mangling support for ReturnDroppingAsyncThunk.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs Introduces ReturnDroppingAsyncThunk type and updates async-thunk classification helpers.

Comment thread src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncThunks.cs
Comment thread src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncThunks.cs
Comment thread src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

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

Comment thread src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs Outdated
Comment thread src/coreclr/tools/Common/Compiler/AsyncMethodVariant.Mangling.cs Outdated
Comment thread src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs
Comment thread src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncThunks.cs
Comment thread src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncThunks.cs
Comment thread src/tests/async/covariant-return/covariant-returns.csproj
Copilot AI review requested due to automatic review settings April 13, 2026 20:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread src/tests/async/covariant-return/covariant-returns.cs
@MichalStrehovsky
Copy link
Copy Markdown
Member

PR feedback except fix, let the CI fail with the error

CI is not failing because the test is still disabled (I assume there was a merge conflict with the R2R disablement)

@eduardo-vp
Copy link
Copy Markdown
Member Author

eduardo-vp commented Apr 14, 2026

CI is not failing because the test is still disabled (I assume there was a merge conflict with the R2R disablement)

Ah yes, I locally updated the project and tested the native aot compiled test.

Copilot AI review requested due to automatic review settings April 14, 2026 00:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Comment thread src/coreclr/vm/asyncthunks.cpp
Comment thread src/tests/async/covariant-return/covariant-returns.cs
Comment thread src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.cs Outdated
Copilot AI review requested due to automatic review settings April 20, 2026 11:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericMethodsHashtableNode.cs:127

  • GenericMethodsHashtableNode.GetMethodForMetadata currently asserts that the typical method definition is not a ReturnDroppingAsyncThunk and always returns isReturnDroppingAsyncThunk = false. This makes the new GenericMethodsHashtableConstants.IsReturnDroppingAsyncThunk flag effectively unreachable for generic-method dictionary lookups and will either trip the debug assert or prevent the runtime from finding dictionary entries for return-dropping async thunks (e.g., in generic covariant-return/GVM scenarios). Update this helper to unwrap ReturnDroppingAsyncThunk the same way as NativeLayoutVertexNode/ExactMethodInstantiationsNode (set the flag and return the underlying target method for metadata).
        private static MethodDesc GetMethodForMetadata(MethodDesc method, out bool isAsyncVariant, out bool isReturnDroppingAsyncThunk)
        {
            MethodDesc result = method.GetTypicalMethodDefinition();
            Debug.Assert(!(result is ReturnDroppingAsyncThunk));
            isReturnDroppingAsyncThunk = false;
            if (result is AsyncMethodVariant asyncVariant)
            {
                isAsyncVariant = true;
                return asyncVariant.Target;
            }
            isAsyncVariant = false;
            return result;

@eduardo-vp
Copy link
Copy Markdown
Member Author

Given the latest commits, it looks like generic virtual methods are failing on CoreCLR. If the changes for Native AOT look fine, should we file an issue and disable the test?

@VSadov
Copy link
Copy Markdown
Member

VSadov commented Apr 21, 2026

Given the latest commits, it looks like generic virtual methods are failing on CoreCLR. If the changes for Native AOT look fine, should we file an issue and disable the test?

        // If this assert fires, we may just need to add a lookup that matches AsyncMethodFlags::ReturnDroppingThunk
        // It does not look like there is a scenario for directly calling ReturnDroppingThunk right now.
        _ASSERTE(!pPrimaryMD->IsReturnDroppingThunk());

It looks like we found a scenario involving GVM where we need to lookup for a return dropping thunk.

Yes, log an issue and disable the test on CorCLR.

@MichalStrehovsky
Copy link
Copy Markdown
Member

This will break the following program (that worked before the PR):

class Program
{
    interface IFoo
    {
        Task<int> AsyncInterfaceMethod<T>();
    }

    class Foo : IFoo
    {
        async Task<int> IFoo.AsyncInterfaceMethod<T>()
        {
            await Task.Yield();
            return typeof(T).FullName.Length;
        }
    }

    static async Task Main()
    {
        IFoo f = new Foo();
        int x = await f.AsyncInterfaceMethod<object>();
        Console.WriteLine(x);
    }
}

We should add this test and fix the bug (the bug is that the logic that chooses return-dropping thunk in System.Private.TypeLoader doesn't match the logic in the compiler in WrapAsAsyncVariant).

Comment thread src/tests/async/covariant-return/covariant-returns.cs Outdated
Copilot AI review requested due to automatic review settings April 21, 2026 07:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.

@eduardo-vp
Copy link
Copy Markdown
Member Author

/azp run runtime-nativeaot-outerloop

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Comment thread src/coreclr/tools/Common/Internal/Runtime/RuntimeConstants.cs Outdated
Co-authored-by: Michal Strehovský <MichalStrehovsky@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 21, 2026 17:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.

@eduardo-vp eduardo-vp merged commit 1ee309e into dotnet:main Apr 21, 2026
117 of 119 checks passed
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.

Covariant returns with runtime async

4 participants