From e9619d727894637ba4ef2d84473c5a06a17a8fee Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 17 Dec 2014 01:11:30 +0100 Subject: [PATCH] fixes #1655 --- compiler/semexprs.nim | 4 ++-- compiler/semtypes.nim | 24 +++++++++++++----------- tests/metatype/tautonotgeneric.nim | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 tests/metatype/tautonotgeneric.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index ac82e9fed0..ce06c2e77d 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 1d0bba6f05..e33df75ffd 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 0000000000..a55ae488e6 --- /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)