Skip to content

Unsafe evolution: allow await in unsafe context - #84616

Merged
jjonescz merged 11 commits into
dotnet:mainfrom
jjonescz:Unsafe-44-AwaitInUnsafe
Aug 11, 2026
Merged

jjonescz merged 11 commits into
dotnet:mainfrom
jjonescz:Unsafe-44-AwaitInUnsafe

Conversation

@jjonescz

@jjonescz jjonescz commented Jul 24, 2026

Copy link
Copy Markdown
Member

Test plan: #81207
Relevant speclet section: await in unsafe contexts

Microsoft Reviewers: Open in CodeFlow

@azure-pipelines

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

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.

Pull request overview

This PR updates the C# compiler’s await context checks to support the Unsafe Evolution feature: await is permitted in unsafe contexts when the feature is enabled, while await remains disallowed inside a fixed statement (with a new dedicated diagnostic). It also updates compiler tests and the Expression Evaluator tests accordingly, and adds localized resources for the new diagnostic.

Changes:

  • Gate ERR_AwaitInUnsafeContext on the Unsafe Evolution feature, and introduce ERR_BadAwaitInFixed for await inside fixed when the feature is enabled.
  • Track fixed-statement binding context via a new BinderFlags.InFixedStatement and propagate it through FixedStatementBinder.
  • Update/extend tests and resources (resx + xlf) to reflect the new behavior across language versions and debugger EE behavior.

Reviewed changes

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

Show a summary per file
File Description
src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs Expands EE coverage across language versions; adds EE test for await inside fixed under debugger binder flags.
src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocInitializerTests.cs Pins legacy behavior to C# 14 for await diagnostics in unsafe stackalloc initializers.
src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs Updates expectations to reflect that preview/next no longer errors on await in unsafe contexts.
src/Compilers/CSharp/Test/Semantic/Semantics/BindingAsyncTests.cs Updates/retargets diagnostics checks for legacy vs next behavior around await in unsafe contexts.
src/Compilers/CSharp/Test/Emit3/RefUnsafeInIteratorAndAsyncTests.cs Updates diagnostics now that await in unsafe can succeed and reach ref-across-await checks.
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs Pins legacy await-in-unsafe behavior to C# 14.
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs Pins legacy await-in-unsafe behavior to C# 14.
src/Compilers/CSharp/Test/CSharp15/UnsafeEvolutionTests.cs Adds new coverage for await in unsafe blocks and for the new await-in-fixed restriction/diagnostic.
src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf Adds ERR_BadAwaitInFixed localization entry (new).
src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs Marks the new error as build-only diagnostic.
src/Compilers/CSharp/Portable/Errors/ErrorCode.cs Introduces ERR_BadAwaitInFixed = 9396.
src/Compilers/CSharp/Portable/CSharpResources.resx Adds the user-facing message for ERR_BadAwaitInFixed.
src/Compilers/CSharp/Portable/Binder/FixedStatementBinder.cs Sets BinderFlags.InFixedStatement for the fixed-statement binding scope.
src/Compilers/CSharp/Portable/Binder/BinderFlags.cs Introduces InFixedStatement and clears it at executable code boundaries.
src/Compilers/CSharp/Portable/Binder/Binder_Await.cs Updates await-context checking for Unsafe Evolution + new fixed-statement restriction.

Comment thread src/Compilers/CSharp/Test/CSharp15/UnsafeEvolutionTests.cs
@jjonescz
jjonescz marked this pull request as ready for review July 27, 2026 10:30
@jjonescz
jjonescz requested a review from a team as a code owner July 27, 2026 10:30
@jjonescz
jjonescz requested review from 333fred and AlekseyTs July 27, 2026 10:30
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

Comment thread src/Compilers/CSharp/Portable/Binder/Binder_Await.cs Outdated
Comment thread src/Compilers/CSharp/Portable/Binder/FixedStatementBinder.cs
Comment thread src/Compilers/CSharp/Test/CSharp15/UnsafeEvolutionTests.cs Outdated
Comment thread src/Compilers/CSharp/Test/CSharp15/UnsafeEvolutionTests.cs Outdated
Comment thread src/Compilers/CSharp/Portable/Binder/Binder_Await.cs Outdated
Comment thread src/Compilers/CSharp/Test/CSharp15/UnsafeEvolutionTests.cs Outdated
Comment thread src/Compilers/CSharp/Portable/Binder/Binder_Await.cs Outdated
@AlekseyTs

Copy link
Copy Markdown
Contributor

Done with review pass (commit 2)

Copilot AI review requested due to automatic review settings July 30, 2026 11:00

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.

Pull request overview

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

Comments suppressed due to low confidence (1)

src/Compilers/CSharp/Portable/Binder/Binder_Await.cs:228

  • ReportBadAwaitContext reports ERR_BadAwaitInFixed for any await in a fixed statement body, even when BinderFlags.AllowAwaitInUnsafeContext is set. This looks inconsistent with the intended debugger behavior (and the new ExpressionCompiler test remarks) where the debugger should allow awaiting in unsafe contexts, including within fixed bodies.
            if (this.Flags.Includes(BinderFlags.InFixedStatementBody))
            {
                Error(diagnostics, ErrorCode.ERR_BadAwaitInFixed, awaitNodeOrToken);
                return true;
            }

Copilot AI review requested due to automatic review settings July 30, 2026 12:28
<data name="ERR_AwaitInUnsafeContext" xml:space="preserve">
<value>Cannot await in an unsafe context</value>
<data name="ERR_BadAwaitInFixed" xml:space="preserve">
<value>Cannot await in the body or the initializer of a 'fixed' statement</value>

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.

Cannot await in the body or the initializer of a 'fixed' statement

Not blocking, but I would go with: "Cannot await in context of a 'fixed' statement"

@AlekseyTs AlekseyTs 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.

LGTM (commit 6)

@AlekseyTs AlekseyTs 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.

LGTM (commit 6)

Copilot AI review requested due to automatic review settings July 30, 2026 16:11

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.

Pull request overview

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

@jjonescz

Copy link
Copy Markdown
Member Author

@333fred for a second review, thanks

Copilot AI review requested due to automatic review settings August 4, 2026 12:52

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.

Pull request overview

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

Suppressed comments (3)

src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs:900

  • Same as above: this comment mentions "ref and unsafe in async and iterator methods", but the test is asserting a preview-gated diagnostic for await in an unsafe context. Please update the comment to match the scenario being tested.
            // https://github.com/dotnet/roslyn/issues/73280 - these should ideally be langversion errors for 'ref and unsafe in async and iterator methods'

src/Compilers/CSharp/Portable/CSharpResources.resx:3836

  • The new diagnostic text is slightly ungrammatical compared to adjacent messages (e.g., "Cannot await in the body of a lock statement"). Consider adding "the" so the message reads naturally.
  <data name="ERR_BadAwaitInFixed" xml:space="preserve">
    <value>Cannot await in context of a 'fixed' statement</value>
  </data>

src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs:873

  • This comment references issue #73280 and "ref and unsafe in async and iterator methods", but the asserted diagnostic here is for the preview-gated "updated memory safety rules" feature (triggered by await in an unsafe context). The comment should be updated to reflect what this test is actually asserting.

This issue also appears on line 900 of the same file.

            // https://github.com/dotnet/roslyn/issues/73280 - these should ideally be langversion errors for 'ref and unsafe in async and iterator methods'

@jjonescz

jjonescz commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

@333fred for a second review, thanks

@jjonescz
jjonescz requested a review from RikkiGibson August 10, 2026 09:00
Copilot AI review requested due to automatic review settings August 11, 2026 08:18

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.

Pull request overview

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

Comment thread src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@jjonescz
jjonescz enabled auto-merge (squash) August 11, 2026 08:26
@jjonescz
jjonescz merged commit 461c2ef into dotnet:main Aug 11, 2026
27 of 28 checks passed
@jjonescz
jjonescz deleted the Unsafe-44-AwaitInUnsafe branch August 11, 2026 13:19
333fred added a commit to 333fred/roslyn that referenced this pull request Aug 11, 2026
…-15-langver

* upstream/main:
  Unsafe evolution: allow await in unsafe context (dotnet#84616)
  Fix empty localization stage on non-main/release branches in official pipeline (dotnet#84845)
  Reorder stages for localization and build (dotnet#84841)
  Revert the sonic decl/impl split merge from main (dotnet#84831)
  AI Workflow - switch to use personal token instead of organizational (dotnet#84832)
  [main] Update dependencies from dotnet/arcade (dotnet#84819)
  Do not offer introduce parameter for incomplete calls (dotnet#84769)
@jjonescz jjonescz added this to the 18.11 milestone Aug 25, 2026
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.

4 participants