From 7302a8ce7a0cc566c098b29fdb73c5da3b8e6ac0 Mon Sep 17 00:00:00 2001 From: cooldome Date: Sun, 10 Jun 2018 22:49:09 +0100 Subject: [PATCH 1/5] Fixes 7845 --- compiler/ast.nim | 12 +++++------- compiler/semstmts.nim | 5 +++-- tests/exception/texcpt1.nim | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 5a84b2b021..dd84452f98 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1667,7 +1667,7 @@ proc skipStmtList*(n: PNode): PNode = proc toRef*(typ: PType): PType = ## If ``typ`` is a tyObject then it is converted into a `ref ` and ## returned. Otherwise ``typ`` is simply returned as-is. - result = typ + let typ = typ.skipTypes({tyAlias, tyGenericInst}) if typ.kind == tyObject: result = newType(tyRef, typ.owner) rawAddSon(result, typ) @@ -1676,7 +1676,7 @@ proc toObject*(typ: PType): PType = ## If ``typ`` is a tyRef then its immediate son is returned (which in many ## cases should be a ``tyObject``). ## Otherwise ``typ`` is simply returned as-is. - result = typ + result = typ.skipTypes({tyAlias, tyGenericInst}) if result.kind == tyRef: result = result.lastSon @@ -1684,14 +1684,12 @@ proc isException*(t: PType): bool = # check if `y` is object type and it inherits from Exception assert(t != nil) - if t.kind != tyObject: - return false - var base = t - while base != nil: + while base != nil and base.kind in {tyObject, tyRef, tyGenericInst, tyAlias}: if base.sym != nil and base.sym.magic == mException: return true - base = base.lastSon + if base.len == 0: break + else: base = base.lastSon return false proc isImportedException*(t: PType; conf: ConfigRef): bool = diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 7213601de5..12337262a8 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -755,9 +755,10 @@ proc semRaise(c: PContext, n: PNode): PNode = checkSonsLen(n, 1, c.config) if n[0].kind != nkEmpty: n[0] = semExprWithType(c, n[0]) - let typ = n[0].typ + var typ = n[0].typ if not isImportedException(typ, c.config): - if typ.kind != tyRef or typ.lastSon.kind != tyObject: + typ = typ.skipTypes({tyAlias, tyGenericInst}) + if typ.kind != tyRef: localError(c.config, n.info, errExprCannotBeRaised) if not isException(typ.lastSon): localError(c.config, n.info, "raised object of type $1 does not inherit from Exception", diff --git a/tests/exception/texcpt1.nim b/tests/exception/texcpt1.nim index 50a95eeec8..ebbb9d44f5 100644 --- a/tests/exception/texcpt1.nim +++ b/tests/exception/texcpt1.nim @@ -1,9 +1,12 @@ discard """ outputsub: "-6" + targets: "c cpp" """ type ESomething = object of Exception ESomeOtherErr = object of Exception + ESomethingGen[T] = object of Exception + ESomethingGenRef[T] = ref object of Exception proc genErrors(s: string) = if s == "error!": @@ -27,4 +30,17 @@ proc blah(): int = echo blah() +# Issue #7845, raise generic exception +var x: ref ESomethingGen[int] +new(x) +try: + raise x +except ESomethingGen[int] as e: + discard +try: + raise new(ESomethingGenRef[int]) +except ESomethingGenRef[int] as e: + discard +except: + discard \ No newline at end of file From a274d77b55ad69d79c1339d5c43f17ce6bec725b Mon Sep 17 00:00:00 2001 From: cooldome Date: Tue, 12 Jun 2018 00:28:09 +0100 Subject: [PATCH 2/5] Fixes --- compiler/ast.nim | 9 ++++----- tests/exception/texcpt1.nim | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index dd84452f98..03f02de135 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1667,8 +1667,7 @@ proc skipStmtList*(n: PNode): PNode = proc toRef*(typ: PType): PType = ## If ``typ`` is a tyObject then it is converted into a `ref ` and ## returned. Otherwise ``typ`` is simply returned as-is. - let typ = typ.skipTypes({tyAlias, tyGenericInst}) - if typ.kind == tyObject: + if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject: result = newType(tyRef, typ.owner) rawAddSon(result, typ) @@ -1676,9 +1675,9 @@ proc toObject*(typ: PType): PType = ## If ``typ`` is a tyRef then its immediate son is returned (which in many ## cases should be a ``tyObject``). ## Otherwise ``typ`` is simply returned as-is. - result = typ.skipTypes({tyAlias, tyGenericInst}) - if result.kind == tyRef: - result = result.lastSon + let t = typ.skipTypes({tyAlias, tyGenericInst}) + if t.kind == tyRef: t.lastSon + else: typ proc isException*(t: PType): bool = # check if `y` is object type and it inherits from Exception diff --git a/tests/exception/texcpt1.nim b/tests/exception/texcpt1.nim index ebbb9d44f5..835f3610af 100644 --- a/tests/exception/texcpt1.nim +++ b/tests/exception/texcpt1.nim @@ -1,6 +1,5 @@ discard """ outputsub: "-6" - targets: "c cpp" """ type ESomething = object of Exception From 0b709fb916923b0d5e9eab06fc8766e46e63d955 Mon Sep 17 00:00:00 2001 From: cooldome Date: Tue, 12 Jun 2018 21:41:35 +0100 Subject: [PATCH 3/5] FIx test tembarrassing_generic_failure --- compiler/ast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 03f02de135..014ffaf264 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1684,7 +1684,7 @@ proc isException*(t: PType): bool = assert(t != nil) var base = t - while base != nil and base.kind in {tyObject, tyRef, tyGenericInst, tyAlias}: + while base != nil and base.kind in {tyObject, tyGenericInst, tyAlias}: if base.sym != nil and base.sym.magic == mException: return true if base.len == 0: break From c20d1ac1c0c40fbd380a591ea80617eea6fa56b7 Mon Sep 17 00:00:00 2001 From: cooldome Date: Tue, 26 Jun 2018 23:50:06 +0100 Subject: [PATCH 4/5] Fix failing test --- compiler/ast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 0e0ff77b89..a52cf21445 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1693,7 +1693,7 @@ proc isException*(t: PType): bool = assert(t != nil) var base = t - while base != nil and base.kind in {tyObject, tyGenericInst, tyAlias}: + while base != nil and base.kind in {tyRef, tyObject, tyGenericInst, tyAlias}: if base.sym != nil and base.sym.magic == mException: return true if base.len == 0: break From 541c2a3fecd7b1f3e6d9dc7e23a7583000cb68f1 Mon Sep 17 00:00:00 2001 From: cooldome Date: Thu, 28 Jun 2018 09:21:09 +0100 Subject: [PATCH 5/5] one more attempt --- compiler/ast.nim | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index a52cf21445..6ad8d78f56 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1692,12 +1692,14 @@ proc isException*(t: PType): bool = # check if `y` is object type and it inherits from Exception assert(t != nil) + if t.kind notin {tyObject, tyGenericInst}: + return false + var base = t - while base != nil and base.kind in {tyRef, tyObject, tyGenericInst, tyAlias}: + while base != nil: if base.sym != nil and base.sym.magic == mException: return true - if base.len == 0: break - else: base = base.lastSon + base = base.lastSon return false proc isImportedException*(t: PType; conf: ConfigRef): bool =