Skip to content

Implement trimming support for the Interop Type Map #116555

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

jkoritzinsky
Copy link
Member

@jkoritzinsky jkoritzinsky commented Jun 11, 2025

Depends on #116355

Completes #110691

@jkoritzinsky jkoritzinsky added blocked Issue/PR is blocked on something - see comments area-Tools-ILLink .NET linker development as well as trimming analyzers labels Jun 11, 2025
@jkoritzinsky jkoritzinsky mentioned this pull request Jun 10, 2025
9 tasks
@dotnet-policy-service dotnet-policy-service bot added the linkable-framework Issues associated with delivering a linker friendly framework label Jun 11, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/illink
See info in area-owners.md if you want to be subscribed.

@jkoritzinsky jkoritzinsky marked this pull request as ready for review June 20, 2025 19:37
@@ -90,6 +92,8 @@ internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeH
}
}

internal TypeMapHandler TypeMapHandler => _typeMapHandler;
Copy link
Member

Choose a reason for hiding this comment

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

I think this is unused

@@ -742,6 +742,11 @@ public bool IsWarningSuppressed (int warningCode, string subcategory, MessageOri
if (Suppressions == null)
return false;

// Don't warn for RUC on assembly attributes.
// There's no way to suppress it.
if (warningCode == 2026 && origin.Provider is AssemblyDefinition)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (warningCode == 2026 && origin.Provider is AssemblyDefinition)
if (warningCode == DiagnosticId.RequiresUnreferencedCode && origin.Provider is AssemblyDefinition)


public void SetEntryPointAssembly(AssemblyDefinition asmDef)
{
Debug.Assert (entry_assembly is null);
Copy link
Member

Choose a reason for hiding this comment

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

There might be multiple root assemblies. Could we just give all root assemblies this treatment?

Copy link
Member Author

Choose a reason for hiding this comment

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

We specifically want to have the "assembly with the entrypoint main method" be the one that roots type map discovery. We don't want to scan type maps for assemblies that are separately fully rooted.

RecordTargetTypeSeen (definition, _unmarkedExternalTypeMapEntries, _referencedExternalTypeMaps, _pendingExternalTypeMapEntries);
}

void RecordTargetTypeSeen (TypeDefinition targetType, Dictionary<TypeDefinition, Dictionary<TypeReference, List<CustomAttributeWithOrigin>>> unmarkedTypeMapAttributes, HashSet<TypeReference> referenceTypeMapGroups, Dictionary<TypeReference, List<CustomAttributeWithOrigin>> typeMapAttributesPendingUniverseMarking)
Copy link
Member

Choose a reason for hiding this comment

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

nit: format these with one argument per line

return;
}
if (attr.Attribute.ConstructorArguments is [_, { Value: TypeReference target }]) {
// This is a TypeMapAssemblyTargetAttribute, which has a single type argument.
Copy link
Member

Choose a reason for hiding this comment

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

This comment doesn't seem to match the check

Copy link
Member

Choose a reason for hiding this comment

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

Currently it looks like the two forms of the external type map attribute both use the same logic for trimTarget and target - is that intentional? My understanding was that the trimTarget variant was supposed to be the only one that participates in the conditional logic, and the (string, Type target) variant was supposed to be kept whether or not the target type is otherwise marked.

Copy link
Member Author

Choose a reason for hiding this comment

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

I implemented it in this way with the NativeAOT implementation and updated the design doc (commited in that PR) with the adjusted rule.

I believe that with the expanded rules for including trimTarget entries, it's impossible to tell the difference in a correctly-written app if the (string, Type) overload always preserves or only does when the Type is marked.

Copy link
Member

Choose a reason for hiding this comment

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

If there's an instance of the (string, Type) attribute with an otherwise unused type, I am expecting the external type mapping to contain this entry. Whereas for an instance of the (string, Type target, Type trimTarget) overload with an otherwise unused trimTarget, I expect it not to contain this entry. Is that right? @AaronRobinsonMSFT

void AddProxyTypeMapEntry (TypeReference group, CustomAttributeWithOrigin attr)
{
if (attr.Attribute.ConstructorArguments is [{ Value: TypeReference sourceType }, _]) {
// This is a TypeMapAssociationAttribute, which has a single type argument.
Copy link
Member

Choose a reason for hiding this comment

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

nit: comment is slightly misleading since the attribute has two type arguments

@@ -13,5 +13,9 @@ public abstract class MarkContext
public abstract void RegisterMarkTypeAction (Action<TypeDefinition> action);

public abstract void RegisterMarkMethodAction (Action<MethodDefinition> action);

public virtual void RegisterMarkInstantiatedAction (Action<TypeDefinition> action)
Copy link
Member

Choose a reason for hiding this comment

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

unused I think

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 blocked Issue/PR is blocked on something - see comments linkable-framework Issues associated with delivering a linker friendly framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Interop Type Mapping
3 participants