Skip to content

Commit

Permalink
make Raising compatible with 2.0 (#526)
Browse files Browse the repository at this point in the history
* make `Raising` compatible with 2.0

See nim-lang/Nim#23432

* Update tests/testfut.nim

* Update tests/testfut.nim
  • Loading branch information
arnetheduck authored Mar 25, 2024
1 parent 0e806d5 commit b8b4e1f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
23 changes: 19 additions & 4 deletions chronos/internal/raisesfutures.nim
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,32 @@ proc members(tup: NimNode): seq[NimNode] {.compileTime.} =
macro hasException(raises: typedesc, ident: static string): bool =
newLit(raises.members.anyIt(it.eqIdent(ident)))

macro Raising*[T](F: typedesc[Future[T]], E: varargs[typedesc]): untyped =
macro Raising*[T](F: typedesc[Future[T]], E: typed): untyped =
## Given a Future type instance, return a type storing `{.raises.}`
## information
##
## Note; this type may change in the future
E.expectKind(nnkBracket)

let raises = if E.len == 0:
# An earlier version used `E: varargs[typedesc]` here but this is buggyt/no
# longer supported in 2.0 in certain cases:
# https://github.com/nim-lang/Nim/issues/23432
let
e =
case E.getTypeInst().typeKind()
of ntyTypeDesc: @[E]
of ntyArray:
for x in E:
if x.getTypeInst().typeKind != ntyTypeDesc:
error("Expected typedesc, got " & repr(x), x)
E.mapIt(it)
else:
error("Expected typedesc, got " & repr(E), E)
@[]

let raises = if e.len == 0:
makeNoRaises()
else:
nnkTupleConstr.newTree(E.mapIt(it))
nnkTupleConstr.newTree(e)
nnkBracketExpr.newTree(
ident "InternalRaisesFuture",
nnkDotExpr.newTree(F, ident"T"),
Expand Down
18 changes: 18 additions & 0 deletions tests/testfut.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2047,9 +2047,27 @@ suite "Future[T] behavior test suite":
check:
future1.cancelled() == true
future2.cancelled() == true

test "Sink with literals":
# https://github.com/nim-lang/Nim/issues/22175
let fut = newFuture[string]()
fut.complete("test")
check:
fut.value() == "test"

test "Raising type matching":
type X[E] = Future[void].Raising(E)

proc f(x: X) = discard

var v: Future[void].Raising([ValueError])
f(v)

type Object = object
# TODO cannot use X[[ValueError]] here..
field: Future[void].Raising([ValueError])
discard Object(field: v)

check:
not compiles(Future[void].Raising([42]))
not compiles(Future[void].Raising(42))

0 comments on commit b8b4e1f

Please sign in to comment.