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

Implement two pass algorithm for variant interface dispatch #21355

Merged
merged 2 commits into from Dec 14, 2018

Conversation

@MichalStrehovsky
Copy link
Member

MichalStrehovsky commented Dec 4, 2018

Fixes #20452.

Fixes #20452.
@MichalStrehovsky MichalStrehovsky added this to the 3.0 milestone Dec 4, 2018
@MichalStrehovsky MichalStrehovsky added this to TODO in Default Interface Methods via automation Dec 4, 2018
@MichalStrehovsky MichalStrehovsky requested a review from davidwrighton Dec 4, 2018
@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 4, 2018

Copy link
Member

davidwrighton left a comment

I think we covered the diamond case in discussion, but not the non-diamond case. Please add handling for non-diamond scenarios.

@@ -7323,6 +7347,11 @@ BOOL MethodTable::FindDefaultInterfaceImplementation(
{
pBestCandidateMT = candidates[i].pMT;
pBestCandidateMD = candidates[i].pMD;

// If this is a second pass lookup, we know this is a variant match. As such

This comment has been minimized.

Copy link
@davidwrighton

davidwrighton Dec 5, 2018

Member

I think I'm starting to understand some of the discussions from email in the last week or so. I don't see a problem with avoiding throwing in the diamond case where there are two most specific implementations, and I believe we should pick some implementation, but I do have a concern that we should be picking between the most specific implementations, not simply picking any possible implementation.

Imagine,

interface IFoo<in T> { string M() { return "IFoo:" + typeof(T).Name; } }
interface IRequiresImpInterface<in T> : IFoo<in T> { string IFoo<T>.M() { return "IRequiresImpInterface:" + typeof(T).Name; } }

class Base {}
class Derived : Base {}

class Test : IFoo<Base>, IRequiresImpInterface<Base>
{
    static void Main()
    {
        var t = new Test();
        ((IFoo<Base>)t).M(); // Clearly calls IRequiresImpInterface<Base>.M()
        ((IFoo<Derived>)t).M(); // I think becomes order dependent in this implementation between calling IRequiresImpInterface<Base> and IFoo<Base> That doesn't seem right to me. I believe it should unambiguously call IRequiresImpInterface<Base>.M()
    }
}

This comment has been minimized.

Copy link
@davidwrighton

davidwrighton Dec 5, 2018

Member

Also if that test above gets codified, it should have the cases in IL where class Test explicitly implements IRequiresImpInterface only, the case where it implements IFoo before IRequiresImpInterface, and the one where it implements IFoo after IRequiresImpInterface.

This comment has been minimized.

Copy link
@davidwrighton

davidwrighton Dec 5, 2018

Member

@AlekseyTs please chime in if you disagree.

This comment has been minimized.

Copy link
@AlekseyTs

AlekseyTs Dec 5, 2018

I agree. Only methods that implement interfaces that class explicitly claims to implement in metadata should be considered as candidates for variant interface dispatch. In the example above, method M in IFoo<Base> doesn't implement any interface that class Test implements. IFoo<T>.M in IRequiresImpInterface<Base> implements method IFoo<Base>.M for class Test. I assume implementations in base classes are handled similarly, i.e. only implementations from most derived bases are considered for variant interface dispatch.

This comment has been minimized.

Copy link
@MichalStrehovsky

MichalStrehovsky Dec 5, 2018

Author Member

It already works that way. The loop that builds the list of candidates already kicks out those that are not most specific. In the second loop (where this comment is attached) we only go over the list of the most specific candidates to see which one is first (for the variant case) or which one is the only one that we came up with (or throw) for the non-variant case.

I've pushed out a commit that adds the test case from your comment to demonstrate we only consider the most specific ones. In that case, the variant dispatch is unambiguous because there's only one most specific implementation for it.

@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 12, 2018

@dotnet-bot test this please

@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 12, 2018

@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test

@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 12, 2018

@dotnet-bot test this please

@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 12, 2018

@dotnet-bot test Ubuntu arm Cross Checked Innerloop Build and Test
@dotnet-bot test Ubuntu arm Cross Checked no_tiered_compilation_innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test (Jit - TieredCompilation=0)

1 similar comment
@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 13, 2018

@dotnet-bot test Ubuntu arm Cross Checked Innerloop Build and Test
@dotnet-bot test Ubuntu arm Cross Checked no_tiered_compilation_innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test (Jit - TieredCompilation=0)

@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 13, 2018

This keeps failing with weird Jenkinsonisms (java.lang.UnsupportedOperationException: Refusing to marshal org.kohsuke.github.GHUser for security reasons; see https://jenkins.io/redirect/class-filter/). I'll just close and reopen...

Default Interface Methods automation moved this from TODO to Done Dec 13, 2018
Default Interface Methods automation moved this from Done to TODO Dec 13, 2018
@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 13, 2018

Seems like Jenkins is not going to give up to Azure DevOps without making our lives miserable for a bit more.

@dotnet-bot test OSX10.12 x64 Checked Innerloop Build and Test
@dotnet-bot test Ubuntu arm Cross Checked Innerloop Build and Test
@dotnet-bot test Ubuntu arm Cross Checked no_tiered_compilation_innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test (Jit - TieredCompilation=0)
@dotnet-bot test Windows_NT x64 Checked CoreFX Tests
@dotnet-bot test Windows_NT x64 Checked Innerloop Build and Test
@dotnet-bot test Windows_NT x64 Release CoreFX Tests

@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 13, 2018

@dotnet-bot test OSX10.12 x64 Checked Innerloop Build and Test
@dotnet-bot test Ubuntu arm Cross Checked Innerloop Build and Test
@dotnet-bot test Ubuntu arm Cross Checked no_tiered_compilation_innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test (Jit - TieredCompilation=0)

1 similar comment
@MichalStrehovsky

This comment has been minimized.

Copy link
Member Author

MichalStrehovsky commented Dec 14, 2018

@dotnet-bot test OSX10.12 x64 Checked Innerloop Build and Test
@dotnet-bot test Ubuntu arm Cross Checked Innerloop Build and Test
@dotnet-bot test Ubuntu arm Cross Checked no_tiered_compilation_innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test
@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test (Jit - TieredCompilation=0)

@MichalStrehovsky MichalStrehovsky merged commit 1649da1 into dotnet:master Dec 14, 2018
31 checks passed
31 checks passed
CentOS7.1 x64 Checked Innerloop Build and Test Build finished.
Details
CentOS7.1 x64 Debug Innerloop Build Build finished.
Details
Linux-musl x64 Debug Build Build finished.
Details
OSX10.12 x64 Checked Innerloop Build and Test Build finished.
Details
Tizen armel Cross Checked Innerloop Build and Test Build finished.
Details
Ubuntu arm Cross Checked Innerloop Build and Test Build finished.
Details
Ubuntu arm Cross Checked crossgen_comparison Build and Test Build finished.
Details
Ubuntu arm Cross Checked no_tiered_compilation_innerloop Build and Test Build finished.
Details
Ubuntu arm Cross Release crossgen_comparison Build and Test Build finished.
Details
Ubuntu x64 Checked CoreFX Tests Build finished.
Details
Ubuntu x64 Checked Innerloop Build and Test Build finished.
Details
Ubuntu x64 Checked Innerloop Build and Test (Jit - TieredCompilation=0) Build finished.
Details
Ubuntu x64 Formatting Build finished.
Details
Ubuntu16.04 arm64 Cross Checked Innerloop Build and Test Build finished.
Details
Ubuntu16.04 arm64 Cross Checked no_tiered_compilation_innerloop Build and Test Build finished.
Details
WIP Ready for review
Details
Windows_NT arm Cross Debug Innerloop Build Build finished.
Details
Windows_NT arm64 Cross Debug Innerloop Build Build finished.
Details
Windows_NT x64 Checked CoreFX Tests Build finished.
Details
Windows_NT x64 Checked Innerloop Build and Test Build finished.
Details
Windows_NT x64 Checked Innerloop Build and Test (Jit - TieredCompilation=0) Build finished.
Details
Windows_NT x64 Formatting Build finished.
Details
Windows_NT x64 Release CoreFX Tests Build finished.
Details
Windows_NT x64 full_opt ryujit CoreCLR Perf Tests Correctness Build finished.
Details
Windows_NT x64 min_opt ryujit CoreCLR Perf Tests Correctness Build finished.
Details
Windows_NT x86 Checked Innerloop Build and Test Build finished.
Details
Windows_NT x86 Checked Innerloop Build and Test (Jit - TieredCompilation=0) Build finished.
Details
Windows_NT x86 Release Innerloop Build and Test Build finished.
Details
Windows_NT x86 full_opt ryujit CoreCLR Perf Tests Correctness Build finished.
Details
Windows_NT x86 min_opt ryujit CoreCLR Perf Tests Correctness Build finished.
Details
license/cla All CLA requirements met.
Details
Default Interface Methods automation moved this from TODO to Done Dec 14, 2018
@MichalStrehovsky MichalStrehovsky deleted the MichalStrehovsky:twopassvariance branch Dec 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants
You can’t perform that action at this time.