dotnet / dotnet/fsharp

Emit diagnostic for ambiguous interface method call

Open
#7,280 5 comments 1 reaction 0 assignees View on GitHub
Area-Diagnostics Feature Improvement
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

I noticed strange behavior when making a method call on an interface where there is ambiguity between two inherited interfaces with the same method signature. In C#, the method call is not allowed and is asked to disambiguate by being explicit with either interface. In F#, there is no error, and the behavior is rather odd. This is existing behavior and only noticed it when writing DIM tests.

```fsharp
open System

type IA1 =

abstract M: unit -> unit

type IB1 =

abstract M: unit -> unit

type I1 =
inherit IA1
inherit IB1

type Test () =

interface IA1 with

member __.M () = Console.Write("IA1")

interface IB1 with

member __.M () = Console.Write("IB1")

interface I1

[]
let main _ =
let x = Test () :> I1
x.M ()
0
```
Prints: `IB1`

In C# (tested with 4 and 8):
```csharp
using System;

namespace CSharpTest
{
public interface IA1
{
void M();
}

public interface IB1
{
void M();
}

public interface I1 : IA1, IB1
{

}

public class Test : I1
{
void IA1.M()
{
Console.Write("IA1");
}

void IB1.M()
{
Console.Write("IB1");
}
}

class Program
{
static void Main(string[] args)
{
I1 x = new Test();
x.M();
}
}
}
```
Errors with:
```
CS0121 The call is ambiguous between the following methods or properties: 'IA1.M()' and 'IB1.M()'
```

In the F# example, swapping the order of the inherited interfaces:
```fsharp
type I1 =
inherit IA1
inherit IB1
```
to
```fsharp
type I1 =
inherit IB1
inherit IA1
```
Will change the print output to: `IA1`

I can't think of a design where this makes sense. I'd argue this is a bug and dangerous. We should fix it even in F# 4.6 version.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.