[ILLink] Fix crash when array types are used as TypeMap trim targets with PublishTrimmed#126380
Open
[ILLink] Fix crash when array types are used as TypeMap trim targets with PublishTrimmed#126380
Conversation
Strip parameterized types (array, pointer, etc.) from TypeMap trim targets and source types, using the element type instead. This fixes the crash when typeof(SomeType[]) is used as a trim target in TypeMap attributes during PublishTrimmed. Add test cases for array type trim targets (used and unused) to TypeMap.cs. Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/82e75422-6094-47d8-be6f-7a4527457908 Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix build failure for array TypeMap entries when PublishTrimmed
[ILLink] Fix crash when array types are used as TypeMap trim targets with PublishTrimmed
Mar 31, 2026
jkoritzinsky
approved these changes
Mar 31, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes an ILLink crash in PublishTrimmed when TypeMap attributes specify non-resolvable TypeSpecification types (notably arrays) as trim targets by stripping wrappers down to a resolvable element type before calling LinkContext.Resolve.
Changes:
- Normalize
TypeMaptrim targets and association source types by unwrappingTypeSpecification(array/pointer/byref/…) to an element type until reaching aTypeDefinitionorGenericInstanceType. - Add new linker test coverage for an array-type trim target scenario (kept case), and introduce a second unused-case scenario that should assert removal.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/tools/illink/src/linker/Linker/TypeMapHandler.cs |
Unwraps TypeSpecification wrappers before resolving trim targets / proxy source types to avoid NotSupportedException crashes. |
src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeMap.cs |
Adds test inputs for array-type trim targets and ensures at least the reachable-element case is preserved. |
Member
- Add RemovedTypeInAssembly("test", ...) for unused array trim target types
to make the expected removal behavior explicit
- Fix misleading comment in AddProxyTypeMapEntry: TypeMapAssociationAttribute
has two constructor type arguments (source and proxy), not one
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/8d0dbb63-91fb-4d87-8ccd-60e91da2e1e9
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Contributor
Author
Done in af0ac93:
Both |
jkoritzinsky
approved these changes
Apr 1, 2026
This was referenced Apr 1, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PublishTrimmedcrashes withNotSupportedException: TypeDefinition cannot be resolved from 'Mono.Cecil.ArrayType'when aTypeMapattribute specifies an array type as its trim target (e.g.,typeof(Foo[])).PublishAotis unaffected (handled in #123031).Root cause:
LinkContext.Resolvethrows for anyTypeSpecificationthat isn't aGenericInstanceType. Array types, pointer types, and byref types all fall into this category.Description
TypeMapHandler.AddExternalTypeMapEntry: Strip non-resolvableTypeSpecificationwrappers (array, pointer, byref, etc.) from the trim target before passing toRecordTypeMapEntry, using the element type instead. Loop terminates at the firstTypeDefinitionorGenericInstanceType(both resolvable).TypeMapHandler.AddProxyTypeMapEntry: Same fix applied symmetrically to the source type parameter. Corrected the comment to accurately state thatTypeMapAssociationAttributehas two constructor type arguments (source and proxy).The loop handles nested arrays (
Foo[][]→Foo), pointer types, and mixed cases likeList<Foo>[](strips toList<Foo>, which is aGenericInstanceTypeand resolvable).Customer Impact
PublishTrimmedbuilds fail with an unhandledNotSupportedException/ fatal ILLink error when any assembly attribute uses an array type as aTypeMaptrim target. No workaround short of removing the array type.Regression
No — this is a new feature (
TypeMap) that never handled array trim targets correctly in ILLink.Testing
Added test cases to
TypeMap.cs:TrimTargetIsUsedArrayType: array trim target whose element type is reachable — attribute must be preserved; verified withKeptAttributeAttribute.TrimTargetIsUnusedArrayType: array trim target whose element type is unreachable — attribute and target types are removed; verified with explicitRemovedTypeInAssembly("test", ...)assertions on bothArrayTypeTrimTargetUnusedClassandArrayTypeTrimTargetUnusedTarget.Both existing
Reflection.TypeMapandReflection.TypeMapEntryAssemblytests pass.Risk
Low. The change is localized to two private methods in
TypeMapHandler. The stripping logic mirrors the existingTypeSpecification/GenericInstanceTypeguard already present inLinkContext.Resolve. No behavior change for existing valid (non-array) trim targets.Package authoring no longer needed in .NET 9
IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.