Backwards compatibility broken
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 11h
- Merged PRs (30d)
- 131
Description
The following code is compiled differently in F#9, depending on which SDK is used ( 8 vs 9, in both cases targeting net8 )
```fsharp
type Default3 = class end
type Default2 = class inherit Default3 end
type Default1 = class inherit Default2 end
type IsAltLeftZero =
inherit Default1
static member inline IsAltLeftZero (_: ref<'T> when 'T : struct , _mthd: Default3) = false
static member inline IsAltLeftZero (_: ref<'T> when 'T : not struct, _mthd: Default2) = false
static member inline IsAltLeftZero (t: ref<'At> , _mthd: Default1) = (^At : (static member IsAltLeftZero : _ -> _) t.Value)
static member inline IsAltLeftZero (_: ref< ^t> when ^t: null and ^t: struct , _mthd: Default1) = ()
static member IsAltLeftZero (t: ref > , _mthd: IsAltLeftZero) = Option.isSome t.Value
static member IsAltLeftZero (t: ref >, _mthd: IsAltLeftZero) = ValueOption.isSome t.Value
static member IsAltLeftZero (t: ref> , _mthd: IsAltLeftZero) = match t.Value with (Ok _ ) -> true | _ -> false
static member IsAltLeftZero (t: ref> , _mthd: IsAltLeftZero) = match t.Value with (Choice1Of2 _) -> true | _ -> false
static member inline Invoke (x: 'At) : bool =
let inline call (mthd : ^M, input: ^I) =
((^M or ^I) : (static member IsAltLeftZero : _*_ -> _) (ref input), mthd)
call(Unchecked.defaultof, x)
```
Looking at the produced type for IsAltLeftZero there are some diffs in the `Invoke$W` method (I guess W stands for witness)
```
// F#8 => Boolean Invoke$W[At](FSharpFunc`2[At,Boolean], FSharpFunc`2[FSharpRef`1[At],FSharpFunc`2[IsAltLeftZero,Boolean]], At);
// F#9 => Boolean Invoke$W[At]( FSharpFunc`2[FSharpRef`1[At],FSharpFunc`2[IsAltLeftZero,Boolean]], At);
```
At the end of the day, the problem is when using the produced dll, from F# 9, the following call will fail when compiled with sdk 8
```fsharp
> IsAltLeftZero.Invoke None ;;
IsAltLeftZero.Invoke None ;;
---------------------^^^^
stdin(4,22): error FS0001: '.Invoke' does not support the type ''a option', because the latter lacks the required (real or built-in) member 'IsAltLeftZero'
```
**Known workarounds**
The only workaround is recompile everything in F#9
Note: I this is a major breaking change. Running SRTP code from FSharpPlus breaks in so many places (See https://github.com/fsprojects/FSharpPlus/issues/613) that I will be really surprised if this affects only F#+ code.
Contributor guide
Assessment
This issue has not been assessed yet.