@@ -524,11 +524,19 @@ module LowPriority =
524524 //
525525 // Note: we cannot place _.Bind directly on the type, as the NoEagerXXX attribute
526526 // has no effect, and each use of `do!` will give an overload error (because the
527- // `TaskLike` type and the `Task<_>` type are interchangeable).
527+ // `TaskLike` type and the `Task<_>` type are partially interchangeable, see notes there ).
528528 //
529529 // However, we cannot unify these two methods, because Task<_> inherits from Task (non-generic)
530530 // and we need a way to distinguish these two methods.
531531 //
532+ // Types handled:
533+ // - ValueTask (non-generic, because it implements GetResult() -> unit)
534+ // - ValueTask<'T> (because it implements GetResult() -> 'TResult)
535+ // - Task (non-generic, because it implements GetResult() -> unit)
536+ // - any other type that implements GetAwaiter()
537+ //
538+ // Not handled:
539+ // - Task<'T> (because it only implements GetResult() -> unit, not GetResult() -> 'TResult)
532540
533541 [<NoEagerConstraintApplication>]
534542 member inline _.Bind < ^TaskLike , 'TResult1 , 'TResult2 , ^Awaiter , 'TOverall
@@ -545,24 +553,24 @@ module LowPriority =
545553 let mutable awaiter = ( ^TaskLike : ( member GetAwaiter : unit -> ^Awaiter ) ( task))
546554 let mutable __stack_fin = true
547555
548- Debug.logInfo " at TaskLike bind! "
556+ Debug.logInfo " at TaskLike bind"
549557
550558 if not ( ^Awaiter : ( member get_IsCompleted : unit -> bool) ( awaiter)) then
551559 // This will yield with __stack_fin2 = false
552560 // This will resume with __stack_fin2 = true
553561 let __stack_fin2 = ResumableCode.Yield() .Invoke(& sm)
554562 __ stack_ fin <- __ stack_ fin2
555563
556- Debug.logInfo ( " at TaskLike bind! : with __stack_fin = " , __ stack_ fin)
557- Debug.logInfo ( " at TaskLike bind! : this.completed = " , sm.Data.completed)
564+ Debug.logInfo ( " at TaskLike bind: with __stack_fin = " , __ stack_ fin)
565+ Debug.logInfo ( " at TaskLike bind: this.completed = " , sm.Data.completed)
558566
559567 if __ stack_ fin then
560568 Debug.logInfo " at TaskLike bind!: finished awaiting, calling continuation"
561569 let result = ( ^Awaiter : ( member GetResult : unit -> 'TResult1) ( awaiter))
562570 ( continuation result) .Invoke(& sm)
563571
564572 else
565- Debug.logInfo " at TaskLike bind! : await further"
573+ Debug.logInfo " at TaskLike bind: await further"
566574
567575 sm.Data.awaiter <- awaiter
568576 sm.Data.current <- ValueNone
@@ -615,9 +623,19 @@ module MediumPriority =
615623module HighPriority =
616624 type TaskSeqBuilder with
617625
626+ //
627+ // Notes Task:
628+ // - Task<_> implements GetAwaiter(), but TaskAwaiter does not implement GetResult() -> TResult
629+ // - Instead, it has GetResult() -> unit, which is not '^TaskLike'
630+ // - Conclusion: we need an extra high-prio overload to allow support for Task<_>
631+ //
632+ // Notes ValueTask:
633+ // - In contrast, ValueTask<_> *does have* GetResult() -> 'TResult
634+ // - Conclusion: we do not need an extra overload anymore for ValueTask
635+ //
618636 member inline _.Bind ( task : Task < 'TResult1 >, continuation : ( 'TResult1 -> TaskSeqCode < 'T >)) : TaskSeqCode < 'T > =
619637 TaskSeqCode< 'T>( fun sm ->
620- let mutable awaiter = task.GetAwaiter()
638+ let mutable awaiter : TaskAwaiter < 'TResult1 > = task.GetAwaiter()
621639 let mutable __stack_fin = true
622640
623641 Debug.logInfo " at Bind"
@@ -642,30 +660,3 @@ module HighPriority =
642660 sm.Data.awaiter <- awaiter
643661 sm.Data.current <- ValueNone
644662 false )
645-
646- member inline _.Bind
647- (
648- task : ValueTask < 'TResult1 >,
649- continuation : ( 'TResult1 -> TaskSeqCode < 'T >)
650- ) : TaskSeqCode < 'T > =
651- TaskSeqCode< 'T>( fun sm ->
652- let mutable awaiter = task.GetAwaiter()
653- let mutable __stack_fin = true
654-
655- Debug.logInfo " at BindV"
656-
657- if not awaiter.IsCompleted then
658- // This will yield with __stack_fin2 = false
659- // This will resume with __stack_fin2 = true
660- let __stack_fin2 = ResumableCode.Yield() .Invoke(& sm)
661- __ stack_ fin <- __ stack_ fin2
662-
663- if __ stack_ fin then
664- let result = awaiter.GetResult()
665- ( continuation result) .Invoke(& sm)
666- else
667- Debug.logInfo " at BindV: calling AwaitUnsafeOnCompleted"
668-
669- sm.Data.awaiter <- awaiter
670- sm.Data.current <- ValueNone
671- false )
0 commit comments