diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-04-29 22:30:00 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-04-29 22:30:00 +0200 |
commit | e04f3195407cc99f958dd81e0a9d58fe5414e631 (patch) | |
tree | 5a39590d3d11c78b7e511d3a9253434e4ef86dca | |
parent | c870e831c8ab53adacffa80939be70de85de7601 (diff) | |
download | Nim-e04f3195407cc99f958dd81e0a9d58fe5414e631.tar.gz |
fixes #4084
-rw-r--r-- | compiler/sem.nim | 9 | ||||
-rw-r--r-- | compiler/semcall.nim | 14 | ||||
-rw-r--r-- | compiler/types.nim | 9 | ||||
-rw-r--r-- | tests/generics/twrong_explicit_typeargs.nim | 16 |
4 files changed, 38 insertions, 10 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim index 97a20a4da..c29cbe384 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -65,15 +65,6 @@ template semIdeForTemplateOrGeneric(c: PContext; n: PNode; # echo "passing to safeSemExpr: ", renderTree(n) discard safeSemExpr(c, n) -proc typeMismatch(n: PNode, formal, actual: PType) = - if formal.kind != tyError and actual.kind != tyError: - let named = typeToString(formal) - let desc = typeToString(formal, preferDesc) - let x = if named == desc: named else: named & " = " & desc - localError(n.info, errGenerated, msgKindToString(errTypeMismatch) & - typeToString(actual) & ") " & - `%`(msgKindToString(errButExpectedX), [x])) - proc fitNode(c: PContext, formal: PType, arg: PNode): PNode = if arg.typ.isNil: localError(arg.info, errExprXHasNoType, diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 916d897c9..17dd39595 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -361,7 +361,19 @@ proc explicitGenericInstError(n: PNode): PNode = proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = var m: TCandidate - initCandidate(c, m, s, n) + # binding has to stay 'nil' for this to work! + initCandidate(c, m, s, nil) + + for i in 1..sonsLen(n)-1: + let formal = s.ast.sons[genericParamsPos].sons[i-1].typ + let arg = n[i].typ + let tm = typeRel(m, formal, arg, true) + if tm in {isNone, isConvertible}: + if formal.sonsLen > 0 and formal.sons[0].kind != tyNone: + typeMismatch(n, formal.sons[0], arg) + else: + typeMismatch(n, formal, arg) + break var newInst = generateInstance(c, s, m.bindings, n.info) markUsed(n.info, s) styleCheckUse(n.info, s) diff --git a/compiler/types.nim b/compiler/types.nim index c9cbfedb1..bada47075 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1505,3 +1505,12 @@ proc skipHiddenSubConv*(n: PNode): PNode = result.typ = dest else: result = n + +proc typeMismatch*(n: PNode, formal, actual: PType) = + if formal.kind != tyError and actual.kind != tyError: + let named = typeToString(formal) + let desc = typeToString(formal, preferDesc) + let x = if named == desc: named else: named & " = " & desc + localError(n.info, errGenerated, msgKindToString(errTypeMismatch) & + typeToString(actual) & ") " & + `%`(msgKindToString(errButExpectedX), [x])) diff --git a/tests/generics/twrong_explicit_typeargs.nim b/tests/generics/twrong_explicit_typeargs.nim new file mode 100644 index 000000000..37d5b1e38 --- /dev/null +++ b/tests/generics/twrong_explicit_typeargs.nim @@ -0,0 +1,16 @@ +discard """ + errormsg: "type mismatch: got (string) but expected 'int32 or int64'" + line: 16 +""" + +# bug #4084 +type + Image[T] = object + data: seq[T] + +proc newImage[T: int32|int64](w, h: int): ref Image[T] = + new(result) + result.data = newSeq[T](w * h) + +var correct = newImage[int32](320, 200) +var wrong = newImage[string](320, 200) |