Skip to content

Add regression test for tuple swap with implicit indexer references - #132086

Merged
sbomer merged 2 commits into
dotnet:mainfrom
sbomer:runtime-tuple-swap
Aug 11, 2026
Merged

Add regression test for tuple swap with implicit indexer references#132086
sbomer merged 2 commits into
dotnet:mainfrom
sbomer:runtime-tuple-swap

Conversation

@sbomer

@sbomer sbomer commented Aug 10, 2026

Copy link
Copy Markdown
Member

Summary

Adds a regression test for #117122, a crash (Debug.Assert failure in VisitImplicitIndexerReference) hit by the ILLink Roslyn analyzer when analyzing a tuple-swap deconstruction assignment involving Span<T> elements accessed via the ^ (Index) operator, e.g.:

Span<int> span = stackalloc int[4];
(span[^1], span[^2]) = (span[^2], span[^1]);

Root cause

GetValueUsageInfo returns ValueUsageInfo.Write (without .Reference) for operations on the left side of a deconstruction assignment. VisitImplicitIndexerReference previously asserted that any Write-flagged implicit indexer reference must also be Reference, an assumption that didn't hold for deconstruction-assignment targets.

This is already fixed on main by #131624 ("Add dataflow support for deconstruction assignments"), which added proper VisitDeconstructionAssignment handling that routes deconstruction targets through dedicated assignment-processing logic instead of the generic operation visitor that could trip the old assert. That change closes #123767, and as a side effect also fixes this crash — verified by testing with only that fix applied (no separate patch needed here).

Testing

Folded the new test case (TestTupleSwap) into the existing ImplicitIndexerAccess nested test class in PropertyDataFlow.cs, since it already covers directly related ^-indexer and Span<T> write scenarios. Verified the test:

Note

This content was created with assistance from AI.

Fixes #117122

Adds a case to the existing ImplicitIndexerAccess dataflow test in
PropertyDataFlow.cs, covering the pattern from
dotnet#117122, where a tuple swap
involving Span<T> elements accessed via the ^ (Index) operator used to
crash the ILLink Roslyn analyzer with a Debug.Assert failure in
VisitImplicitIndexerReference.

This is now fixed by the deconstruction assignment dataflow support
added for dotnet#123767, so no
additional product change is needed; this just locks in the fix with a
regression test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fc762140-27e7-4d82-9f89-a55a3d8b7d78
Copilot AI lite review requested due to automatic review settings August 10, 2026 17:21
@github-actions github-actions Bot added the area-Tools-ILLink .NET linker development as well as trimming analyzers label Aug 10, 2026
@dotnet-policy-service dotnet-policy-service Bot added the linkable-framework Issues associated with delivering a linker friendly framework label Aug 10, 2026
@azure-pipelines

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

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @dotnet/illink
See info in area-owners.md if you want to be subscribed.

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

Adds regression coverage to prevent an ILLink Roslyn analyzer crash when analyzing tuple-swap deconstruction assignments that target Span<T> elements accessed via the ^ (Index) operator, matching the scenario from #117122.

Changes:

  • Add a new TestTupleSwap case covering (span[^1], span[^2]) = (span[^2], span[^1]) within the existing ImplicitIndexerAccess coverage.
  • Invoke TestTupleSwap from the nested ImplicitIndexerAccess.Test() entrypoint to keep it exercised consistently across tool suites using this file.
Show a summary per file
File Description
src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs Adds a regression test case for tuple-swap deconstruction with implicit indexer (^) access on Span<T>.

Review details

  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs Outdated
Reword the explanatory comment to precisely describe the root cause:
Roslyn marks an implicit indexer reference that is a deconstruction
assignment target as a write without also marking it as a reference,
rather than the previous "not a byref" phrasing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fc762140-27e7-4d82-9f89-a55a3d8b7d78
Copilot AI review requested due to automatic review settings August 10, 2026 17:32

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.

Review details

Suppressed comments (2)

src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs:788

  • The comment is slightly inaccurate: ^ is the C# index-from-end operator (which produces a System.Index), not an operator on System.Index itself. Rewording avoids confusion for future maintainers.
            // Tuple-swapping elements accessed through an implicit indexer (using the
            // System.Index '^' operator) used to crash the analyzer, because Roslyn
            // marks an implicit indexer reference that is a deconstruction assignment
            // target as a write without also marking it as a reference.

src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs:791

  • TestTupleSwap reads from span[^1]/span[^2] on the RHS, but the stackalloc int[4] buffer is left uninitialized. Initializing avoids reading uninitialized stack data while still exercising the same implicit-indexer/deconstruction pattern.
                Span<int> span = stackalloc int[4];
  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@sbomer
sbomer enabled auto-merge (squash) August 10, 2026 23:56
@sbomer
sbomer requested a review from a team August 10, 2026 23:56

@agocke agocke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sbomer
sbomer merged commit e83b5d5 into dotnet:main Aug 11, 2026
86 checks passed
@github-project-automation github-project-automation Bot moved this to Done in AppModel Aug 11, 2026
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-rc1 milestone Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-Tools-ILLink .NET linker development as well as trimming analyzers linkable-framework Issues associated with delivering a linker friendly framework

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

ILLink analyzer hole for deconstruction assignments ILLink.RoslynAnalyzer asserts on tuple swap involving implicit indexer reference

3 participants