Skip to content

Commit d382452

Browse files
committed
Moving Source methods around
1 parent b085c2e commit d382452

File tree

2 files changed

+120
-130
lines changed

2 files changed

+120
-130
lines changed

src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs

Lines changed: 112 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ module CancellableTaskResultCE =
162162
)
163163

164164
member inline this.Source(ctr: CancellableTaskResult<'T, 'Error>) : CancellableTaskResult<'T, 'Error> = ctr
165+
member inline this.Source(ctr: CancellableTaskResultCode<'T,'Error,'T>) : CancellableTaskResultCode<'T,'Error,'T> = ctr
166+
165167

166168
member inline _.Source(result: TaskResult<_, _>) : CancellableTaskResult<_, _> = fun _ -> result
167169
member inline _.Source(result: Async<Result<_, _>>) : CancellableTaskResult<_, _> = fun ct -> Async.StartAsTask(result, cancellationToken=ct)
@@ -368,33 +370,18 @@ module CancellableTaskResultCE =
368370
module LowPriority =
369371
// Low priority extensions
370372

371-
type BackgroundCancellableTaskResultBuilder with
372-
[<NoEagerConstraintApplication>]
373-
member inline this.Source< ^TaskLike2, ^Awaiter2, 'T, 'Error when ^TaskLike2: (member GetAwaiter : unit -> ^Awaiter2) and ^Awaiter2 :> ICriticalNotifyCompletion and ^Awaiter2: (member get_IsCompleted :
374-
unit -> bool) and ^Awaiter2: (member GetResult : unit -> 'T)>
375-
(t: ^TaskLike2)
376-
: CancellableTaskResult<'T, 'Error> =
377-
// TODO: Gets errors like "error FS0073: internal error: Undefined or unsolved type variable: ^Awaiter"
378-
// this.Run(this.ReturnFrom(t))
379-
fun _ ->
380-
backgroundTask {
381-
let! result = t
382-
return Ok result
383-
}
384-
type CancellableTaskResultBuilder with
385-
386-
[<NoEagerConstraintApplication>]
387-
member inline this.Source< ^TaskLike, ^Awaiter, 'T, 'Error when ^TaskLike: (member GetAwaiter : unit -> ^Awaiter) and ^Awaiter :> ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted :
388-
unit -> bool) and ^Awaiter: (member GetResult : unit -> 'T)>
389-
(t: ^TaskLike)
390-
: CancellableTaskResult<'T, 'Error> =
391-
// TODO: Gets errors like "error FS0073: internal error: Undefined or unsolved type variable: ^Awaiter"
392-
// this.Run(this.ReturnFrom(t))
393-
fun _ ->
394-
task {
395-
let! result = t
396-
return Ok result
397-
}
373+
// type BackgroundCancellableTaskResultBuilder with
374+
// [<NoEagerConstraintApplication>]
375+
// member inline this.Source< ^TaskLike, ^Awaiter, 'T, 'Error when ^TaskLike: (member GetAwaiter : unit -> ^Awaiter) and ^Awaiter :> ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted :
376+
// unit -> bool) and ^Awaiter: (member GetResult : unit -> 'T)>
377+
// (t: ^TaskLike)
378+
// : CancellableTaskResult<'T, 'Error> =
379+
// fun _ ->
380+
// backgroundTask {
381+
// let! result = t
382+
// return Ok result
383+
// }
384+
398385

399386
type CancellableTaskResultBuilderBase with
400387

@@ -475,77 +462,77 @@ module CancellableTaskResultCE =
475462
//-- RESUMABLE CODE END
476463
)
477464

478-
// [<NoEagerConstraintApplication>]
479-
// static member inline BindDynamic< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error when ^TaskLike: (member GetAwaiter:
480-
// unit -> ^Awaiter) and ^Awaiter :> ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted:
481-
// unit -> bool) and ^Awaiter: (member GetResult: unit -> 'TResult1)>
482-
// (
483-
// sm: byref<ResumableStateMachine<CancellableTaskResultStateMachineData<'TOverall,'Error>>>,
484-
// task: ^TaskLike,
485-
// continuation: ('TResult1 -> CancellableTaskResultCode<'TOverall, 'Error, 'TResult2>)
486-
// ) : bool =
487-
// sm.Data.CancellationToken.ThrowIfCancellationRequested()
465+
[<NoEagerConstraintApplication>]
466+
static member inline BindDynamic< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error when ^TaskLike: (member GetAwaiter:
467+
unit -> ^Awaiter) and ^Awaiter :> ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted:
468+
unit -> bool) and ^Awaiter: (member GetResult: unit -> 'TResult1)>
469+
(
470+
sm: byref<ResumableStateMachine<CancellableTaskResultStateMachineData<'TOverall,'Error>>>,
471+
task: ^TaskLike,
472+
continuation: ('TResult1 -> CancellableTaskResultCode<'TOverall, 'Error, 'TResult2>)
473+
) : bool =
474+
sm.Data.CancellationToken.ThrowIfCancellationRequested()
488475

489-
// let mutable awaiter =
490-
// (^TaskLike: (member GetAwaiter: unit -> ^Awaiter) (task))
476+
let mutable awaiter =
477+
(^TaskLike: (member GetAwaiter: unit -> ^Awaiter) (task))
491478

492-
// let cont =
493-
// (CancellableTaskResultResumptionFunc<'TOverall, 'Error> (fun sm ->
494-
// let result = (^Awaiter: (member GetResult: unit -> 'TResult1) (awaiter))
479+
let cont =
480+
(CancellableTaskResultResumptionFunc<'TOverall, 'Error> (fun sm ->
481+
let result = (^Awaiter: (member GetResult: unit -> 'TResult1) (awaiter))
495482

496-
// (continuation result).Invoke(&sm)
497-
// ))
483+
(continuation result).Invoke(&sm)
484+
))
498485

499-
// // shortcut to continue immediately
500-
// if (^Awaiter: (member get_IsCompleted: unit -> bool) (awaiter)) then
501-
// cont.Invoke(&sm)
502-
// else
503-
// sm.ResumptionDynamicInfo.ResumptionData <- (awaiter :> ICriticalNotifyCompletion)
504-
// sm.ResumptionDynamicInfo.ResumptionFunc <- cont
505-
// false
486+
// shortcut to continue immediately
487+
if (^Awaiter: (member get_IsCompleted: unit -> bool) (awaiter)) then
488+
cont.Invoke(&sm)
489+
else
490+
sm.ResumptionDynamicInfo.ResumptionData <- (awaiter :> ICriticalNotifyCompletion)
491+
sm.ResumptionDynamicInfo.ResumptionFunc <- cont
492+
false
506493

507-
// [<NoEagerConstraintApplication>]
508-
// member inline this.Bind< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error when ^TaskLike: (member GetAwaiter:
509-
// unit -> ^Awaiter) and ^Awaiter :> ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted:
510-
// unit -> bool) and ^Awaiter: (member GetResult: unit -> 'TResult1)>
511-
// (
512-
// task: ^TaskLike,
513-
// continuation: ('TResult1 -> CancellableTaskResultCode<'TOverall, 'Error, 'TResult2>)
514-
// ) : CancellableTaskResultCode<'TOverall, 'Error, 'TResult2> =
494+
[<NoEagerConstraintApplication>]
495+
member inline this.Bind< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error when ^TaskLike: (member GetAwaiter:
496+
unit -> ^Awaiter) and ^Awaiter :> ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted:
497+
unit -> bool) and ^Awaiter: (member GetResult: unit -> 'TResult1)>
498+
(
499+
task: ^TaskLike,
500+
continuation: ('TResult1 -> CancellableTaskResultCode<'TOverall, 'Error, 'TResult2>)
501+
) : CancellableTaskResultCode<'TOverall, 'Error, 'TResult2> =
515502

516503

517-
// CancellableTaskResultCode<'TOverall, _, _> (fun sm ->
518-
// if __useResumableCode then
519-
// //-- RESUMABLE CODE START
520-
// sm.Data.CancellationToken.ThrowIfCancellationRequested()
521-
// // Get an awaiter from the awaitable
522-
// let mutable awaiter =
523-
// (^TaskLike: (member GetAwaiter: unit -> ^Awaiter) (task))
524-
525-
// let mutable __stack_fin = true
526-
527-
// if not (^Awaiter: (member get_IsCompleted: unit -> bool) (awaiter)) then
528-
// // This will yield with __stack_yield_fin = false
529-
// // This will resume with __stack_yield_fin = true
530-
// let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
531-
// __stack_fin <- __stack_yield_fin
532-
533-
// if __stack_fin then
534-
// let result = (^Awaiter: (member GetResult: unit ->'TResult1) (awaiter))
535-
// (continuation result).Invoke(&sm)
536-
537-
// else
538-
// sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm)
539-
// false
540-
// else
504+
CancellableTaskResultCode<'TOverall, _, _> (fun sm ->
505+
if __useResumableCode then
506+
//-- RESUMABLE CODE START
507+
sm.Data.CancellationToken.ThrowIfCancellationRequested()
508+
// Get an awaiter from the awaitable
509+
let mutable awaiter =
510+
(^TaskLike: (member GetAwaiter: unit -> ^Awaiter) (task))
511+
512+
let mutable __stack_fin = true
513+
514+
if not (^Awaiter: (member get_IsCompleted: unit -> bool) (awaiter)) then
515+
// This will yield with __stack_yield_fin = false
516+
// This will resume with __stack_yield_fin = true
517+
let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
518+
__stack_fin <- __stack_yield_fin
519+
520+
if __stack_fin then
521+
let result = (^Awaiter: (member GetResult: unit ->'TResult1) (awaiter))
522+
(continuation result).Invoke(&sm)
523+
524+
else
525+
sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm)
526+
false
527+
else
541528

542-
// CancellableTaskResultBuilderBase.BindDynamic< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error>(
543-
// &sm,
544-
// task,
545-
// continuation
546-
// )
547-
// //-- RESUMABLE CODE END
548-
// )
529+
CancellableTaskResultBuilderBase.BindDynamic< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error>(
530+
&sm,
531+
task,
532+
continuation
533+
)
534+
//-- RESUMABLE CODE END
535+
)
549536

550537

551538
// [<NoEagerConstraintApplication>]
@@ -585,13 +572,13 @@ module CancellableTaskResultCE =
585572

586573
// this.Bind(task, (fun v -> this.Return v))
587574

588-
// [<NoEagerConstraintApplication>]
589-
// member inline this.ReturnFrom< ^TaskLike, ^Awaiter, 'T, 'Error when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) and ^Awaiter :> ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted:
590-
// unit -> bool) and ^Awaiter: (member GetResult: unit -> 'T)>
591-
// (task: ^TaskLike)
592-
// : CancellableTaskResultCode<'T, 'Error, 'T> =
575+
[<NoEagerConstraintApplication>]
576+
member inline this.ReturnFrom< ^TaskLike, ^Awaiter, 'T, 'Error when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) and ^Awaiter :> ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted:
577+
unit -> bool) and ^Awaiter: (member GetResult: unit -> 'T)>
578+
(task: ^TaskLike)
579+
: CancellableTaskResultCode<'T, 'Error, 'T> =
593580

594-
// this.Bind(task, (fun v -> this.Return v))
581+
this.Bind(task, (fun v -> this.Return v))
595582

596583
member inline _.Using<'Resource, 'TOverall, 'Error, 'T when 'Resource :> IDisposable>
597584
(
@@ -601,7 +588,7 @@ module CancellableTaskResultCE =
601588
ResumableCode.Using(resource, body)
602589

603590

604-
591+
605592

606593
[<AutoOpen>]
607594
module HighPriority =
@@ -616,6 +603,24 @@ module CancellableTaskResultCE =
616603
fun ct -> Async.StartAsTask(computation, cancellationToken = ct)
617604

618605

606+
607+
608+
type CancellableTaskResultBuilder with
609+
610+
[<NoEagerConstraintApplication>]
611+
member inline this.Source< ^TaskLike, ^Awaiter, 'T when ^TaskLike: (member GetAwaiter : unit -> ^Awaiter) and ^Awaiter :> ICriticalNotifyCompletion and ^Awaiter: (member get_IsCompleted :
612+
unit -> bool) and ^Awaiter: (member GetResult : unit -> 'T)>
613+
(t: ^TaskLike)
614+
: CancellableTaskResult<_, _> =
615+
// : CancellableTaskResultCode<_,_,_> =
616+
// TODO: Gets errors like "error FS0073: internal error: Undefined or unsolved type variable: ^Awaiter"
617+
// this.Run(this.ReturnFrom(t))
618+
// this.ReturnFrom(t)
619+
fun _ -> task {
620+
let! r = t
621+
return Ok r
622+
}
623+
619624
// High priority extensions
620625
type CancellableTaskResultBuilderBase with
621626

@@ -707,46 +712,31 @@ module CancellableTaskResultCE =
707712

708713
type CancellableTaskResultBuilder with
709714

710-
member inline this.Source(t: Task<'T>) : CancellableTaskResult<'T, 'Error> =
715+
member inline this.Source(t: Task<'T>)
716+
// : CancellableTaskResult<'T, 'Error> =
717+
=
718+
// this.ReturnFrom(t)
711719
fun _ ->
712720
task {
713721
let! r = t
714722
return Ok r
715723
}
716-
member inline this.Source(t: Task) : CancellableTaskResult<unit, 'Error> =
717-
fun _ ->
724+
member inline _.Source(result: CancellableTask<'T>) : CancellableTaskResult<'T, 'Error> =
725+
fun ct ->
726+
// TODO: using `cancellableTask` results in "internal error: The local field ResumptionDynamicInfo was referenced but not declare" compliation error
718727
task {
719-
do! t
720-
return Ok()
721-
}
728+
let! r = result ct
729+
return Ok r
730+
}
722731
// Medium priority extensions
723732
type CancellableTaskResultBuilderBase with
724733

725734

726-
727-
member inline this.Source(t: ValueTask<'T>) : CancellableTaskResult<'T, 'Error> = fun _ -> t |> Task.mapV Ok
728-
729-
member inline this.Source(t: ValueTask) : CancellableTaskResult<unit, 'Error> =
730-
fun _ ->
731-
task {
732-
do! t
733-
return Ok()
734-
}
735735
member inline this.Source(t: Async<'T>) : CancellableTaskResult<'T, 'Error> =
736736
fun ct ->
737737
let t = t |> Async.map Ok
738738
Async.StartAsTask(t, cancellationToken = ct)
739-
740-
// TODO: Use backgroundTask?
741-
member inline _.Source(result: CancellableTask<'T>) : CancellableTaskResult<'T, 'Error> =
742-
fun ct ->
743-
// TODO: using `cancellableTask` results in "internal error: The local field ResumptionDynamicInfo was referenced but not declare" compliation error
744-
task {
745-
let! r = result ct
746-
return Ok r
747-
}
748739

749-
750740
// member inline this.Bind
751741
// (
752742
// [<InlineIfLambda>] computation: ColdTask<'TResult1>,

tests/FsToolkit.ErrorHandling.IcedTasks.Tests/CancellableTaskResultCE.fs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,14 @@ module CancellableTaskResultCE =
177177
Expect.equal actual (Ok ()) "Should be able to Return! CancellableTask"
178178
}
179179

180-
// testCaseTask "return! TaskLike" <| fun () -> task {
181-
// let ctr = cancellableTaskResult {
182-
// return! Task.Yield()
183-
// }
184-
185-
// let! actual = ctr CancellationToken.None
186-
// Expect.equal actual (Ok ()) "Should be able to Return! CancellableTask"
187-
// }
180+
testCaseTask "return! TaskLike" <| fun () -> task {
181+
let ctr = cancellableTaskResult {
182+
return! Task.Yield()
183+
}
184+
185+
let! actual = ctr CancellationToken.None
186+
Expect.equal actual (Ok ()) "Should be able to Return! CancellableTask"
187+
}
188188

189189
]
190190

0 commit comments

Comments
 (0)