More progress towards Lent[T] in Nim 1.6

* Worked-around a bug where Nim comlains that the return value is
  not a path expression in functions lacking explicit return
  statements

* Worked-around a limitation that Nim doesn't allow:
  let foo: lent T = makeT()
This commit is contained in:
Zahary Karadjov 2021-10-19 19:35:48 +03:00
parent d8f35df7a7
commit 2dd113f754
2 changed files with 20 additions and 6 deletions

View File

@ -466,14 +466,14 @@ func get*[T: not void, E](self: Result[T, E]): Lent[T] {.inline.} =
## Exception bridge mode: raise given Exception instead
## See also: Option.get
assertOk(self)
self.v
return self.v
func tryGet*[T: not void, E](self: Result[T, E]): Lent[T] {.inline.} =
## Fetch value of result if set, or raise
## When E is an Exception, raise that exception - otherwise, raise a ResultError[E]
mixin raiseResultError
if not self.o: self.raiseResultError()
self.v
return self.v
func get*[T, E](self: Result[T, E], otherwise: T): Lent[T] {.inline.} =
## Fetch value of result if set, or return the value `otherwise`
@ -523,7 +523,7 @@ func expect*[T: not void, E](self: Result[T, E], m: string): Lent[T] =
raiseResultDefect(m, self.e)
else:
raiseResultDefect(m)
self.v
return self.v
func expect*[T: not void, E](self: var Result[T, E], m: string): var T =
if not self.o:
@ -545,7 +545,7 @@ func error*[T, E](self: Result[T, E]): Lent[E] =
raiseResultDefect("Trying to access error when value is set", self.v)
else:
raiseResultDefect("Trying to access error when value is set")
self.e
return self.e
template value*[T, E](self: Result[T, E]): Lent[T] =
mixin get
@ -651,6 +651,11 @@ template value*[E](self: var Result[void, E]) =
mixin get
self.get()
template isBorrowable*(x: typed): bool =
type T = typeof(x)
compiles:
let v: Lent[T] = x
template `?`*[T, E](self: Result[T, E]): auto =
## Early return - if self is an error, we will return from the current
## function, else we'll move on..
@ -659,9 +664,14 @@ template `?`*[T, E](self: Result[T, E]): auto =
## let v = ? funcWithResult()
## echo v # prints value, not Result!
## ```
let v: Lent[Result[T, E]] = self
type S = typeof(self)
when isBorrowable(self):
let v: Lent[S] = self
else:
let v = self
if not v.o:
when typeof(result) is typeof(v):
when typeof(result) is typeof(self):
return v
else:
return err(typeof(result), v.e)

View File

@ -168,8 +168,12 @@ doAssert testErr().error == "323"
doAssert testOk().expect("testOk never fails") == 42
static: doAssert isBorrowable(works()) == false
static: doAssert isBorrowable(counter2) == true
func testQn(): Result[int, string] =
let x = ?works() - ?works()
static: doAssert isBorrowable(x) == true
result.ok(x)
func testQn2(): Result[int, string] =