summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-08-22 23:38:08 +0200
committerAraq <rumpf_a@web.de>2012-08-22 23:38:08 +0200
commit1c6870712ba368ef9112f8791b3e4123b6cffbcc (patch)
tree9498261071be728848597bea51ee74d569d1d153
parent5f0bbb911fc70f9e2787247c8abf99792edafdd0 (diff)
downloadNim-1c6870712ba368ef9112f8791b3e4123b6cffbcc.tar.gz
bugfix for methods (comment in #185)
-rwxr-xr-xcompiler/cgmeth.nim3
-rwxr-xr-xcompiler/transf.nim11
2 files changed, 10 insertions, 4 deletions
diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim
index baa1e292c..76f5414ec 100755
--- a/compiler/cgmeth.nim
+++ b/compiler/cgmeth.nim
@@ -36,6 +36,7 @@ proc methodCall*(n: PNode): PNode =
   result = n
   # replace ordinary method by dispatcher method: 
   var disp = lastSon(result.sons[0].sym.ast).sym
+  assert sfDispatcher in disp.flags
   result.sons[0].sym = disp
   # change the arguments to up/downcasts to fit the dispatcher's parameters:
   for i in countup(1, sonsLen(result)-1):
@@ -99,6 +100,8 @@ proc methodDef*(s: PSym, fromCache: bool) =
     if s.typ.sons[0] != nil: 
       disp.ast.sons[resultPos].sym = copySym(s.ast.sons[resultPos].sym)
     attachDispatcher(s, newSymNode(disp))
+    # attach to itself to prevent bugs:
+    attachDispatcher(disp, newSymNode(disp))
 
 proc relevantCol(methods: TSymSeq, col: int): bool = 
   # returns true iff the position is relevant
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 57ada2b1a..fd356442f 100755
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -556,11 +556,14 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
           inc(j)
       add(result, a.ptransnode)
     if len(result) == 2: result = result[1]
-  elif n.sons[0].kind == nkSym and n.sons[0].sym.kind == skMethod: 
-    # use the dispatcher for the call:
-    result = methodCall(transformSons(c, n).pnode).ptransNode
   else:
-    result = transformSons(c, n)
+    let s = transformSons(c, n).pnode
+    # bugfix: check after 'transformSons' if it's still a method call:
+    # use the dispatcher for the call:
+    if s.sons[0].kind == nkSym and s.sons[0].sym.kind == skMethod:
+      result = methodCall(s).ptransNode
+    else:
+      result = s.ptransNode
 
 proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
   # symbols that expand to a complex constant (array, etc.) should not be