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

ILLink: Allow interface methods to not have newslot #93662

Merged
merged 2 commits into from
Oct 27, 2023

Conversation

vitek-karas
Copy link
Member

Fixes #93008

This comes from F#, where interface method defined in F# doesn't have newslot flag in its metadata. Trimmer gets confused and doesn't recognize such method as a "base" method for its implementation in the type which implements the interface. As a result, the implementation method is removed from the program because there doesn't seem to be a use for it anywhere.

The fix is to basically ignore the newslot flag for interface instance methods. The existing behavior must be kept for static interface methods though - as a redefinition of a method with the new C# keyword will produce an interface method definition without the newslot flag as well.

The change adds a new test and modifies the AOT/analyzer infra to run the test as well.

Fixes dotnet#93008

This comes from F#, where interface method defined in F# doesn't have `newslot` flag in its metadata. Trimmer gets confused and doesn't recognize such method as a "base" method for its implementation in the type which implements the interface. As a result, the implementation method is removed from the program because there doesn't seem to be a use for it anywhere.

The fix is to basically ignore the `newslot` flag for interface instance methods. The existing behavior must be kept for static interface methods though - as a redefinition of a method with the `new` C# keyword will produce an interface method definition without the `newslot` flag as well.

The change adds a new test and modifies the AOT/analyzer infra to run the test as well.
@vitek-karas vitek-karas added the area-Tools-ILLink .NET linker development as well as trimming analyzers label Oct 18, 2023
@vitek-karas vitek-karas added this to the 9.0.0 milestone Oct 18, 2023
@vitek-karas vitek-karas self-assigned this Oct 18, 2023
@ghost
Copy link

ghost commented Oct 18, 2023

Tagging subscribers to this area: @agocke, @sbomer, @vitek-karas
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes #93008

This comes from F#, where interface method defined in F# doesn't have newslot flag in its metadata. Trimmer gets confused and doesn't recognize such method as a "base" method for its implementation in the type which implements the interface. As a result, the implementation method is removed from the program because there doesn't seem to be a use for it anywhere.

The fix is to basically ignore the newslot flag for interface instance methods. The existing behavior must be kept for static interface methods though - as a redefinition of a method with the new C# keyword will produce an interface method definition without the newslot flag as well.

The change adds a new test and modifies the AOT/analyzer infra to run the test as well.

Author: vitek-karas
Assignees: vitek-karas
Labels:

area-Tools-ILLink

Milestone: 9.0.0

Copy link
Member

@ivanpovazan ivanpovazan left a comment

Choose a reason for hiding this comment

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

Thank you for looking into this!

@MichalStrehovsky
Copy link
Member

MichalStrehovsky commented Oct 18, 2023

The existing behavior must be kept for static interface methods though - as a redefinition of a method with the new C# keyword will produce an interface method definition without the newslot flag as well.

Is there a test that exercises this? I wasn't able to get C# to produce a static virtual method with a newslot flag set. Was this code doing anything for static virtuals?

(I'm wondering if the fix shouldn't be to ignore all static methods. It seems like they're handled elsewhere.)

@vitek-karas
Copy link
Member Author

I made this modification due to a failing test. Specifically this:

We should remove the IInheritsFromBase.UsedOnBaseOnlyConstrainedTypeImplicitImpl because the call is made through the IBase1 and the implementation has method-impl for both the method on IBase1 as well as the "new" method on IInheritsFromBase. The "new" method doesn't get a newslot in IL, and so it was hitting the condition before the change.

@vitek-karas
Copy link
Member Author

I must admit that I don't know if IL allows for implicit implementation of a static virtual/abstract - that is done via method signature match and not relying on method-impl record. If it only allows this via method-impl records, then I agree we should just skip all static methods in this place (since the code after the if handles the method signature matching).

@MichalStrehovsky
Copy link
Member

Copy link
Member

@sbomer sbomer left a comment

Choose a reason for hiding this comment

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

Nice! LGTM, thank you for looking into this.

@vitek-karas vitek-karas merged commit 6936887 into dotnet:main Oct 27, 2023
131 of 134 checks passed
@vitek-karas vitek-karas deleted the NewSlotFix branch October 27, 2023 18:18
@ivanpovazan
Copy link
Member

@vitek-karas should we backport this to a servicing release?

liveans pushed a commit to liveans/dotnet-runtime that referenced this pull request Nov 9, 2023
Fixes dotnet#93008

This comes from F#, where interface method defined in F# doesn't have `newslot` flag in its metadata. Trimmer gets confused and doesn't recognize such method as a "base" method for its implementation in the type which implements the interface. As a result, the implementation method is removed from the program because there doesn't seem to be a use for it anywhere.

The fix is to basically ignore the `newslot` flag for interface instance methods. The existing behavior must be kept for static interface methods though - as a redefinition of a method with the `new` C# keyword will produce an interface method definition without the `newslot` flag as well.

The change adds a new test and modifies the AOT/analyzer infra to run the test as well.
@charlesroddie
Copy link

@vitek-karas should we backport this to a servicing release?

That would be very useful - effectively enabling F# support in dotnet8 ios nativeaot.

@vitek-karas
Copy link
Member Author

We discussed this couple of weeks ago, but then it was a weird time (right around the branches closing for RTM).
@agocke would you know which branch to backport this to for 8 servicing release?

@ivanpovazan
Copy link
Member

@vitek-karas it should be: /backport to release/8.0-staging

@vitek-karas
Copy link
Member Author

/backport to release/8.0-staging

Copy link
Contributor

github-actions bot commented Dec 4, 2023

Started backporting to release/8.0-staging: https://github.com/dotnet/runtime/actions/runs/7085143215

@github-actions github-actions bot locked and limited conversation to collaborators Jan 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Tools-ILLink .NET linker development as well as trimming analyzers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ILLink fails to resolve method's base interface method if the interface method doesn't have newslot
5 participants