-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ILLink: Allow interface methods to not have newslot (#93662)
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.
- Loading branch information
1 parent
c7479b9
commit 6936887
Showing
6 changed files
with
161 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
53 changes: 53 additions & 0 deletions
53
...st/Mono.Linker.Tests.Cases/Inheritance.Interfaces/Dependencies/InterfaceWithoutNewSlot.il
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
.assembly extern mscorlib { } | ||
|
||
.assembly 'library' { } | ||
|
||
.class interface public auto ansi abstract IInterfaceWithoutNewSlot | ||
{ | ||
.method public hidebysig abstract virtual | ||
instance void AbstractNoNewSlot () cil managed | ||
{ | ||
} | ||
|
||
.method public hidebysig abstract virtual | ||
instance void AbstractNoNewSlotUnused () cil managed | ||
{ | ||
} | ||
|
||
.method public hidebysig newslot abstract virtual | ||
instance void AbstractNewSlot () cil managed | ||
{ | ||
} | ||
|
||
.method public hidebysig newslot abstract virtual | ||
instance void AbstractNewSlotUnused () cil managed | ||
{ | ||
} | ||
|
||
.method public hidebysig virtual | ||
instance void ImplementedNoNewSlot () cil managed | ||
{ | ||
ret; | ||
} | ||
|
||
.method public hidebysig virtual | ||
instance void ImplementedNoNewSlotUnused () cil managed | ||
{ | ||
ret; | ||
} | ||
|
||
.method public hidebysig newslot virtual | ||
instance void ImplementedNewSlot () cil managed | ||
{ | ||
ret; | ||
} | ||
|
||
.method public hidebysig newslot virtual | ||
instance void ImplementedNewSlotUnused () cil managed | ||
{ | ||
ret; | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
...ols/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceWithoutNewSlot.cs
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Mono.Linker.Tests.Cases.Expectations.Assertions; | ||
using Mono.Linker.Tests.Cases.Expectations.Metadata; | ||
|
||
namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces | ||
{ | ||
// Tests the case where the interface method doesn't have 'newslot' flag set | ||
[TestCaseRequirements (TestRunCharacteristics.SupportsDefaultInterfaceMethods, "Requires support for default interface methods")] | ||
[Define ("IL_ASSEMBLY_AVAILABLE")] | ||
[SetupCompileBefore ("library.dll", new[] { "Dependencies/InterfaceWithoutNewSlot.il" })] | ||
class InterfaceWithoutNewSlot | ||
{ | ||
public static void Main () | ||
{ | ||
ImplementationType.Test (); | ||
} | ||
|
||
#if !IL_ASSEMBLY_AVAILABLE | ||
// Declaration for the build of the test suite | ||
// When compiled for actual run the IL version is used instead | ||
// This is because there's no way to express the newslot/no-newslot in C# | ||
interface IInterfaceWithoutNewSlot | ||
{ | ||
void AbstractNoNewSlot (); | ||
void AbstractNoNewSlotUnused (); | ||
void AbstractNewSlot (); | ||
void AbstractNewSlotUnused (); | ||
void ImplementedNoNewSlot () { } | ||
void ImplementedNoNewSlotUnused () { } | ||
void ImplementedNewSlot () { } | ||
void ImplementedNewSlotUnused () { } | ||
} | ||
#endif | ||
|
||
[Kept] | ||
[KeptInterface (typeof (IInterfaceWithoutNewSlot))] | ||
[KeptMember (".ctor()")] | ||
class ImplementationType : IInterfaceWithoutNewSlot | ||
{ | ||
[Kept] | ||
public void AbstractNoNewSlot () { } | ||
|
||
public void AbstractNoNewSlotUnused () { } | ||
|
||
[Kept] | ||
public void AbstractNewSlot () { } | ||
|
||
public void AbstractNewSlotUnused () { } | ||
|
||
// This is not considered an implementation of the interface method | ||
// CoreCLR doesn't treat it that way either. | ||
public void ImplementedNoNewSlot () { } | ||
|
||
public void ImplementedNoNewSlotUnused () { } | ||
|
||
[Kept] | ||
public void ImplementedNewSlot () { } | ||
|
||
public void ImplementedNewSlotUnused () { } | ||
|
||
[Kept] | ||
public static void Test () | ||
{ | ||
IInterfaceWithoutNewSlot instance = new ImplementationType (); | ||
instance.AbstractNoNewSlot (); | ||
instance.AbstractNewSlot (); | ||
instance.ImplementedNoNewSlot (); | ||
instance.ImplementedNewSlot (); | ||
} | ||
} | ||
} | ||
} |