Skip to content

[✨ Triage] dotnet/runtime#125952 by matouskozak - TrailingHeadersTest.cs: CS4007 ReadOnlySpan<byte> cannot be preser ... #167

@MihuBot

Description

@MihuBot

Triage for dotnet/runtime#125952.
Repo filter: All networking issues.
MihuBot version: 246635.
Ping MihaZupan for any issues.

This is a test triage report generated by AI, aimed at helping the triage team quickly identify past issues/PRs that may be related.
Take any conclusions with a large grain of salt.

Tool logs
dotnet/runtime#125952: TrailingHeadersTest.cs: CS4007 ReadOnlySpan<byte> cannot be preserved across await boundary by matouskozak
Extracted 5 search queries: CS4007: Instance of type 'System.ReadOnlySpan<byte>' cannot be preserved across 'await' or 'yield' boundary, ReadOnlySpan<byte> used across await boundary in System.Net.Http tests, TrailingHeadersTest.cs ReadOnlySpan<byte> await boundary WinHttpHandler functional test, CS4007 build error in System.Net.Http functional tests on windows-x64 Release AllSubsets_Mono, preserving ReadOnlySpan across await/yield compiler error (suggestions: use Memory<byte> or copy to byte[])
Found 21 candidate issues
  • PR #125946 (Mar 23, 2026) - Fix CS4007: ReadOnlySpan across await in TrailingHeadersTest
    Summary: quick fix for the failing functional test in System.Net.Http.WinHttpHandler (TrailingHeadersTest.cs). The failing statement used Assert.Equal(Array.Empty(), await response.Content.ReadAsByteArrayAsync()) which resolved to the ReadOnlySpan overload and caused CS4007. The PR extracts the await to a local byte[] (byte[] responseBody = await ...; Assert.Equal(Array.Empty(), responseBody);). Discussion: confirmed as a practical test fix; CI jobs/outerloops triggered. Actionable: this PR directly addresses the build error in the new issue.

  • Issue roslyn#74046 (Jun 18, 2024) - False positive CS4007 "Instance of type 'System.ReadOnlySpan<...>' cannot be preserved across 'await' or 'yield' boundary"
    Summary: reproduction of CS4007 where a span-like expression appears around an await. Roslyn/maintainers explain the error is expected: ReadOnlySpan must be on the stack when invoked/used and cannot be preserved across an await. Conclusion: CS4007 is by-design for these scenarios (not a compiler bug to be fixed by suppressing the diagnostic).

  • Issue roslyn#76779 (Jan 16, 2025) - Error CS4007 is not visible in the editor
    Summary: reports that CS4007 is only reported at full-build time (later stages of the compiler) and so the editor/IDE may not show the error inline. Maintainers confirmed it's a "build-only diagnostic" today and acknowledged the poor UX. Conclusion: you may only see CS4007 during CI/build (not in the IDE), so fixes may be discovered only after CI runs.

  • Issue runtime#125115 (Mar 3, 2026) - .NET 10 SequenceEqual breaks when there is an await in the argument position
    Summary: real-world regression triggered by overload resolution changes: calls like (await A()).SequenceEqual(await B()) now bind to ReadOnlySpan.SequenceEqual (span overloads) instead of IEnumerable overloads, which can introduce CS4007 when one argument contains an await. Author notes it compiles on .NET 8/9 but fails on 10. Workarounds: assign awaited results to locals before calling SequenceEqual or force IEnumerable overload (e.g., .AsEnumerable()). Conclusion: the change in overload resolution is a broader root cause for many CS4007 build failures when awaits are used inside argument positions.

  • Issue roslyn#82608 (Mar 3, 2026) - .NET 10 SequenceEqual breaks when there is an await in the argument position (duplicate / Roslyn tracking)
    Summary: same as runtime#125115 but tracked in Roslyn; Roslyn maintainers explained this is the intended result of the overload-resolution change (SequenceEqual now prefers span overload). Suggested workarounds: assign awaited results to locals or use .AsEnumerable() to pick the IEnumerable overload. Conclusion: this explains why the trailing-headers test started failing (overload resolution change + await in argument).

  • PR #48704 (Feb 24, 2021) - WinHttpHandler: Read HTTP/2 trailing headers (replacement PR)
    Summary: historical PR that added trailing headers support and the TrailingHeadersTest.cs tests to System.Net.Http.WinHttpHandler. Relevance: provides context for where TrailingHeadersTest.cs came from and why that test exists in WinHttpHandler. Conclusion: the test is legitimate and maintained; the current failure is a C#/overload/await interaction in the test, not a networking bug.

  • Issue runtime#46263 (Dec 20, 2020) - [HTTP/3] Error when reading trailing headers (unit tests)
    Summary: earlier/trailing-headers-related test work and issues around trailers; not directly about CS4007 but gives historical context for trailer-related tests and decoder state. Conclusion: useful background but not directly related to the CS4007 compiler error.

Overall conclusions for the new issue (TrailingHeadersTest.cs CS4007):

  • The immediate, low-risk fix is exactly what PR #125946 implements: avoid having a ReadOnlySpan-like value (here, Array.Empty() resolving to a span overload) in the same statement as an await by awaiting into a local and then asserting. That resolves the compile-time CS4007.
  • The underlying class of failures is a language/overload-resolution change (SequenceEqual and other APIs with span overloads) plus the compiler rule that spans cannot be preserved across await; this is by-design in Roslyn. Workarounds are to materialize awaited results into locals or to disambiguate overload selection (e.g., AsEnumerable()).
  • UX note: CS4007 may only appear during full builds/CI, not in the IDE. Expect similar test breaks to surface in CI after language/library upgrades; automated test fixes like PR #125946 are appropriate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions