Skip to content

await in a static dynamic call materializes the call site's typeof marker as the receiver #4018

Description

@christophwille

When a dynamic argument list containing an await is passed to a static method, the call site's typeof(TargetType) marker is materialized as a receiver variable, and the static call is rewritten as an instance call on that Type.

Input

public async Task DynamicAwaitInStaticCall(dynamic value)
{
	Console.WriteLine("x" + await value);
}

Actual output

public async Task DynamicAwaitInStaticCall(dynamic value)
{
	Type typeFromHandle = typeof(Console);
	typeFromHandle.WriteLine("x" + await value);
}

This is CS1061 (Type has no WriteLine).

Expected output

public async Task DynamicAwaitInStaticCall(dynamic value)
{
	Console.WriteLine("x" + await value);
}

Notes

The await is what triggers it. Both of these round-trip correctly:

  • the same call without the await (Console.WriteLine("x" + value))
  • the same await in a dynamic instance call

For a static dynamic call, Roslyn passes typeof(Console) to the call site as the target-type marker. Without a suspension point that ldtoken/GetTypeFromHandle pair stays inline and is recognized; the state-machine split hoists it into its own local first, and the dynamic-call transform then treats the local as an ordinary receiver.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions