From ef2566218e701e6294608c6c30a367624786dcd6 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 22 Mar 2020 19:32:37 +0100 Subject: [PATCH] better error messages for Nim's effect system --- changelog.md | 1 + compiler/semcall.nim | 17 ++++++++++++++ compiler/sempass2.nim | 46 +++++++++++++++++++++---------------- tests/effects/teffects1.nim | 3 ++- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/changelog.md b/changelog.md index d5d1be956..a471ffbb2 100644 --- a/changelog.md +++ b/changelog.md @@ -189,6 +189,7 @@ echo f this is **very bad** style. You should inherit from `ValueError`, `IOError`, `OSError` or from a different specific exception type that inherits from `CatchableError` and cannot be confused with a `Defect`. +- The error reporting for Nim's effect system has been improved. ## Bugfixes diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 55ff80b6c..d8834dc90 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -136,6 +136,23 @@ proc effectProblem(f, a: PType; result: var string) = elif tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags: result.add "\n This expression can have side effects. Annotate the " & "proc with {.noSideEffect.} to get extended error information." + else: + case compatibleEffects(f, a) + of efCompat: discard + of efRaisesDiffer: + result.add "\n The `.raises` requirements differ." + of efRaisesUnknown: + result.add "\n The `.raises` requirements differ. Annotate the " & + "proc with {.raises: [].} to get extended error information." + of efTagsDiffer: + result.add "\n The `.tags` requirements differ." + of efTagsUnknown: + result.add "\n The `.tags` requirements differ. Annotate the " & + "proc with {.tags: [].} to get extended error information." + of efLockLevelsDiffer: + result.add "\n The `.locks` requirements differ. Annotate the " & + "proc with {.locks: 0.} to get extended error information." + proc renderNotLValue(n: PNode): string = result = $n diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index d5514d8d1..c8ad14c41 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -281,8 +281,14 @@ proc addToIntersection(inter: var TIntersection, s: int) = return inter.add((id: s, count: 1)) -proc throws(tracked, n: PNode) = - if n.typ == nil or n.typ.kind != tyError: tracked.add n +proc throws(tracked, n, orig: PNode) = + if n.typ == nil or n.typ.kind != tyError: + if orig != nil: + let x = copyNode(n) + x.info = orig.info + tracked.add x + else: + tracked.add n proc getEbase(g: ModuleGraph; info: TLineInfo): PType = result = g.sysTypeFromName(info, "Exception") @@ -302,34 +308,34 @@ proc createTag(g: ModuleGraph; n: PNode): PNode = result.typ = g.sysTypeFromName(n.info, "RootEffect") if not n.isNil: result.info = n.info -proc addEffect(a: PEffects, e: PNode, useLineInfo=true) = +proc addEffect(a: PEffects, e, comesFrom: PNode) = assert e.kind != nkRaiseStmt var aa = a.exc for i in a.bottom..