No compile-time error when static abstract member accessed on type parameter whose resolved type has no concrete implementation for said member
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 144
Description
There is no compile-time error when:
1. You invoke a static abstract member on a type parameter that is constrained to be an interface with the given static abstract member (IWSAM).
2. The type variable for that type parameter is automatically constrained to be _the interface type itself_ (as opposed to a concrete type that has a concrete implementation of the member being invoked).
A `System.Runtime.AmbiguousImplementationException` is raised at runtime instead. This is raised even when the interface in question has only one static abstract member (or member of any kind).
**Repro steps**
```fsharp
#nowarn "3535"
type IFace =
static abstract P1 : int
type T =
interface IFace with
static member P1 = 1
let inline p1<'T & #IFace> = 'T.P1
let _ = p1 // 'T is resolved to be IFace itself.
```

#### `net8.0`
```stderr
Unhandled exception. System.Runtime.AmbiguousImplementationException: Could not call method 'Program+IFace.get_P1()' on interface 'Program+IFace' with type 'Program+IFace' from assembly '' because there are multiple incompatible interface methods overriding this method.
at .$Program.main@() in D:\src\ConsoleApp1\ConsoleApp1\Program.fs:line 12
```
#### `net9.0`
```stderr
Unhandled exception. System.Runtime.AmbiguousImplementationException: Ambiguous implementation found.
at .$Program.main@() in D:\src\ConsoleApp1\ConsoleApp1\Program.fs:line 12
```
**Expected behavior**
Resolution of the type variable should fail at compile-time in the absence of further type information when the type variable has a constraint involving static abstract members — although ideally it would only fail when an `abstract` (as opposed to `virtual`) member was actually being accessed, which is not visible through a constraint like `'T & #IFace` alone.
**Actual behavior**
A type variable like `'T & #IFace` resolves to the interface type `IFace` itself, and a `System.Runtime.AmbiguousImplementationException` is raised at runtime.
**Known workarounds**
Always manually ensure that all type variables are resolved to types with concrete implementations for all static abstract methods that are invoked on them.
**Related information**
.NET 8/9 preview.
This problem is similar in spirit to #14012, #16299, etc., although it might be a bit trickier to fix.
Contributor guide
Assessment
This issue has not been assessed yet.