diff options
author | Araq <rumpf_a@web.de> | 2015-07-22 16:32:56 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-07-22 16:32:56 +0200 |
commit | b0b716fca73293328d4290d6407f9f3cbcdfe164 (patch) | |
tree | 06d8f84489960e8be1b66558a10c1c4c68b98093 | |
parent | 862ee8d1d3f76dbbae0866f9048292a74fc07b71 (diff) | |
download | Nim-b0b716fca73293328d4290d6407f9f3cbcdfe164.tar.gz |
fixes #3079, fixes #1146, fixes #2879
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 1 | ||||
-rw-r--r-- | compiler/semtypes.nim | 7 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 11 | ||||
-rw-r--r-- | tests/typerel/ttypedesc_as_genericparam1.nim | 6 | ||||
-rw-r--r-- | tests/typerel/ttypedesc_as_genericparam2.nim | 9 |
6 files changed, 33 insertions, 3 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 83d170e26..3a4158204 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -525,6 +525,8 @@ const tfOldSchoolExprStmt* = tfVarargs # for now used to distinguish \ # 'varargs[expr]' from 'varargs[untyped]'. Eventually 'expr' will be # deprecated and this mess can be cleaned up. + tfVoid* = tfVarargs # for historical reasons we conflated 'void' with + # 'empty' ('@[]' has the type 'seq[empty]'). skError* = skUnknown # type flags that are essential for type equality: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 886f9458d..fba64776d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -33,6 +33,7 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if result.typ.kind == tyVar: result = newDeref(result) elif {efWantStmt, efAllowStmt} * flags != {}: result.typ = newTypeS(tyEmpty, c) + result.typ.flags.incl tfVoid else: localError(n.info, errExprXHasNoType, renderTree(result, {renderNoComments})) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 144a41ff0..b518f0fb9 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1051,6 +1051,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = return newOrPrevType(tyError, prev, c) else: var m = newCandidate(c, t) + m.isNoCall = true matches(c, n, copyTree(n), m) if m.state != csMatch and not m.typedescMatched: @@ -1338,7 +1339,11 @@ proc processMagicType(c: PContext, m: PSym) = of mTypeDesc: setMagicType(m, tyTypeDesc, 0) rawAddSon(m.typ, newTypeS(tyNone, c)) - of mVoidType: setMagicType(m, tyEmpty, 0) + of mVoidType: + setMagicType(m, tyEmpty, 0) + # for historical reasons we conflate 'void' with 'empty' so that '@[]' + # has the type 'seq[void]'. + m.typ.flags.incl tfVoid of mArray: setMagicType(m, tyArray, 0) of mOpenArray: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 540f0a04f..a44df5783 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -47,6 +47,7 @@ type coerceDistincts*: bool # this is an explicit coercion that can strip away # a distrinct type typedescMatched*: bool + isNoCall*: bool # misused for generic type instantiations C[T] inheritancePenalty: int # to prefer closest father object type errors*: CandidateErrors # additional clarifications to be displayed to the # user if overload resolution fails @@ -259,7 +260,7 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1; if i != sonsLen(n) - 1: add(result, ", ") proc typeRel*(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation -proc concreteType(c: TCandidate, t: PType): PType = +proc concreteType(c: TCandidate, t: PType; forAny=false): PType = case t.kind of tyArrayConstr: # make it an array @@ -268,6 +269,12 @@ proc concreteType(c: TCandidate, t: PType): PType = addSonSkipIntLit(result, t.sons[1]) # XXX: semantic checking for the type? of tyNil: result = nil # what should it be? + of tyEmpty: + if tfVoid in t.flags and not forAny: result = nil + else: result = t + of tyTypeDesc: + if c.isNoCall: result = t + else: result = nil of tySequence, tySet: if t.sons[0].kind == tyEmpty: result = nil else: result = t @@ -967,7 +974,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyAnything: considerPreviousT: - var concrete = concreteType(c, a) + var concrete = concreteType(c, a, forAny=true) if concrete != nil and doBind: put(c.bindings, f, concrete) return isGeneric diff --git a/tests/typerel/ttypedesc_as_genericparam1.nim b/tests/typerel/ttypedesc_as_genericparam1.nim new file mode 100644 index 000000000..677bf6fc8 --- /dev/null +++ b/tests/typerel/ttypedesc_as_genericparam1.nim @@ -0,0 +1,6 @@ +discard """ + line: 6 + errormsg: "type mismatch: got (typedesc[int])" +""" +# bug #3079, #1146 +echo repr(int) diff --git a/tests/typerel/ttypedesc_as_genericparam2.nim b/tests/typerel/ttypedesc_as_genericparam2.nim new file mode 100644 index 000000000..49d8eea3c --- /dev/null +++ b/tests/typerel/ttypedesc_as_genericparam2.nim @@ -0,0 +1,9 @@ +discard """ + line: 9 + errormsg: "type mismatch: got (empty)" +""" + +# bug #2879 + +var s: seq[int] +echo repr(s.new_seq(3)) |