Skip to content

Suppress interface generic dataflow warnings under RUC - #131911

Open
sbomer wants to merge 4 commits into
dotnet:mainfrom
sbomer:runtime-base-ctor
Open

Suppress interface generic dataflow warnings under RUC#131911
sbomer wants to merge 4 commits into
dotnet:mainfrom
sbomer:runtime-base-ctor

Conversation

@sbomer

@sbomer sbomer commented Aug 5, 2026

Copy link
Copy Markdown
Member

Summary

  • suppress generic interface-list IL2026 and IL2091 warnings when the implementing type is directly annotated with RequiresUnreferencedCode
  • keep linker and NativeAOT dataflow running so constructors and members required by the interface instantiation remain preserved
  • keep NativeAOT's independent IL3002 and IL3050 warnings active when only the trimming warning axis is suppressed
  • add cross-tool diagnostic coverage and a kept-member regression for the interface path

This follows the existing base-type behavior while keeping the suppression local to interface-list analysis. Warnings from attributes and DynamicallyAccessedMembers type-hierarchy analysis remain unaffected because those can be reached through reflection outside the type's RequiresUnreferencedCode scope.

Fixes #108507
Fixes #108523

Testing

  • ILLink.RoslynAnalyzer.Tests
  • ILCompiler.Trimming.Tests
  • Mono.Linker.Tests

Note

This content was created with assistance from AI.

sbomer and others added 3 commits July 27, 2026 14:06
Warnings for generic instantiations in the interface list originate from
the type declaration itself, so they are not suppressed by
RequiresUnreferencedCode on the type. The base type case was fixed in
dotnet#119419 by moving the check to the (implicit) constructor,
but the interface list is still analyzed at the type level in the
analyzer, ILLink and ILCompiler.

Cover the interface analogues of the existing base type test cases:
- new() constraint with a RUC generic argument, with and without RUC on
  the implementing type (dotnet#108507)
- DynamicallyAccessedMembers mismatch with RUC on the implementing type
  (dotnet#108523)

The unsuppressed warnings are marked with UnexpectedWarning so the tests
document the current behavior and will need updating once fixed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 89d21a2e-26e9-4e1c-b670-5ec5336c5e28
Assisted-by: GitHub Copilot CLI:claude-opus-5
The generic instantiations in a type's interface list are only reachable
through the members of that type. When the type is annotated with
RequiresUnreferencedCode, all of those members are in the Requires scope,
so the attribute should silence the warnings, the same way it already does
for the base type instantiation (dotnet#119419).

This warns at the type declaration rather than at the point where the type
becomes castable to the interface, so it is scoped narrowly to the three
interface-list call sites instead of being added to the shared Requires
suppression helpers. Attributes on the type and DynamicallyAccessedMembers
type hierarchy warnings are deliberately not affected, since those are
reachable from reflection outside of any Requires scope.

The data flow still runs in ILLink and ILCompiler so that the members
required by the instantiation (for example the parameterless constructor
implied by a new() constraint) keep being marked; only the diagnostics are
suppressed.

Fixes dotnet#108507 for interfaces.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 89d21a2e-26e9-4e1c-b670-5ec5336c5e28
Assisted-by: GitHub Copilot CLI:claude-opus-5
Type-level RequiresUnreferencedCode should suppress the trimming warnings
produced while analyzing a generic interface instantiation, but it does not
suppress RequiresAssemblyFiles or RequiresDynamicCode warnings.

Narrow NativeAOT's warning gate to the trimming axis so IL3002 and IL3050
remain reported. Add regression coverage for those capability warnings and
for the requirement that suppressed interface dataflow still preserves the
members requested by DynamicallyAccessedMembers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 89d21a2e-26e9-4e1c-b670-5ec5336c5e28
Assisted-by: GitHub Copilot CLI:gpt-5.6-sol
Copilot AI review requested due to automatic review settings August 5, 2026 23:00
@github-actions github-actions Bot added the area-Tools-ILLink .NET linker development as well as trimming analyzers label Aug 5, 2026
@dotnet-policy-service dotnet-policy-service Bot added the linkable-framework Issues associated with delivering a linker friendly framework label Aug 5, 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.

Pull request overview

This PR adjusts trimming/dataflow diagnostics so that generic instantiations in a type’s interface list no longer produce IL2026/IL2091 warnings when the implementing type is directly annotated with RequiresUnreferencedCode, while still running dataflow to preserve members required by the instantiation and maintaining cross-tool consistency (linker, analyzer, NativeAOT).

Changes:

  • Suppress interface-list generic-argument dataflow warnings under type-level RUC while keeping marking/dataflow active (ILLink + NativeAOT).
  • Align Roslyn analyzer behavior to skip interface-list generic instantiation warnings for RUC-annotated types while leaving DAM hierarchy/attribute analysis intact.
  • Extend test coverage to validate warning suppression behavior and that required members are still kept/marked.
Show a summary per file
File Description
src/tools/illink/src/linker/Linker.Steps/MarkStep.cs Adds localized suppression state around interface implementation generic-argument dataflow to silence warnings while still marking required members.
src/tools/illink/src/linker/Linker.Dataflow/GenericArgumentDataFlow.cs Adds a suppression parameter to control whether generic-argument diagnostics are emitted during processing.
src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs Skips interface-list generic instantiation analysis for types with RequiresUnreferencedCode, while still applying DAM type-hierarchy analysis.
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DataflowAnalyzedTypeDefinitionNode.cs Suppresses interface-list trimming diagnostics under type-level RUC while still executing dataflow to mark required members.
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs Introduces an option to suppress trim-analysis warnings while keeping other capability warnings (e.g., AOT/single-file) reportable.
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/GenericArgumentDataFlow.cs Threads suppression through generic argument dataflow to match the updated interface-list behavior.
src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs Adds test cases covering interface-list generic warnings under RUC and ensures other capability warnings remain for NativeAOT where appropriate.
src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlowMarking.cs Adds a kept-member regression ensuring interface instantiation still marks required members under RUC suppression.
src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs Updates expected warnings to reflect the new suppression behavior for interface generic analysis under RUC.

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 1

Comment on lines +49 to +53
var diagnosticContext = new DiagnosticContext(
origin,
!logger.ShouldSuppressAnalysisWarningsForRequires(origin.MemberDefinition, DiagnosticUtilities.RequiresUnreferencedCodeAttribute),
!suppressWarnings && !logger.ShouldSuppressAnalysisWarningsForRequires(origin.MemberDefinition, DiagnosticUtilities.RequiresUnreferencedCodeAttribute),
logger);
var reflectionMarker = new ReflectionMarker(logger, factory, flowAnnotations, typeHierarchyDataFlowOrigin: null, enabled: true);
var reflectionMarker = new ReflectionMarker(logger, factory, flowAnnotations, typeHierarchyDataFlowOrigin: null, enabled: true, suppressWarnings);
Keep interface-list suppression limited to trimming diagnostics while
preserving the origin's independent AOT and single-file suppression scopes.
Name the ReflectionMarker suppression argument to clarify which diagnostic
axis it controls.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 89d21a2e-26e9-4e1c-b670-5ec5336c5e28
Assisted-by: GitHub Copilot CLI:gpt-5.6-sol
Copilot AI review requested due to automatic review settings August 6, 2026 18:06

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's findings

Suppressed comments (2)

src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs:1503

  • If you add the non-RUC baseline interface implementation (ClassImplementingInterfaceWithWarning), it needs to be referenced/instantiated so the interface list is processed and the IL2091 expectation is exercised.
                var m = new GenericAnnotatedWithWarningWithRequires<int>();
                var n = new ClassImplementingInterfaceWithWarningOnGenericArgumentConstructor();
                var o = new ClassImplementingInterfaceWithWarningOnGenericArgumentConstructorWithRequires();
                var p = new ClassImplementingInterfaceWithWarningWithRequires();
                var q = new ClassImplementingInterfaceWithOtherCapabilityWarningsWithRequires();

src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs:1457

  • The new coverage for interface-list generic dataflow under type-level RUC doesn't include a non-RUC baseline for the IL2091 interface generic-argument mismatch. Adding one here would ensure the change suppresses IL2091 only under [RequiresUnreferencedCode] and doesn't accidentally suppress it unconditionally.

This issue also appears on line 1499 of the same file.

            [RequiresUnreferencedCode("--ClassImplementingInterfaceWithWarningWithRequires--")]
            public class ClassImplementingInterfaceWithWarningWithRequires : IRequiresAll<T>
            {
            }
  • Files reviewed: 9/9 changed files
  • Comments generated: 0 new

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

2 participants