Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision 8e4bc30d485d1a562bd9e65c76b526736543455b)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 8fc9a5fcdfcbc515e3c551f072da9656d0800e52)
@@ -37,7 +37,5 @@
 // Anything that implements this trait can be resumed.
 // Anything that is resumed is a coroutine.
-trait is_coroutine(dtype T
-		| is_resumption_exception(CoroutineCancelled(T),
-			CoroutineCancelled_vtable(T))) {
+trait is_coroutine(dtype T | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) {
 	void main(T & this);
 	$coroutine * get_coroutine(T & this);
Index: libcfa/src/exception.hfa
===================================================================
--- libcfa/src/exception.hfa	(revision 8e4bc30d485d1a562bd9e65c76b526736543455b)
+++ libcfa/src/exception.hfa	(revision 8fc9a5fcdfcbc515e3c551f072da9656d0800e52)
@@ -125,4 +125,13 @@
 #define VTABLE_ASSERTION(exception_name, parameters) \
 	{ VTABLE_TYPE(exception_name) parameters VTABLE_NAME(exception_name); }
+
+// IS_EXCEPTION(exception_name [, (...parameters)])
+// IS_RESUMPTION_EXCEPTION(exception_name [, (parameters...)])
+// IS_TERMINATION_EXCEPTION(exception_name [, (parameters...)])
+// Create an assertion that exception_name, possibly with the qualifing parameters, is the given
+// kind of exception with the standard vtable with the same parameters if applicable.
+#define IS_EXCEPTION(...) _IS_EXCEPTION(is_exception, __VA_ARGS__, , ~)
+#define IS_RESUMPTION_EXCEPTION(...) _IS_EXCEPTION(is_resumption_exception, __VA_ARGS__, , ~)
+#define IS_TERMINATION_EXCEPTION(...) _IS_EXCEPTION(is_termination_exception, __VA_ARGS__, , ~)
 
 // All internal helper macros begin with an underscore.
@@ -234,2 +243,5 @@
 		_GLUE2(exception_name,_copy), ^?{}, \
 		_CLOSE
+
+#define _IS_EXCEPTION(kind, exception_name, parameters, ...) \
+	kind(exception_name parameters, VTABLE_TYPE(exception_name) parameters)
