Skip to content

Do not report MA0214 on functions returning only completed tasks - #1372

Merged
meziantou merged 1 commit into
mainfrom
feature/meziantou-analyzer-1371-2442e3
Sep 3, 2026
Merged

meziantou merged 1 commit into
mainfrom
feature/meziantou-analyzer-1371-2442e3

Conversation

@meziantou

Copy link
Copy Markdown
Owner

Fixes #1371

What

MA0214 (Use 'await' instead of returning the task) no longer reports a function when every return produces an already-completed task:

Task FooAsync() => Task.CompletedTask;          // no longer reported
Task<bool> BarAsync() => Task.FromResult(false); // no longer reported

Completed tasks recognized: Task.CompletedTask / ValueTask.CompletedTask, Task/ValueTask FromResult, FromException, FromCanceled, new ValueTask(), and new ValueTask<T>(value).

Functions that mix a completed task with a real task are still reported on every return:

Task<bool> BarAsync(bool condition) => condition ? OtherAsync() : Task.FromResult(false); // still reported

Why

These are "bridging methods", e.g. implementing an asynchronous interface synchronously. Awaiting the task there brings no accuracy to the stack trace and only adds a state machine, so the rule was making the code worse.

Notes for the reviewer

  • The detection of completed tasks already existed inside AwaitTaskBeforeDisposingResourcesAnalyzer (MA0100). It moved to AwaitableTypes.IsCompletedTask and both rules now share it; MA0100 behavior is unchanged (its four now-unused symbol properties were removed).
  • MA0215 needs no change: for async Task Foo() => await Task.CompletedTask; it already suggests Task Foo() => Task.CompletedTask;, which is the shape MA0214 now leaves alone.
  • 8 tests added, including the mixed case (with the fixer output) and a same-named CompletedTask property declared on another type (still reported).
  • dotnet run --project src/DocumentationGenerator produces no further markdown change. Full test suite passes on roslyn5.9 (3862 tests) and roslyn4.8 (3750 tests).

MA0214 flagged "async bridging methods" such as `Task FooAsync() =>
Task.CompletedTask;` or `Task<bool> BarAsync() => Task.FromResult(false);`,
where awaiting the task brings no benefit and only adds a state machine.

The rule is now skipped when every return of the function produces an
already-completed task (Task/ValueTask CompletedTask, FromResult,
FromException, FromCanceled, new ValueTask(), new ValueTask<T>(value)).
Functions mixing a completed task with a real task are still reported.

The detection of completed tasks moves from
AwaitTaskBeforeDisposingResourcesAnalyzer to AwaitableTypes.IsCompletedTask
so that both rules share it.

Fixes #1371
@meziantou
meziantou merged commit 0c5afb9 into main Sep 3, 2026
13 checks passed
@meziantou
meziantou deleted the feature/meziantou-analyzer-1371-2442e3 branch September 3, 2026 00:29
This was referenced Sep 3, 2026
This was referenced Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MA0214 flags usages of "async bridging methods" like Task.CompletedTask

1 participant