Skip to content
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

Don't remove unused interfaces in library mode #2711

Merged
merged 14 commits into from
Apr 12, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions src/linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2287,12 +2287,18 @@ void MarkGenericParameter (GenericParameter parameter)
}

/// <summary>
/// Returns true if any of the base methods of the <paramref name="method"/> passed is in an assembly that is not trimmed (i.e. action != trim)
/// Returns true if any of the base methods of the <paramref name="method"/> passed is in an assembly that is not trimmed (i.e. action != trim).
/// Meant to be used to determine whether methods should be marked regardless of whether it is instantiated or not.
/// </summary>
/// <remarks>This ignores any base methods defined in interfaces. To also check methods defined in interfaces</remarks>
/// <remarks>
/// When the unusedinterfaces optimization is on, this is used to mark methods that override a virtual from a non-link assembly and must be kept.
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
/// When the unusedinterfaces optimization is on, this is used to mark methods that override a virtual from a non-link assembly and must be kept.
/// When the unusedinterfaces optimization is on, this is used to mark methods that override an abstract method from a non-link assembly and must be kept.

/// When the unusedinterfaces optimization is off, this will do the same as when on but will also mark interface methods from interfaces defined in a non-link assembly.
/// If the containing type is instantiated, the caller should use <see cref="IsOverrideNeededByInstantiatedTypeDueToPreservedScope (MethodDefinition)" />
/// </remarks>
bool IsVirtualNeededByTypeDueToPreservedScope (MethodDefinition method)
Copy link
Member

Choose a reason for hiding this comment

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

I would rename this to IsMethodNeededByTypeDueToPreservedScope - the caller uses it that way (the caller doesn't filter on virtuals - and it must not anyway).

{
if (!method.IsVirtual)
// Static methods may also have base methods in static interface methods. These methods are not captured by IsVirtual and must be checked separately
if (!(method.IsVirtual || method.IsStatic))
return false;

var base_list = Annotations.GetBaseMethods (method);
Expand Down Expand Up @@ -2322,12 +2328,17 @@ bool IsVirtualNeededByTypeDueToPreservedScope (MethodDefinition method)
}

/// <summary>
/// Returns true if any of the base methods of <paramref name="method" /> is defined in an assembly that is not trimmed (i.e. action!=trim)
/// Returns true if any of the base methods of <paramref name="method" /> is defined in an assembly that is not trimmed (i.e. action!=trim).
/// This is meant to be used on methods from a type that is known to be instantiated.
/// </summary>
/// <remarks>This is very similar to <see cref="IsVirtualNeededByTypeDueToPreservedScope(MethodDefinition)"/>, except this also checks if the base method is an interface.</remarks>
bool IsVirtualNeededByInstantiatedTypeDueToPreservedScope (MethodDefinition method)
/// <remarks>
/// This is very similar to <see cref="IsVirtualNeededByTypeDueToPreservedScope (MethodDefinition)"/>,
/// but will mark methods from an interface defined in a non-link assembly regardless of the optimization, and does not handle static interface methods.
/// </remarks>
bool IsOverrideNeededByInstantiatedTypeDueToPreservedScope (MethodDefinition method)
{
if (!(method.IsVirtual || method.IsStatic))
// Any static interface methods are captured by <see cref="IsVirtualNeededByTypeDueToPreservedScope">, which should be called on all relevant methods so no need to check again here.
if (!method.IsVirtual)
vitek-karas marked this conversation as resolved.
Show resolved Hide resolved
return false;

var base_list = Annotations.GetBaseMethods (method);
Expand Down Expand Up @@ -3126,7 +3137,7 @@ protected virtual void MarkRequirementsForInstantiatedTypes (TypeDefinition type
protected virtual IEnumerable<MethodDefinition> GetRequiredMethodsForInstantiatedType (TypeDefinition type)
{
foreach (var method in type.Methods) {
if (IsVirtualNeededByInstantiatedTypeDueToPreservedScope (method))
if (IsOverrideNeededByInstantiatedTypeDueToPreservedScope (method))
yield return method;
}
}
Expand Down