Skip to content

Code is not sufficiently generic #31

Open
@NinoFloris

Description

@NinoFloris

Was porting an old project (netcoreapp2.2) to 3.1 today, noticed something that did compile back then that doesn't anymore.

This code is not sufficiently generic. The type variable ^TEntity when ^TEntity : not struct could not be generalized because it would escape its scope

Note the compiler inferred an SRTP type var ^TEntity here even though no SRTP constraints are used.

open FSharp.Control.Tasks.V2.ContextInsensitive
open Microsoft.EntityFrameworkCore

type DbSet<'TEntity when 'TEntity: not struct> with
    member this.TryFindAsync(keyValues) = task {
        let! r = this.FindAsync(keyValues)
        if obj.ReferenceEquals(r, null) then return ValueNone
        else return ValueSome r
    }

What seems to have happened here is EF moving from returning Task<'T> in 2.x to ValueTask<'T> in 3.x that caused this error to surface.

I've produced a minimal repro

open FSharp.Control.Tasks.V2.ContextInsensitive

type Foo<'T> =
    member this.FindAsync() = ValueTask<_>(Unchecked.defaultof<'T>)
    member this.TryFindAsync() = task {
        let! r = this.FindAsync()
        if obj.ReferenceEquals(r, null) then return ValueNone
        else return ValueSome r
    }

My hunch is something is iffy around the SRTP based 'tasklike' Bind as ValueTask isn't directly supported.

Also, adding inline to the new member TryFindAsync to potentially flow the SRTP var doesn't work either and returns a different error:

The signature and implementation are not compatible because the type parameter in the class/signature has a different compile-time requirement to the one in the member/implementation

Finally to confirm my hunch I tried this code in Ply under netstandard2.0, where Ply has no explicit ValueTask overloads, only similar tasklike support, and under netcoreapp2.2 (which does have the overloads) both compile without errors. Something is going wrong with the SRTP constrained overloads in Taskbuilder.

/cc: @gusty

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions