mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-04 10:54:42 +00:00
fix #23381 As for the read function, the original plan was to use lent for annotation, but after my experiments, it still produced copies, so I had to move it out. Now the `read` function cannot be called repeatedly
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
import std/[os, tables, strutils, times, heapqueue, options, deques, cstrutils]
|
||||
import std/[os, tables, strutils, times, heapqueue, options, deques, cstrutils, typetraits]
|
||||
|
||||
import system/stacktraces
|
||||
|
||||
@@ -193,7 +193,7 @@ proc add(callbacks: var CallbackList, function: CallbackFunc) =
|
||||
last = last.next
|
||||
last.next = newCallback
|
||||
|
||||
proc completeImpl[T, U](future: Future[T], val: U, isVoid: static bool) =
|
||||
proc completeImpl[T, U](future: Future[T], val: sink U, isVoid: static bool) =
|
||||
#assert(not future.finished, "Future already finished, cannot finish twice.")
|
||||
checkFinished(future)
|
||||
assert(future.error == nil)
|
||||
@@ -203,7 +203,7 @@ proc completeImpl[T, U](future: Future[T], val: U, isVoid: static bool) =
|
||||
future.callbacks.call()
|
||||
when isFutureLoggingEnabled: logFutureFinish(future)
|
||||
|
||||
proc complete*[T](future: Future[T], val: T) =
|
||||
proc complete*[T](future: Future[T], val: sink T) =
|
||||
## Completes `future` with value `val`.
|
||||
completeImpl(future, val, false)
|
||||
|
||||
@@ -219,7 +219,7 @@ proc complete*[T](future: FutureVar[T]) =
|
||||
fut.callbacks.call()
|
||||
when isFutureLoggingEnabled: logFutureFinish(Future[T](future))
|
||||
|
||||
proc complete*[T](future: FutureVar[T], val: T) =
|
||||
proc complete*[T](future: FutureVar[T], val: sink T) =
|
||||
## Completes a `FutureVar` with value `val`.
|
||||
##
|
||||
## Any previously stored value will be overwritten.
|
||||
@@ -370,11 +370,7 @@ proc injectStacktrace[T](future: Future[T]) =
|
||||
# newMsg.add "\n" & $entry
|
||||
future.error.msg = newMsg
|
||||
|
||||
proc read*[T](future: Future[T] | FutureVar[T]): T =
|
||||
## Retrieves the value of `future`. Future must be finished otherwise
|
||||
## this function will fail with a `ValueError` exception.
|
||||
##
|
||||
## If the result of the future is an error then that error will be raised.
|
||||
template readImpl(future, T) =
|
||||
when future is Future[T]:
|
||||
let fut {.cursor.} = future
|
||||
else:
|
||||
@@ -384,11 +380,21 @@ proc read*[T](future: Future[T] | FutureVar[T]): T =
|
||||
injectStacktrace(fut)
|
||||
raise fut.error
|
||||
when T isnot void:
|
||||
result = fut.value
|
||||
result = distinctBase(future).value
|
||||
else:
|
||||
# TODO: Make a custom exception type for this?
|
||||
raise newException(ValueError, "Future still in progress.")
|
||||
|
||||
proc read*[T](future: Future[T] | FutureVar[T]): lent T =
|
||||
## Retrieves the value of `future`. Future must be finished otherwise
|
||||
## this function will fail with a `ValueError` exception.
|
||||
##
|
||||
## If the result of the future is an error then that error will be raised.
|
||||
readImpl(future, T)
|
||||
|
||||
proc read*(future: Future[void] | FutureVar[void]) =
|
||||
readImpl(future, void)
|
||||
|
||||
proc readError*[T](future: Future[T]): ref Exception =
|
||||
## Retrieves the exception stored in `future`.
|
||||
##
|
||||
|
||||
Reference in New Issue
Block a user