This commit is contained in:
Zahary Karadjov
2013-12-28 23:53:48 +02:00
parent 5d75ce2f2e
commit eb1d23c0c7
2 changed files with 60 additions and 9 deletions

View File

@@ -2545,7 +2545,7 @@ proc raiseAssert*(msg: string) {.noinline.} =
sysFatal(EAssertionFailed, msg)
when true:
proc hiddenRaiseAssert(msg: string) {.raises: [], tags: [].} =
proc failedAssertImpl*(msg: string) {.raises: [], tags: [].} =
# trick the compiler to not list ``EAssertionFailed`` when called
# by ``assert``.
type THide = proc (msg: string) {.noinline, raises: [], noSideEffect,
@@ -2558,11 +2558,11 @@ template assert*(cond: bool, msg = "") =
## raises an ``EAssertionFailure`` exception. However, the compiler may
## not generate any code at all for ``assert`` if it is advised to do so.
## Use ``assert`` for debugging purposes only.
bind instantiationInfo, hiddenRaiseAssert
bind instantiationInfo
mixin failedAssertImpl
when compileOption("assertions"):
{.line.}:
if not cond:
hiddenRaiseAssert(astToStr(cond) & ' ' & msg)
if not cond: failedAssertImpl(astToStr(cond) & ' ' & msg)
template doAssert*(cond: bool, msg = "") =
## same as `assert` but is always turned on and not affected by the
@@ -2575,9 +2575,9 @@ template doAssert*(cond: bool, msg = "") =
when not defined(nimhygiene):
{.pragma: inject.}
template onFailedAssert*(msg: expr, code: stmt): stmt =
## Sets an assertion failure handler that will intercept any assert statements
## following `onFailedAssert` in the current lexical scope.
template onFailedAssert*(msg: expr, code: stmt): stmt {.dirty, immediate.} =
## Sets an assertion failure handler that will intercept any assert
## statements following `onFailedAssert` in the current lexical scope.
## Can be defined multiple times in a single function.
##
## .. code-block:: nimrod
@@ -2594,8 +2594,8 @@ template onFailedAssert*(msg: expr, code: stmt): stmt =
##
## assert(...)
##
template raiseAssert(msgIMPL: string): stmt =
let msg {.inject.} = msgIMPL
template failedAssertImpl(msgIMPL: string): stmt {.dirty, immediate.} =
let msg = msgIMPL
code
proc shallow*[T](s: var seq[T]) {.noSideEffect, inline.} =

View File

@@ -0,0 +1,51 @@
discard """
output: '''
WARNING: false first asseertion from bar
ERROR: false second assertion from bar
-1
tests/run/tfailedassert.nim:40 false assertion from foo
'''
"""
type
TLineInfo = tuple[filename: string, line: int]
TMyError = object of E_Base
lineinfo: TLineInfo
EMyError = ref TMyError
# module-wide policy to change the failed assert
# exception type in order to include a lineinfo
onFailedAssert(msg):
var e = new(TMyError)
e.msg = msg
e.lineinfo = instantiationInfo(-2)
raise e
proc foo =
assert(false, "assertion from foo")
proc bar: int =
# local overrides that are active only
# in this proc
onFailedAssert(msg): echo "WARNING: " & msg
assert(false, "first asseertion from bar")
onFailedAssert(msg):
echo "ERROR: " & msg
return -1
assert(false, "second assertion from bar")
return 10
echo("")
echo(bar())
try:
foo()
except:
let e = EMyError(getCurrentException())
echo e.lineinfo.filename, ":", e.lineinfo.line, " ", e.msg