dotnet / dotnet/fsharp

"Complex" generic constraints from c# interface can't be implemented

Open
#7,607 1 comment 2 reactions 0 assignees View on GitHub
Area-Compiler-Checking Bug Impact-Medium
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

The following works:

// csharp
public interface FromCSharp
{
void F(Enumerable source)
where Enumerable : System.Collections.IEnumerable;
}

// fsharp
type C<'T>() =
interface FromCSharp with
member __.F<'Enumerable
when 'Enumerable :> System.Collections.IEnumerable
> (e:'Enumerable) : unit = ()

The following more complex example doesn't (i.e. it introduces another generic type at the interface level):

// csharp
public interface FromCSharp
{
void F(Enumerable source)
where Enumerable : System.Collections.Generic.IEnumerable;
}
// fsharp
type C<'T>() =
interface FromCSharp<'T> with
member __.F<'Enumerable
when 'Enumerable :> System.Collections.Generic.IEnumerable<'T>
> (e:'Enumerable) : unit = ()

It fails with the following compliation error:

The member 'F<'Enumerable when 'Enumerable :> Collections.Generic.IEnumerable<'T>> : #Collections.Generic.IEnumerable<'T> -> unit' does not have the correct type to override the corresponding abstract method.

If you define the interface in fsharp it does work (even in a different assembly):

type FromFSharp<'T> =
abstract F<'Enumerable
when 'Enumerable :> System.Collections.Generic.IEnumerable<'T>> : 'Enumerable -> unit

type C<'T>() =
interface FromFSharp<'T> with
member __.F<'Enumerable
when 'Enumerable :> System.Collections.Generic.IEnumerable<'T>
> (e:'Enumerable) : unit = ()

No known work around, other than to define all interfaces in fsharp, which is obviously not always an option.

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.