diff options
author | Araq <rumpf_a@web.de> | 2014-12-17 01:11:30 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-12-17 01:11:30 +0100 |
commit | e9619d727894637ba4ef2d84473c5a06a17a8fee (patch) | |
tree | 83e11ddfa807fcc1b5d191bf81213caf14236d73 | |
parent | 8be177627a15de6328d761c61ff52c25fcdb92c4 (diff) | |
download | Nim-e9619d727894637ba4ef2d84473c5a06a17a8fee.tar.gz |
fixes #1655
-rw-r--r-- | compiler/semexprs.nim | 4 | ||||
-rw-r--r-- | compiler/semtypes.nim | 24 | ||||
-rw-r--r-- | tests/metatype/tautonotgeneric.nim | 15 |
3 files changed, 30 insertions, 13 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index ac82e9fed..ce06c2e77 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1249,8 +1249,8 @@ proc semAsgn(c: PContext, n: PNode): PNode = proc semReturn(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1) - if c.p.owner.kind in {skConverter, skMethod, skProc, skMacro} or - c.p.owner.kind == skClosureIterator: + if c.p.owner.kind in {skConverter, skMethod, skProc, skMacro, + skClosureIterator}: if n.sons[0].kind != nkEmpty: # transform ``return expr`` to ``result = expr; return`` if c.p.resultSym != nil: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 1d0bba6f0..e33df75ff 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -939,17 +939,19 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, # turn explicit 'void' return type into 'nil' because the rest of the # compiler only checks for 'nil': if skipTypes(r, {tyGenericInst}).kind != tyEmpty: - if r.sym == nil or sfAnon notin r.sym.flags: - let lifted = liftParamType(c, kind, genericParams, r, "result", - n.sons[0].info) - if lifted != nil: r = lifted - r.flags.incl tfRetType - r = skipIntLit(r) - if kind == skIterator: - # see tchainediterators - # in cases like iterator foo(it: iterator): type(it) - # we don't need to change the return type to iter[T] - if not r.isInlineIterator: r = newTypeWithSons(c, tyIter, @[r]) + # 'auto' as a return type does not imply a generic: + if r.kind != tyExpr: + if r.sym == nil or sfAnon notin r.sym.flags: + let lifted = liftParamType(c, kind, genericParams, r, "result", + n.sons[0].info) + if lifted != nil: r = lifted + r.flags.incl tfRetType + r = skipIntLit(r) + if kind == skIterator: + # see tchainediterators + # in cases like iterator foo(it: iterator): type(it) + # we don't need to change the return type to iter[T] + if not r.isInlineIterator: r = newTypeWithSons(c, tyIter, @[r]) result.sons[0] = r res.typ = r diff --git a/tests/metatype/tautonotgeneric.nim b/tests/metatype/tautonotgeneric.nim new file mode 100644 index 000000000..a55ae488e --- /dev/null +++ b/tests/metatype/tautonotgeneric.nim @@ -0,0 +1,15 @@ +discard """ + output: "wof!" +""" + +# bug #1659 +type Animal = ref object {.inheritable.} +type Dog = ref object of Animal + +method say(a: Animal): auto = "wat!" +method say(a: Dog): auto = "wof!" + +proc saySomething(a: Animal): auto = a.say() + +var a = Dog() +echo saySomething(a) |