Workaround template & quote do binding issues

This commit is contained in:
Tanguy 2022-06-21 14:52:46 +02:00
parent 2ce6dba98b
commit e963a934ed
No known key found for this signature in database
GPG Key ID: 7DD8EC6B6CE6C45E
2 changed files with 19 additions and 10 deletions

View File

@ -14,15 +14,17 @@ macro `=?`*(name, expression): bool =
## instance in an `if` statement.
name.expectKind({nnkIdent, nnkVarTy})
# Outside of the quote do to avoid binding symbol too early
let unpacker = newCall("questionableUnpack", expression)
if name.kind == nnkIdent:
quote do:
mixin questionableUnpack
let (`name` {.used.}, isOk) = questionableUnpack(`expression`)
let (`name` {.used.}, isOk) = `unpacker`
isOk
else:
let name = name[0]
quote do:
mixin questionableUnpack
var (`name` {.used.}, isOk) = questionableUnpack(`expression`)
var (`name` {.used.}, isOk) = `unpacker`
isOk

View File

@ -110,14 +110,21 @@ proc option*[T,E](value: Result[T,E]): ?T =
else:
T.none
template questionableUnpack*[T, E](expression: Result[T, E]): (T, bool) =
macro questionableUnpack*[T, E](expression: Result[T, E]): (T, bool) =
## Used internally
let res = expression
when declared(internalWithoutError):
if res.isFailure:
internalWithoutError = res.error
questionableUnpack(res.option)
# expression must be resolved before quote do to avoid binding issues
let
resSymbol = genSym()
res = newNimNode(nnkLetSection).add(
newIdentDefs(resSymbol, newEmptyNode(), expression)
)
quote do:
`res`
when declared(internalWithoutError):
if `resSymbol`.isFailure:
internalWithoutError = `resSymbol`.error
questionableUnpack(`resSymbol`.option)
Result.liftUnary(`-`)
Result.liftUnary(`+`)