fslang-suggestions icon indicating copy to clipboard operation
fslang-suggestions copied to clipboard

Allow inref-argument members to satisfy SRTP constraints

Open dsyme opened this issue 5 years ago • 1 comments

Transferring https://github.com/dotnet/fsharp/issues/9018

This is related to FS-1053: voidptr, IsReadOnly structs, inref, outref, ByRefLike structs, byref extension members

In C#, you can mark the parameters of an overloaded operator as inref:

public readonly struct C
{
    public readonly int I {get;}
    public C(int i)
    {
        I = i;
    }
    
    public void M()
    {
        var c1 = new C(1);
        var c2 = new C(2);
        
        var c3 = c1 + c2;
    }
    
    public static C operator+ (in C a, in C b)
    {
        return new C(a.I + b.I);
    }
}

This operator is not directly usable in F#:

    let c1 = C(1)
    let c2 = C(1)
    let c3 = c1 + c2;

error FS0001: Type constraint mismatch. The type 'C' is not compatible with type 'inref<C>' error FS0043: Type constraint mismatch. The type 'C' is not compatible with type 'inref<C>'

As a workaround, you can explicitly call op_Addition:

let c3 = C.op_Addition(&c1, &c2)

For the first part, this is by design as things currently stand.

  • a + b is not a method call but a call to the F# library operator for (+) with its SRTP constraint

  • the inref version of the op_Addition member provided by C# does not satisfy this SRTP constraint

We could consider a language suggestion where members taking inref arguments can be considered to satisfy such constraints but it would need an RFC. I'm not sure of its technical feasiblity.

dsyme avatar Sep 01 '20 13:09 dsyme

I think it makes sense to allow this, if indeed feasible. I wonder if it would also solve issues like #1360 (possibly using inline).

abelbraaksma avatar May 19 '24 18:05 abelbraaksma