Fix: `without` should work when `$` has side effects

It's ok to use unsafeError in bindFailed, because we've
already checked that the result contains an error.
This commit is contained in:
Mark Spanbroek 2024-03-10 12:02:45 +01:00 committed by markspanbroek
parent 47692e0d92
commit 57e467b8b0
2 changed files with 18 additions and 5 deletions

View File

@ -21,16 +21,16 @@ macro captureBindError*(error: var ref CatchableError, expression): auto =
# return the evaluated result
evaluated
func error[T](_: Option[T]): ref CatchableError =
func unsafeError[T](_: Option[T]): ref CatchableError =
newException(ValueError, "Option is set to `none`")
func error[T](_: ref T): ref CatchableError =
func unsafeError[T](_: ref T): ref CatchableError =
newException(ValueError, "ref is nil")
func error[T](_: ptr T): ref CatchableError =
func unsafeError[T](_: ptr T): ref CatchableError =
newException(ValueError, "ptr is nil")
func error[Proc: proc | iterator](_: Proc): ref CatchableError =
func unsafeError[Proc: proc | iterator](_: Proc): ref CatchableError =
newException(ValueError, "proc or iterator is nil")
macro bindFailed*(expression: typed) =
@ -49,4 +49,4 @@ macro bindFailed*(expression: typed) =
# check that the error variable is in scope
when compiles(`errorVariable`):
# assign bind error to error variable
`errorVariable` = `expression`.error
`errorVariable` = `expression`.unsafeError

View File

@ -643,6 +643,19 @@ suite "result":
someProc(42.success)
someProc(int.failure "some error")
type TypeWithSideEffect = object
proc `$`*(value: TypeWithSideEffect): string {.sideEffect.} =
discard
suite "result side effects":
test "without statement with error works when `$` has side effects":
proc foo =
without x =? TypeWithSideEffect.failure("error"), error:
discard error
return
fail()
foo()
import pkg/questionable/resultsbase