-
Notifications
You must be signed in to change notification settings - Fork 11
Closed
Labels
bugSomething isn't workingSomething isn't workingtopic: taskseq-ceRelated to the taskseq computation expression builders or overloadsRelated to the taskseq computation expression builders or overloads
Milestone
Description
F# fails to determine which overload of TaskSeqBuilder.Using to use when type implements both IDisposable and IAsyncDisposable.
A real-world example with the NpgsqlDataReader type from Npgsql:
#r "nuget: Npgsql"
#r "nuget: FSharp.Control.TaskSeq"
open Npgsql
open FSharp.Control
let readRows (command: NpgsqlCommand) (ct: CancellationToken) f = taskSeq {
use! reader = command.ExecuteReaderAsync ct // Fails to compile.
let! reader = command.ExecuteReaderAsync ct
use reader = reader // Also fails to compile.
}Below is a set of test cases replicating the issue.
#r "nuget: FSharp.Control.TaskSeq"
#r "nuget: Xunit"
#r "nuget: FsUnit"
open System
open System.Threading.Tasks
open FSharp.Control
open FsUnit
open Xunit
type private OneGetter() =
member _.Get1() = 1
type private Disposable() =
inherit OneGetter()
interface IDisposable with
member _.Dispose() = ()
type private AsyncDisposable() =
inherit OneGetter()
interface IAsyncDisposable with
member _.DisposeAsync() = ValueTask()
type private MultiDispose() =
inherit OneGetter()
interface IDisposable with
member _.Dispose() =
()
interface IAsyncDisposable with
member _.DisposeAsync() =
ValueTask()
let private check ts = task {
let! length = ts |> TaskSeq.length
length |> should equal 1
}
[<Fact>]
let ``CE task: Using when type implements IDisposable``() =
let ts = taskSeq {
use x = new Disposable()
yield x.Get1()
}
check ts
[<Fact>]
let ``CE task: Using when type implements IAsyncDisposable``() =
let ts = taskSeq {
use x = AsyncDisposable()
yield x.Get1()
}
check ts
[<Fact>]
let ``CE task: Using when type implements IDisposable and IAsyncDisposable``() =
let ts = taskSeq {
use x = new MultiDispose() // Fails to compile
yield x.Get1()
}
check ts
[<Fact>]
let ``CE task: Using! when type implements IDisposable``() =
let ts = taskSeq {
use! x = task { return new Disposable() }
yield x.Get1()
}
check ts
[<Fact>]
let ``CE task: Using! when type implements IAsyncDisposable``() =
let ts = taskSeq {
use! x = task { return AsyncDisposable() }
yield x.Get1()
}
check ts
[<Fact>]
let ``CE task: Using! when type implements IDisposable and IAsyncDisposable``() =
let ts = taskSeq {
use! x = task { return new MultiDispose() } // Fails to compile
yield x.Get1()
}
check tsabelbraaksma
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingtopic: taskseq-ceRelated to the taskseq computation expression builders or overloadsRelated to the taskseq computation expression builders or overloads