summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-12-17 01:11:30 +0100
committerAraq <rumpf_a@web.de>2014-12-17 01:11:30 +0100
commite9619d727894637ba4ef2d84473c5a06a17a8fee (patch)
tree83e11ddfa807fcc1b5d191bf81213caf14236d73
parent8be177627a15de6328d761c61ff52c25fcdb92c4 (diff)
downloadNim-e9619d727894637ba4ef2d84473c5a06a17a8fee.tar.gz
fixes #1655
-rw-r--r--compiler/semexprs.nim4
-rw-r--r--compiler/semtypes.nim24
-rw-r--r--tests/metatype/tautonotgeneric.nim15
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)