Skip to content

Mark descriptor-preserved members as reflection-visible#128272

Merged
sbomer merged 26 commits into
dotnet:mainfrom
sbomer:descriptor-abstract
Jun 4, 2026
Merged

Mark descriptor-preserved members as reflection-visible#128272
sbomer merged 26 commits into
dotnet:mainfrom
sbomer:descriptor-abstract

Conversation

@sbomer
Copy link
Copy Markdown
Member

@sbomer sbomer commented May 15, 2026

And mark their declaring types as reflection-visible.

When a member is marked via descriptor it should be considered visible to reflection. And when that is the case, its declaring type is accessible via reflection, so the requirements for reflection-visible types should be preserved too.

Fixes #128120

sbomer and others added 8 commits May 15, 2026 15:51
…t impls

Add a regression test for dotnet#128120. When a type is preserved
via an XML descriptor, ILLink should keep its static abstract interface
implementations if those methods are called through constrained generics
elsewhere in the program. Currently the test fails because ILLink strips
the interface and override from the descriptor-preserved type.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
…ant casting

A method preserved via XML descriptor is reflection-visible, which means
its declaring type is also accessible (e.g., via
MethodBase.GetCurrentMethod().DeclaringType) and could be used as a
generic argument in constrained calls (e.g., via MakeGenericMethod).

Mark the declaring type as relevant to variant casting so that its static
abstract interface implementations are preserved by the linker.

Fixes dotnet#128120

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
…t be kept

Test that a reference type with explicit layout preserved via XML
descriptor retains its fields. This verifies the type is treated as
fully reflection-visible (MarkImplicitlyUsedFields), not just relevant
to variant casting.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
…tion-visible

Descriptor-preserved methods and fields are reflection-visible. Their
declaring types are also accessible (e.g., via MethodBase.DeclaringType
or FieldInfo.DeclaringType) and could be used as generic arguments in
constrained calls via MakeGenericMethod.

Defer full reflection-visible treatment from DescriptorMarker to
MarkStep via pending sets in Annotations, so that MarkStep can call
MarkMethodVisibleToReflection, MarkFieldVisibleToReflection, and
MarkTypeVisibleToReflection on the declaring type. This ensures:
- Static abstract interface implementations are preserved
- Implicit fields for explicit-layout types are preserved
- Metadata names are not swept
- TypeMap entries are processed

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Clarify that GetCurrentMethod produces IL2026 but the suppression is
justified because the descriptor preserves the method. Add
ExpectedNoWarnings to the explicit layout test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
- Remove unnecessary #pragma warning disable IL2060 from tests
- Add ExpectedNoWarnings to explicit layout test
- Remove issue references from test comments
- Clarify comment about IL2026 suppression justification
- Expose pending sets as properties, inline clear in ProcessMarkedPending
- Separate doc comments for method and field pending sets

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Copilot AI review requested due to automatic review settings May 15, 2026 22:55
@github-actions github-actions Bot added the area-Tools-ILLink .NET linker development as well as trimming analyzers label May 15, 2026
@dotnet-policy-service dotnet-policy-service Bot added the linkable-framework Issues associated with delivering a linker friendly framework label May 15, 2026
@sbomer sbomer force-pushed the descriptor-abstract branch from bf799c8 to 323fb3e Compare May 15, 2026 22:56
@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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 updates the ILLink marking pipeline so that members preserved via XML descriptors are treated as reflection-visible, and it additionally marks their declaring types as reflection-visible to preserve reflection-dependent semantics (e.g., variant casting behaviors and explicit-layout field preservation).

Changes:

  • Add pending-tracking for descriptor-preserved methods/fields and process them in MarkStep via Mark*VisibleToReflection, also marking declaring types reflection-visible.
  • Extend DescriptorMarker to schedule descriptor-preserved fields/methods for reflection-visible processing.
  • Add new linker test cases + descriptors validating static abstract interface implementations and explicit-layout fields are preserved when reachability is via descriptor-preserved members.
Show a summary per file
File Description
src/tools/illink/src/linker/Linker/Annotations.cs Adds pending collections/APIs to schedule descriptor-preserved members for reflection-visible processing.
src/tools/illink/src/linker/Linker.Steps/MarkStep.cs Drains pending reflection-visible members and marks members + declaring types as reflection-visible.
src/tools/illink/src/linker/Linker.Steps/DescriptorMarker.cs Schedules descriptor-preserved fields/methods for reflection-visible handling.
src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/StaticAbstractMethodsPreservedViaDescriptor.cs New regression test for static abstract interface implementations preserved via descriptor reachability.
src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/StaticAbstractMethodsPreservedViaDescriptor.xml Descriptor roots methods used by the static-abstract preservation test.
src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/DescriptorPreservedTypeIsReflectionVisible.cs New test validating descriptor-preserved type is fully treated as reflection-visible (variant casting + explicit layout fields).
src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/DescriptorPreservedTypeIsReflectionVisible.xml Descriptor roots methods used by the reflection-visible type behavior test.

Copilot's findings

  • Files reviewed: 8/8 changed files
  • Comments generated: 3

Comment thread src/tools/illink/src/linker/Linker.Steps/MarkStep.cs Outdated
Comment thread src/tools/illink/src/linker/Linker/Annotations.cs Outdated
sbomer and others added 3 commits May 15, 2026 16:35
ILTrim does not support static abstract interface methods or
descriptor-based reflection-visible marking.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
- Convert tabs to spaces in test files to match .editorconfig
- Remove spaces before parentheses to match neighbor test style
- Make pending reflection-visible APIs internal

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Pass DependencyInfo and MessageOrigin from DescriptorMarker through to
MarkStep so warnings and dependency tracking attribute correctly to the
descriptor XML location. Encapsulate the pending data behind a
DrainPendingReflectionVisibleMembers method.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot's findings

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

Comment thread src/tools/illink/src/linker/Linker/Annotations.cs Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 16, 2026 00:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot's findings

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

Comment thread src/tools/illink/src/linker/Linker/Annotations.cs Outdated
sbomer and others added 2 commits May 16, 2026 15:12
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
…o from pending sets

Descriptor provenance is already recorded in the tracer via
Annotations.Mark. The reflection-visible drain just adds extra
treatment on top, matching the existing pattern where
ProcessMarkedPending uses AlreadyMarked.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Copilot AI review requested due to automatic review settings May 18, 2026 19:44
Copilot AI review requested due to automatic review settings May 26, 2026 18:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 11/11 changed files
  • Comments generated: 3

Comment thread src/tools/illink/src/linker/Linker.Steps/MarkStep.cs Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomer and others added 3 commits May 26, 2026 14:01
NativeAOT doesn't cascade MarkMethodVisibleToReflection to declaring
type the same way ILLink does, so TargetType4 is only kept by the
Trimmer tool.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
For consistency with MarkMethodVisibleToReflection, mark the declaring
type as reflection-visible inside MarkFieldVisibleToReflection itself
rather than special-casing it in the descriptor drain loop.

Update TypeWithPreserveFieldsHasBackingFieldsOfPropertiesRemoved to
expect marked interfaces are kept on reflection-visible types.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Copilot AI review requested due to automatic review settings May 27, 2026 21:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 12/12 changed files
  • Comments generated: 0 new

sbomer and others added 2 commits May 27, 2026 14:50
…isible

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
ILTrim doesn't have MarkMethodVisibleToReflection/MarkFieldVisibleToReflection
declaring-type changes, so interfaces are still stripped there. Mark
the new expectations as Trimmer-only and add the tests to the ILTrim
expected failures baseline.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Comment thread src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeMap.cs
Comment thread src/tools/illink/src/linker/Linker.Steps/DescriptorMarker.cs
Comment thread src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeMap.cs Outdated
Comment thread src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeMap.cs
Add pending reflection-visible type infrastructure so that
preserve="nothing" types get MarkTypeVisibleToReflection treatment
in MarkStep. Apply Michal's suggested comment for TypeMap test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Copilot AI review requested due to automatic review settings June 3, 2026 16:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 12/12 changed files
  • Comments generated: 2

Comment thread src/tools/illink/src/linker/Linker.Steps/MarkStep.cs
Comment thread src/tools/illink/src/linker/Linker.Steps/MarkStep.cs
Avoid redundant MarkTypeVisibleToReflection calls when iterating
multiple methods/fields on the same declaring type.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
@sbomer
Copy link
Copy Markdown
Member Author

sbomer commented Jun 4, 2026

/ba-g "deadlettered work items"

@sbomer sbomer merged commit 4c16f5f into dotnet:main Jun 4, 2026
129 of 134 checks passed
@github-project-automation github-project-automation Bot moved this to Done in AppModel Jun 4, 2026
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview6 milestone Jun 5, 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.

Referencing type from ILLink.Descriptors doesn't preserve its static abstracts

4 participants