Skip to content

F# 10 - Class hierarchy employing CRGP now produces compile error FS0193 #19037

@jwosty

Description

@jwosty

A certain code pattern utilizing CRGP (Curiously Recurring Generic Pattern) which successfully compiles under the F# 9 compiler no longer compiles under the F# 10 compiler.

In the real scenario, I encountered this with a type hierarchy implementing IEquatable<'T>.

Repro steps

  1. Create an F# library project. Paste the following into Library.fs:
module MyModule

type IFoo<'T when 'T :> IFoo<'T>> =
    abstract member Bar: other:'T -> unit

[<AbstractClass>]
type FooBase() =
    
    interface IFoo<FooBase> with
        member this.Bar (other: FooBase) = ()

[<Sealed>]
type FooDerived<'T>() =
    inherit FooBase()
    
    interface IFoo<FooDerived<'T>> with
        member this.Bar other = ()

type IFooContainer<'T> =
    abstract member Foo: FooDerived<'T>

let inline bar<'a when 'a :> IFoo<'a>> (x: 'a) (y: 'a) = x.Bar y
let inline takeSame<'a> (x: 'a) (y: 'a) = ()

// Successfully compiles under .NET 9 + F# 9
// Error under .NET 10 + F# 10: Program.fs(26,13): Error FS0193 : The type 'FooDerived<'TId>' does not match the type 'FooBase'
let callBar_NewlyBroken (foo1: IFooContainer<'TId>) (foo2: IFooContainer<'TId>) =
    bar foo1.Foo foo2.Foo
    
// Successfully compiles under both versions
let callBar (foo1: IFooContainer<'TId>) (foo2: IFooContainer<'TId>) =
    let id1 = foo1.Foo
    let id2 = foo2.Foo
    bar id1 id2
  1. Target .NET 9 in project and global.json (I tested under .NET SDK 9.0.111 + F# Compiler version 12.9.100.0 for F# 9.0)
  2. Run dotnet build
  3. Observe that the project builds successfully
  4. Change target in project and global.json to latest .NET 10 preview (at the time of writing .NET SDK 10.0.100-rc.2.25502.107 + F# Compiler version 14.0.100.0 for F# 10.0)
  5. Run dotnet build
  6. Observe F# compile error: Error FS0193 : The type 'FooDerived<'TId>' does not match the type 'FooBase'

Expected behavior

Project should compile successfully

Actual behavior

The F# compiler produces an error: Error FS0193 : The type 'FooDerived<'TId>' does not match the type 'FooBase'

Known workarounds

Provide additional annotations, or introduce additional variable bindings to get type inference to succeed.

Related information

Provide any related information (optional):

  • Operating system
  • .NET SDK 10.0.100-rc.2.25502.107
  • F# Compiler version 12.9.100.0 for F# 9.0
  • Editing Tools (e.g. Visual Studio Version, Visual Studio)

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    New

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions