From e963a934ed2463474dfccf9595c66baac10c25ec Mon Sep 17 00:00:00 2001 From: Tanguy Date: Tue, 21 Jun 2022 14:52:46 +0200 Subject: [PATCH] Workaround template & quote do binding issues --- questionable/binding.nim | 10 ++++++---- questionable/results.nim | 19 +++++++++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/questionable/binding.nim b/questionable/binding.nim index 5cf91e9..55bf8f0 100644 --- a/questionable/binding.nim +++ b/questionable/binding.nim @@ -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 diff --git a/questionable/results.nim b/questionable/results.nim index 220dd1a..4f6cb7c 100644 --- a/questionable/results.nim +++ b/questionable/results.nim @@ -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(`+`)