summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelog.md4
-rw-r--r--compiler/vmops.nim9
-rw-r--r--lib/std/effecttraits.nim19
-rw-r--r--tests/macros/tgetraiseslist.nim22
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)