diff --git a/chronos/internal/raisesfutures.nim b/chronos/internal/raisesfutures.nim index 07e3438..546f3b7 100644 --- a/chronos/internal/raisesfutures.nim +++ b/chronos/internal/raisesfutures.nim @@ -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"), diff --git a/tests/testfut.nim b/tests/testfut.nim index 8c08293..c2231f1 100644 --- a/tests/testfut.nim +++ b/tests/testfut.nim @@ -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))