Fix CS4007: ReadOnlySpan across await in TrailingHeadersTest#125946
Fix CS4007: ReadOnlySpan across await in TrailingHeadersTest#125946MichalStrehovsky merged 2 commits intomainfrom
Conversation
Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com> Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/7513d91a-dbcc-4acf-86c6-d9110df1c1c0
|
Cc @agocke, I think this is from the xunit upgrade, not completely sure why we didn't see this in that PR's CI run, but I now see: in various CI legs. |
There was a problem hiding this comment.
Pull request overview
Fixes a functional test build failure in System.Net.Http.WinHttpHandler caused by overload resolution selecting an Assert.Equal<byte>(ReadOnlySpan<byte>, ReadOnlySpan<byte>) overload in the presence of an await, which triggers CS4007.
Changes:
- Store
await response.Content.ReadAsByteArrayAsync()into a localbyte[]before asserting. - Update the assertion to compare the empty byte array against the local variable without an
awaitin the same statement.
|
/azp run runtime-nativeaot-outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
(Triggering a native AOT outerloop, since we very like won't run the relevant legs here either, but naot outerloops for sure hit this.) |
|
Tagging subscribers to this area: @karelz, @dotnet/ncl |
|
/ba-g one is #125953, another has a pr out by me, another is a timeout, all unrelated |
|
Huh. Little weird but Lgtm |
`Assert.Equal<byte>(Array.Empty<byte>(), await ...)` resolves the `ReadOnlySpan<byte>` overload, causing CS4007 since the span can't be preserved across the `await` boundary — breaking functional test builds for `System.Net.Http.WinHttpHandler`. ## Description - **`TrailingHeadersTest.cs`**: In `Http2GetAsync_TrailingHeaders_NoData_EmptyResponseObserved`, extract the awaited call into a local variable before `Assert.Equal`: ```csharp // Before (broken): Assert.Equal<byte>(Array.Empty<byte>(), await response.Content.ReadAsByteArrayAsync()); // After (fixed): byte[] responseBody = await response.Content.ReadAsByteArrayAsync(); Assert.Equal(Array.Empty<byte>(), responseBody); ``` <!-- --> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ## Problem > > Building the functional tests for `System.Net.Http.WinHttpHandler` fails with the following error: > > ``` > src\libraries\System.Net.Http.WinHttpHandler\tests\FunctionalTests\TrailingHeadersTest.cs(220,36): error CS4007: Instance of type 'System.ReadOnlySpan<byte>' cannot be preserved across 'await' or 'yield' boundary. > ``` > > ### Root Cause > > In `src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/TrailingHeadersTest.cs`, line 220, inside the `Http2GetAsync_TrailingHeaders_NoData_EmptyResponseObserved` async test method: > > ```csharp > Assert.Equal<byte>(Array.Empty<byte>(), await response.Content.ReadAsByteArrayAsync()); > ``` > > `Assert.Equal<byte>(ReadOnlySpan<byte>, ReadOnlySpan<byte>)` overload is being resolved here, which means `Array.Empty<byte>()` is implicitly converted to a `ReadOnlySpan<byte>`. Since there is an `await` expression in the same statement (as the second argument), the compiler cannot preserve the `ReadOnlySpan<byte>` across the `await` boundary — resulting in CS4007. > > ## Fix > > In the `Http2GetAsync_TrailingHeaders_NoData_EmptyResponseObserved` method, extract the `await` call to a local variable **before** the `Assert.Equal` call, so that no `ReadOnlySpan<byte>` lives across an `await`: > > ```csharp > // Before (broken): > Assert.Equal<byte>(Array.Empty<byte>(), await response.Content.ReadAsByteArrayAsync()); > > // After (fixed): > byte[] responseBody = await response.Content.ReadAsByteArrayAsync(); > Assert.Equal(Array.Empty<byte>(), responseBody); > ``` > > The file to change is: > `src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/TrailingHeadersTest.cs` > > The change is in the `Http2GetAsync_TrailingHeaders_NoData_EmptyResponseObserved` method, around line 220. > > > The following is the prior conversation context from the user's chat exploration (may be truncated): > > User: in testing we started hitting following error, fix it: src\libraries\System.Net.Http.WinHttpHandler\tests\FunctionalTests\TrailingHeadersTest.cs(220,36): error CS4007: (NETCORE_ENGINEERING_TELEMETRY=Build) Instance of type 'System.ReadOnlySpan<byte>' cannot be preserved across 'await' or 'yield' boundary. > > > Assistant: The issue is clear. On line 220, `Assert.Equal<byte>` is being called inside an `async` method where the first argument is `Array.Empty<byte>()` — which returns a `ReadOnlySpan<byte>` — and the second argument is `await response.Content.ReadAsByteArrayAsync()`. The `ReadOnlySpan<byte>` cannot be preserved across the `await` boundary. > > The fix is to `await` the `ReadAsByteArrayAsync()` call first, store it in a local variable, and then pass it to `Assert.Equal`. > > Assistant: We're waiting for your response to the tool call dialog to continue — please accept or reject the proposed pull request action so I can proceed. > > </details> <!-- START COPILOT CODING AGENT SUFFIX --> *This pull request was created from Copilot chat.* > <!-- START COPILOT CODING AGENT TIPS --> --- 📱 Kick off Copilot coding agent tasks wherever you are with [GitHub Mobile](https://gh.io/cca-mobile-docs), available on iOS and Android. Fixes #125952 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Assert.Equal<byte>(Array.Empty<byte>(), await ...)resolves theReadOnlySpan<byte>overload, causing CS4007 since the span can't be preserved across theawaitboundary — breaking functional test builds forSystem.Net.Http.WinHttpHandler.Description
TrailingHeadersTest.cs: InHttp2GetAsync_TrailingHeaders_NoData_EmptyResponseObserved, extract the awaited call into a local variable beforeAssert.Equal:Original prompt
This pull request was created from Copilot chat.
📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.
Fixes #125952