`results` `valueOr` access to `error` template injected symbol fails with certain generic callers
Closed this issue · 2 comments
tersec commented
import stew/results
proc makeBeaconBlockForHeadAndSlot[T](): Result[int, string] =
var gps: Result[int, string]
discard gps.valueOr:
return err(error)
return err("")
proc getBlindedBlockParts() =
discard makeBeaconBlockForHeadAndSlot[int]()
For example, results in an error of:
stew/results.nim(405, 16) Error: type mismatch: got 'proc (self: Result[error.T, error.E]): E{.noSideEffect.}' for 'error' but expected 'string'
but if one makes makeBeaconBlockForHeadAndSlot
non-generic, it compiles fine, even though it doesn't use its dummy parameter regardless.
It's the result of conflict between the error
func
and injected symbol, which is a known Nim issue. Reproduced in
type
Result[T, E] = object
case o: bool
of false:
e: E
of true:
v: T
template err[T, E](R: type Result[T, E], x: untyped): R =
R(o: false, e: x)
template err(v: auto): auto = err(typeof(result), v)
func error[T, E](self: Result[T, E]): E =
if self.o:
raiseAssert("Trying to access error when value is set")
when E isnot void:
self.e
template valueOr[T: not void, E](self: Result[T, E], def: untyped): T =
let s = (self) # TODO avoid copy
if s.o: s.v
else:
when E isnot void:
template error: E {.used, inject.} = s.e
def
#proc makeBeaconBlockForHeadAndSlot[T](): Result[int, string] =
proc makeBeaconBlockForHeadAndSlot(): Result[int, string] =
var gps: Result[int, string]
discard gps.valueOr:
return err(error)
return err("")
proc getBlindedBlockParts() =
#discard makeBeaconBlockForHeadAndSlot[int]()
discard makeBeaconBlockForHeadAndSlot()
in a self-contained way.
arnetheduck commented
Workaround: qualify the error
access inside valueOr
:
proc makeBeaconBlockForHeadAndSlot[T](): Result[int, string] =
var gps: Result[int, string]
discard gps.valueOr:
return err(gps.error)
return err("")
arnetheduck commented
moved to arnetheduck/nim-results#34