Allow inref-argument members to satisfy SRTP constraints
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 + bis not a method call but a call to the F# library operator for(+)with its SRTP constraint -
the
inrefversion 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.
I think it makes sense to allow this, if indeed feasible. I wonder if it would also solve issues like #1360 (possibly using inline).