diff options
author | LemonBoy <LemonBoy@users.noreply.github.com> | 2018-08-22 09:40:31 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-08-22 09:40:31 +0200 |
commit | a87341775aa424f252e9e17d58119b0758b58693 (patch) | |
tree | 86a2ba9d2936c65d7fc16d58a9c2198bd36955f6 | |
parent | 3e7aaa70878d6eda0dfb2737243efae6daa6e26c (diff) | |
download | Nim-a87341775aa424f252e9e17d58119b0758b58693.tar.gz |
Don't consider tyAnd/tyNot/tyOr/tyAnything as generic (#8700)
* Don't consider tyAnd/tyNot/tyOr/tyAnything as generic `containsGenericType` was too shallow and didn't check all the branches. The resulting half-processed nodes are often simplified by the constant folding pass but when that's not possible we get a nasty error during codegen. Fixes #8693 * Move the blame onto the semFold pass Slightly better evaluation of `is` forms.
-rw-r--r-- | compiler/semexprs.nim | 5 | ||||
-rw-r--r-- | compiler/semfold.nim | 46 | ||||
-rw-r--r-- | tests/magics/t8693.nim | 29 |
3 files changed, 63 insertions, 17 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index c9f9eb33f..91bee54ac 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -352,6 +352,11 @@ proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode = res = t.kind == tyProc and t.callConv == ccClosure and tfIterator notin t.flags + of "iterator": + let t = skipTypes(t1, abstractRange) + res = t.kind == tyProc and + t.callConv == ccClosure and + tfIterator in t.flags else: res = false else: diff --git a/compiler/semfold.nim b/compiler/semfold.nim index a6c185fdc..0a33fea7a 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -173,32 +173,41 @@ proc makeRangeF(typ: PType, first, last: BiggestFloat; g: ModuleGraph): PType = result.n = n addSonSkipIntLit(result, skipTypes(typ, {tyRange})) -proc evalIs(n, a: PNode): PNode = +proc evalIs(n: PNode, lhs: PSym, g: ModuleGraph): PNode = # XXX: This should use the standard isOpImpl - #internalAssert a.kind == nkSym and a.sym.kind == skType - #internalAssert n.sonsLen == 3 and - # n[2].kind in {nkStrLit..nkTripleStrLit, nkType} + internalAssert g.config, + n.sonsLen == 3 and + lhs.typ != nil and + n[2].kind in {nkStrLit..nkTripleStrLit, nkType} - let t1 = a.sym.typ + var + res = false + t1 = lhs.typ + t2 = n[2].typ + + if t1.kind == tyTypeDesc and t2.kind != tyTypeDesc: + t1 = t1.base if n[2].kind in {nkStrLit..nkTripleStrLit}: case n[2].strVal.normalize of "closure": let t = skipTypes(t1, abstractRange) - result = newIntNode(nkIntLit, ord(t.kind == tyProc and - t.callConv == ccClosure and - tfIterator notin t.flags)) + res = t.kind == tyProc and + t.callConv == ccClosure and + tfIterator notin t.flags of "iterator": let t = skipTypes(t1, abstractRange) - result = newIntNode(nkIntLit, ord(t.kind == tyProc and - t.callConv == ccClosure and - tfIterator in t.flags)) - else: discard + res = t.kind == tyProc and + t.callConv == ccClosure and + tfIterator in t.flags + else: + res = false else: # XXX semexprs.isOpImpl is slightly different and requires a context. yay. let t2 = n[2].typ - var match = sameType(t1, t2) - result = newIntNode(nkIntLit, ord(match)) + res = sameType(t1, t2) + + result = newIntNode(nkIntLit, ord(res)) result.typ = n.typ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = @@ -584,6 +593,9 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode = result = copyTree(s.ast) of skProc, skFunc, skMethod: result = n + of skParam: + if s.typ != nil and s.typ.kind == tyTypeDesc: + result = newSymNodeTypeDesc(s, n.info) of skType: # XXX gensym'ed symbols can come here and cannot be resolved. This is # dirty, but correct. @@ -651,9 +663,9 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode = of mConStrStr: result = foldConStrStr(m, n, g) of mIs: - let a = getConstExpr(m, n[1], g) - if a != nil and a.kind == nkSym and a.sym.kind == skType: - result = evalIs(n, a) + let lhs = getConstExpr(m, n[1], g) + if lhs != nil and lhs.kind == nkSym: + result = evalIs(n, lhs.sym, g) else: result = magicCall(m, n, g) except OverflowError: diff --git a/tests/magics/t8693.nim b/tests/magics/t8693.nim new file mode 100644 index 000000000..554244de4 --- /dev/null +++ b/tests/magics/t8693.nim @@ -0,0 +1,29 @@ +discard """ + output: '''true +false +true +false +false +true +true +false +true +true +''' +""" + +type Foo = int | float + +proc bar(t1, t2: typedesc): bool = + echo (t1 is t2) + (t2 is t1) + +proc bar[T](x: T, t2: typedesc): bool = + echo (T is t2) + (t2 is T) + +echo bar(int, Foo) +echo bar(4, Foo) +echo bar(any, int) +echo bar(int, any) +echo bar(Foo, Foo) |