make `Raising` compatible with 2.0 (#526)

* make `Raising` compatible with 2.0

See https://github.com/nim-lang/Nim/issues/23432

* Update tests/testfut.nim

* Update tests/testfut.nim
This commit is contained in:
Jacek Sieka 2024-03-25 10:37:42 +01:00 committed by GitHub
parent 0e806d59ae
commit b8b4e1fc47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 4 deletions

View File

@ -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"),

View File

@ -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))