diff options
-rw-r--r-- | changelog.md | 4 | ||||
-rw-r--r-- | compiler/vmops.nim | 9 | ||||
-rw-r--r-- | lib/std/effecttraits.nim | 19 | ||||
-rw-r--r-- | tests/macros/tgetraiseslist.nim | 22 |
4 files changed, 53 insertions, 1 deletions
diff --git a/changelog.md b/changelog.md index 3cdf138ad..219d085b1 100644 --- a/changelog.md +++ b/changelog.md @@ -292,7 +292,9 @@ proc mydiv(a, b): int {.raises: [].} = - `system.deepcopy` has to be enabled explicitly for `--gc:arc` and `--gc:orc` via `--deepcopy:on`. - +- Added a `std/effecttraits` module for introspection of the inferred `.raise` effects. + We hope this enables `async` macros that are precise about the possible exceptions that + can be raised. - Added `critbits.toCritBitTree`, similar to `tables.toTable`, creates a new `CritBitTree` with given arguments. diff --git a/compiler/vmops.nim b/compiler/vmops.nim index 298a02bb6..de6229ec7 100644 --- a/compiler/vmops.nim +++ b/compiler/vmops.nim @@ -261,3 +261,12 @@ proc registerAdditionalOps*(c: PCtx) = a.setResult osproc.execCmdEx(getString(a, 0), options).toLit registerCallback c, "stdlib.times.getTime", proc (a: VmArgs) {.nimcall.} = setResult(a, times.getTime().toLit) + + registerCallback c, "stdlib.effecttraits.getRaisesListImpl", proc (a: VmArgs) = + let fn = getNode(a, 0) + if fn.typ != nil and fn.typ.n != nil and fn.typ.n[0].len >= effectListLen and + fn.typ.n[0][exceptionEffects] != nil: + var list = newNodeI(nkBracket, fn.info) + for e in fn.typ.n[0][exceptionEffects]: + list.add opMapTypeInstToAst(c.cache, e.typ.skipTypes({tyRef}), e.info) + setResult(a, list) diff --git a/lib/std/effecttraits.nim b/lib/std/effecttraits.nim new file mode 100644 index 000000000..a5d799786 --- /dev/null +++ b/lib/std/effecttraits.nim @@ -0,0 +1,19 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2018 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module provides access to the inferred .raises effects +## for Nim's macro system. + +import macros + +proc getRaisesListImpl(n: NimNode): NimNode = discard "see compiler/vmops.nim" + +proc getRaisesList*(call: NimNode): NimNode = + expectKind call, nnkCallKinds + result = getRaisesListImpl(call[0]) diff --git a/tests/macros/tgetraiseslist.nim b/tests/macros/tgetraiseslist.nim new file mode 100644 index 000000000..de7ba06c8 --- /dev/null +++ b/tests/macros/tgetraiseslist.nim @@ -0,0 +1,22 @@ +discard """ + nimout: '''##[ValueError, Gen[string]]##''' +""" + +import macros +import std / effecttraits + +type + Gen[T] = object of CatchableError + x: T + +macro m(call: typed): untyped = + echo "##", repr getRaisesList(call), "##" + result = call + +proc r(inp: int) = + if inp == 0: + raise newException(ValueError, "bah") + elif inp == 1: + raise newException(Gen[string], "bahB") + +m r(2) |