Skip to content

[release/11.0] Revert deconstruction analysis in trim analyzer - #134484

Open
jtschuster wants to merge 3 commits into
dotnet:release/11.0from
jtschuster:RevertDeconstructionAnalysis
Open

jtschuster wants to merge 3 commits into
dotnet:release/11.0from
jtschuster:RevertDeconstructionAnalysis

Conversation

@jtschuster

@jtschuster jtschuster commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

#131624 implemented support for deconstruction and dataflow for TupleOperations (e.g. (a, b) = (b, a)). However, in some cases it made assumptions that Roslyn would lower a TupleOperation to a ValueTuple creation and ItemN field reference. This led to unexpected warnings like the one found in #133911.

#134377 offers one possible fix, but doesn't seem bulletproof and may introduce more regressions. A more "proper" fix would be an even larger change. The least risky "fix" is to revert the original PR and avoid creating bogus warnings at the cost of missing some valid warnings until publish time. However, a full revert reintroduces some bogus warnings (though they were present in .NET 10). Instead, we add very basic support to clear the dataflow information for locals that we see are assigned to in deconstruction assignments. In other words, the following snippet does not produce a bogus warning.

void Method(Type input)
{
    Type localType1 = input;
    Type localType2 = input;
    (localType, localType2) = GetTypesWithMethods();
    localType1.GetMethods(); // warns in .NET 10, does not warn in 11
    localType2.GetMethods(); // warns in .NET 10, does not warn in 11
}

This PR is broken into three commits:

  • Revert the initial PR
  • Re-add the tests from the initial PR, but with assertions changed to reflect the current behavior
  • Add minimal support for "clearing" dataflow values from local variables that are targets of deconstruction assignments.

Customer Impact

  • Customer reported
  • Found internally

Regression

  • Yes
  • No

Testing

Tests from the original PR were re-introduced with the assertions changed to reflect the behavior prior to the PR's product changes. Existing regression tests validate other scenarios are unaffected.

Risk

Low to medium. The diff is large, but it reverts behavior to .NET 10. There's a small possibility of regressions, but the likelihood and severity of regressions are less risky than the known regression in #133911.

@jtschuster jtschuster self-assigned this Sep 23, 2026
@github-actions github-actions Bot added the area-Tools-ILLink .NET linker development as well as trimming analyzers label Sep 23, 2026
@dotnet-policy-service dotnet-policy-service Bot added the linkable-framework Issues associated with delivering a linker friendly framework label Sep 23, 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.

@jtschuster
jtschuster force-pushed the RevertDeconstructionAnalysis branch from ea6366a to 5206ea7 Compare September 23, 2026 05:20
@jtschuster
jtschuster marked this pull request as ready for review September 23, 2026 16:38
@jtschuster
jtschuster requested a review from sbomer as a code owner September 23, 2026 16:38
Copilot AI lite review requested due to automatic review settings September 23, 2026 16:38
@jtschuster jtschuster changed the title Revert deconstruction analysis in trim analyzer [release/11.0-rc2] Revert deconstruction analysis in trim analyzer Sep 23, 2026

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

One or more issues must be addressed before approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity · 1 Medium severity

Open (3)
What changed in this PR

Reverts full deconstruction dataflow analysis while retaining conservative local clearing to avoid bogus trim warnings.

Changes:

  • Restores conservative conversion handling.
  • Removes complex deconstruction tracking and adds basic local invalidation.
  • Updates shared test expectations.
File Description
src/​tools/​illink/​test/​Mono.Linker.Tests.Cases/​DataFlow/​ExtensionMembersDataFlow.cs Updated as part of this pull request.
src/​tools/​illink/​test/​Mono.Linker.Tests.Cases/​DataFlow/​DeconstructUserDefinedConversion.cs Updated as part of this pull request.
src/​tools/​illink/​test/​Mono.Linker.Tests.Cases/​DataFlow/​DeconstructFieldTarget.cs Updated as part of this pull request.
src/​tools/​illink/​test/​Mono.Linker.Tests.Cases/​DataFlow/​ConstructedTypesDataFlow.cs Updated as part of this pull request.
src/​tools/​illink/​src/​ILLink.RoslynAnalyzer/​TrimAnalysis/​TrimAnalysisVisitor.cs Updated as part of this pull request.
src/​tools/​illink/​src/​ILLink.RoslynAnalyzer/​DataFlow/​LocalStateLattice.cs Updated as part of this pull request.
src/​tools/​illink/​src/​ILLink.RoslynAnalyzer/​DataFlow/​LocalStateAndContextLattice.cs Updated as part of this pull request.
src/​tools/​illink/​src/​ILLink.RoslynAnalyzer/​DataFlow/​LocalDataFlowVisitor.cs Updated as part of this pull request.


// Local dataflow states are mutable and should never be used as dictionary keys.
public override int GetHashCode() => throw new NotImplementedException();
public override int GetHashCode() => HashUtils.Combine(LocalState, Context);
Dictionary.Equals(other.Dictionary) &&
CapturedReferences.Equals(other.CapturedReferences) &&
CapturedTargetValues.Equals(other.CapturedTargetValues);
public bool Equals(LocalState<TValue> other) => Dictionary.Equals(other.Dictionary);
Comment on lines +752 to +754
case IDeclarationExpressionOperation declaration:
SetDeconstructedLocalsToTop(declaration.Expression, state);
break;
@agocke agocke added the Servicing-approved Approved for servicing release label Sep 23, 2026
@agocke
agocke requested a balanced review from Copilot September 23, 2026 17: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.

Copilot review overview

🟡 Changes recommended

Flow-captured locals are not cleared, and captured-reference changes are omitted from fixpoint equality.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 2 High severity · 2 Medium severity · 3 Low severity

Open (7)

Comment on lines +744 to +759
private void SetDeconstructedLocalsToTop(IOperation target, LocalDataFlowState<TValue, TContext, TValueLattice, TContextLattice> state)
{
switch (target)
{
case ITupleOperation tuple:
foreach (IOperation element in tuple.Elements)
SetDeconstructedLocalsToTop(element, state);
break;
case IDeclarationExpressionOperation declaration:
SetDeconstructedLocalsToTop(declaration.Expression, state);
break;
case ILocalReferenceOperation local:
SetLocal(local.Local, TopValue, state);
break;
}
}
// (IIncrementOrDecrementOperation) and coalescing assignment (ICoalesceAssignmentOperation)
// are not handled here and fall back to the base visitor, which visits the write target
// directly. Enabling the following assert requires handling those first.
// This can also happen for a deconstruction assignments, where the write is not to a byref.
static (Type type, object instance) GetInput(Type type, int unused) => (type, null);

[ExpectedWarning("IL2077")]
[ExpectedWarning("IL2077", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/123767")]
Comment on lines +269 to +270
[ExpectedWarning("IL2026", nameof(GetIndexerHolder), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/123767")]
[ExpectedWarning("IL2026", nameof(GetIndex), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/123767")]
agocke
agocke previously approved these changes Sep 23, 2026

@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

@jtschuster
jtschuster changed the base branch from release/11.0-rc2 to release/11.0 September 24, 2026 17:23
@jtschuster
jtschuster dismissed agocke’s stale review September 24, 2026 17:23

The base branch was changed.

@jtschuster jtschuster changed the title [release/11.0-rc2] Revert deconstruction analysis in trim analyzer [release/11.0] Revert deconstruction analysis in trim analyzer Sep 24, 2026

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 Servicing-approved Approved for servicing release

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants