Describe the bug
When I try to use use! node = tryGetNode path, I get an error that there is no Bind for IDisposable (more or less)
To Reproduce
open System
open System.Threading
open System.Threading.Tasks
open FsToolkit.ErrorHandling
type Node(name: string) =
member _.Name = name
interface IDisposable with
member _.Dispose() = printfn "disposed %s" name
let tryGetNode (path: string) : Task<Result<Node, string>> = Task.FromResult(Ok(new Node(path)))
// D: no member lookup inside -> shows which Using overload got committed
let caseD () =
cancellableTaskResult {
use! node = tryGetNode "d" // error here
return 1
}
printfn "D = %A" ((caseD () CancellationToken.None).Result)
Funnily enough, adding an annotation `use! (node : Node) = tryGetNode "d" ``` makes the error go away in Rider, but not in the compiler.
This:
let! (node : Node) = tryGetNode "d"
use _ = node
return 1
work just fine (but requires the annotation), but I don't like the fact that I have to do this
Expected behavior
The above should just work
I am getting an error:
d.fsx(20,9): error FS0041: No overloads match for method 'Bind'.
Known types of arguments: Runtime.CompilerServices.TaskAwaiter<Result<Node,string>> * ('a -> CancellableTaskResultBuilderBaseCode<int,int,'b,^c>) when 'a :> IAsyncDisposable and ^c: (member AwaitUnsafeOnCompleted: byref<Runtime.CompilerServices.ICriticalNotifyCompletion> * byref<CompilerServices.ResumableStateMachine<CancellableTaskResultBuilderBaseStateMachineData<int,'b,^c>>> -> unit)
Available overloads:
- member CancellableTaskResultBuilderBase.Bind: [<InlineIfLambda>] getAwaiterT: (CancellationToken -> ^Awaiter) * continuation: ('TResult1 -> CancellableTaskResultBuilderBaseCode<'TOverall,'TResult2,'Error,^Builder>) -> CancellableTaskResultBuilderBaseCode<'TOverall,'TResult2,'Error,^Builder> when ^Awaiter :> Runtime.CompilerServices.ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted: unit -> bool) and ^Awaiter: (member GetResult: unit -> 'TResult1) and ^Builder: (member AwaitUnsafeOnCompleted: byref<Runtime.CompilerServices.ICriticalNotifyCompletion> * byref<CompilerServices.ResumableStateMachine<CancellableTaskResultBuilderBaseStateMachineData<'TOverall,'Error,^Builder>>> -> unit) // Argument 'getAwaiterT' doesn't match
- member CancellableTaskResultBuilderBase.Bind: awaiterT: ^Awaiter * continuation: ('TResult1 -> CancellableTaskResultBuilderBaseCode<'TOverall,'TResult2,'Error,^Builder>) -> CancellableTaskResultBuilderBaseCode<'TOverall,'TResult2,'Error,^Builder> when ^Awaiter :> Runtime.CompilerServices.ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted: unit -> bool) and ^Awaiter: (member GetResult: unit -> 'TResult1) and ^Builder: (member AwaitUnsafeOnCompleted: byref<Runtime.CompilerServices.ICriticalNotifyCompletion> * byref<CompilerServices.ResumableStateMachine<CancellableTaskResultBuilderBaseStateMachineData<'TOverall,'Error,^Builder>>> -> unit) // Argument 'continuation' doesn't match
- member CancellableTaskResultBuilderBase.Bind<^Awaiter,'TResult1,'Error,'TOverall,'TResult2,^Builder when ^Awaiter :> Runtime.CompilerServices.ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted: unit -> bool) and ^Awaiter: (member GetResult: unit -> Result<'TResult1,'Error>) and ^Builder: (member AwaitUnsafeOnCompleted: byref<Runtime.CompilerServices.ICriticalNotifyCompletion> * byref<CompilerServices.ResumableStateMachine<CancellableTaskResultBuilderBaseStateMachineData<'TOverall,'Error,^Builder>>> -> unit)> : [<InlineIfLambda>] getAwaiterTResult: (CancellationToken -> ^Awaiter) * continuation: ('TResult1 -> CancellableTaskResultBuilderBaseCode<'TOverall,'TResult2,'Error,^Builder>) -> CancellableTaskResultBuilderBaseCode<'TOverall,'TResult2,'Error,^Builder> when ^Awaiter :> Runtime.CompilerServices.ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted: unit -> bool) and ^Awaiter: (member GetResult: unit -> Result<'TResult1,'Error>) and ^Builder: (member AwaitUnsafeOnCompleted: byref<Runtime.CompilerServices.ICriticalNotifyCompletion> * byref<CompilerServices.ResumableStateMachine<CancellableTaskResultBuilderBaseStateMachineData<'TOverall,'Error,^Builder>>> -> unit) // Argument 'getAwaiterTResult' doesn't match
- member CancellableTaskResultBuilderBase.Bind<^Awaiter,'TResult1,'Error,'TOverall,'TResult2,^Builder when ^Awaiter :> Runtime.CompilerServices.ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted: unit -> bool) and ^Awaiter: (member GetResult: unit -> Result<'TResult1,'Error>) and ^Builder: (member AwaitUnsafeOnCompleted: byref<Runtime.CompilerServices.ICriticalNotifyCompletion> * byref<CompilerServices.ResumableStateMachine<CancellableTaskResultBuilderBaseStateMachineData<'TOverall,'Error,^Builder>>> -> unit)> : awaiterTResult: ^Awaiter * continuation: ('TResult1 -> CancellableTaskResultBuilderBaseCode<'TOverall,'TResult2,'Error,^Builder>) -> CancellableTaskResultBuilderBaseCode<'TOverall,'TResult2,'Error,^Builder> when ^Awaiter :> Runtime.CompilerServices.ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted: unit -> bool) and ^Awaiter: (member GetResult: unit -> Result<'TResult1,'Error>) and ^Builder: (member AwaitUnsafeOnCompleted: byref<Runtime.CompilerServices.ICriticalNotifyCompletion> * byref<CompilerServices.ResumableStateMachine<CancellableTaskResultBuilderBaseStateMachineData<'TOverall,'Error,^Builder>>> -> unit) // Argument 'continuation' doesn't match
I think this is because the IDisposable Using binding for the CE is an extension, not a proper member, and the compiler never reaches the extension resolution.
Is there anything that can be done here in my code or here in the library? or do we have to take it to the compiler people?
Once again, the best feature of F# (computation expressions!) is the worst feature of F#
Describe the bug
When I try to use
use! node = tryGetNode path, I get an error that there is no Bind for IDisposable (more or less)To Reproduce
Funnily enough, adding an annotation `use! (node : Node) = tryGetNode "d" ``` makes the error go away in Rider, but not in the compiler.
This:
work just fine (but requires the annotation), but I don't like the fact that I have to do this
Expected behavior
The above should just work
I am getting an error:
I think this is because the
IDisposableUsingbinding for the CE is an extension, not a proper member, and the compiler never reaches the extension resolution.Is there anything that can be done here in my code or here in the library? or do we have to take it to the compiler people?
Once again, the best feature of F# (computation expressions!) is the worst feature of F#