Skip to content

ILLink Analyzer: Don't assume Tuple operations compile to creation of a ValueTuple - #134377

Open
jtschuster wants to merge 4 commits into
dotnet:mainfrom
jtschuster:fix-ituple-analyzer
Open

jtschuster wants to merge 4 commits into
dotnet:mainfrom
jtschuster:fix-ituple-analyzer

Conversation

@jtschuster

Copy link
Copy Markdown
Member

The trim analyzer assumed that all ITupleOperations lowered to a creation of a ValueTuple, and deconstruction would be a reference to the ItemN field. This isn't always true. Instead, don't make any assumptions and avoid warning by creating TopValue for elements of an ITupleOperaion.

We track all flow captures that have any ITupleOperations in order to resolve which IFlowCaptureReferenceOperations resolve to a Tuple, then for direct ITupleOperations we construct a (potentially nested) tuple of TopValues.

Fixes #133911

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 2c75aa0b-5f23-4371-8668-fa093efefe3c
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 2c75aa0b-5f23-4371-8668-fa093efefe3c
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 2c75aa0b-5f23-4371-8668-fa093efefe3c
@jtschuster jtschuster self-assigned this Sep 21, 2026
Copilot AI lite review requested due to automatic review settings September 21, 2026 21:13
@jtschuster
jtschuster requested a review from sbomer as a code owner September 21, 2026 21:13
@jtschuster
jtschuster requested a review from agocke September 21, 2026 21:13
@dotnet-policy-service dotnet-policy-service Bot added the linkable-framework Issues associated with delivering a linker friendly framework label Sep 21, 2026
@github-actions github-actions Bot added the area-Tools-ILLink .NET linker development as well as trimming analyzers label Sep 21, 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.

Copilot review overview

🟡 Changes recommended

Direct tuple operations currently discard computed element values, causing data-flow regressions and masked warnings.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Updates ILLink tuple data-flow analysis to avoid assuming tuple expressions lower to ValueTuple operations.

Changes:

  • Tracks tuple-producing flow captures.
  • Uses conservative values for ambiguous lowering paths.
  • Adds and updates deconstruction regression tests.
File Summary
src/​tools/​illink/​test/​Mono.Linker.Tests.Cases/​DataFlow/​DeconstructFieldTarget.cs Updates expected warning behavior for deconstruction scenarios.
src/​tools/​illink/​test/​Mono.Linker.Tests.Cases/​DataFlow/​ConstructedTypesDataFlow.cs Adds tuple and deconstruction data-flow regression coverage.
src/​tools/​illink/​src/​ILLink.RoslynAnalyzer/​DataFlow/​LocalDataFlowVisitor.cs Adjusts tuple operation and flow-capture modeling.

Comment thread src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs Outdated
@agocke

agocke commented Sep 21, 2026 •

Copy link
Copy Markdown
Member

This doesn't look right. I think we want to break down the lattice state into top/scalar/multi-value (tuple). Something like

  public enum LocalValueKind
    {
        Top,
        Scalar,
        Tuple
    }

    public readonly struct LocalValue<TValue> : IEquatable<LocalValue<TValue>>, IDeepCopyValue<LocalValue<TValue>>
        where TValue : IEquatable<TValue>
    {
        public LocalValueKind Kind { get; }

        public bool HasValue => Kind is not LocalValueKind.Top;

        public bool IsTuple => Kind is LocalValueKind.Tuple;

        public TValue Value { get; }

        public ImmutableArray<LocalValue<TValue>> Elements { get; }

        public LocalValue(TValue value)
        {
            Kind = LocalValueKind.Scalar;
            Value = value;
            Elements = default;
        }

        public LocalValue(ImmutableArray<LocalValue<TValue>> elements)
        {
            Kind = LocalValueKind.Tuple;
            Value = default!;
            Elements = elements;
        }
    }

And then instead of

 public struct LocalState<TValue> : IEquatable<LocalState<TValue>>
        where TValue : IEquatable<TValue>
    {
        public DefaultValueDictionary<LocalKey, TValue> Dictionary;

we swap out TValue with LocalValue<TValue>?

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 2c75aa0b-5f23-4371-8668-fa093efefe3c
Copilot AI review requested due to automatic review settings September 21, 2026 22:22

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.

Copilot review overview

🟡 Changes recommended

Tuple flow captures may lose element-level dataflow and suppress required warnings.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
Resolved since last review (1)

Comment on lines +867 to +869
useTopForTupleElements
? TopValue
: GetTupleElementValue(tupleElement),

This branch has not been deployed

No deployments
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: No status

Development

Successfully merging this pull request may close these issues.

IL2080 from deconstruction assignment "using" ValueTuple

3 participants