summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-02-04 17:29:34 +0100
committerAraq <rumpf_a@web.de>2014-02-04 17:29:34 +0100
commitc097acedd30602fba903ed4ee132b5e5bae91017 (patch)
tree9f9699827b48c3c0d3b2c98b19881c361467a239 /compiler
parent96e616198d100f0e10337c0210b088730d66d91e (diff)
downloadNim-c097acedd30602fba903ed4ee132b5e5bae91017.tar.gz
bugfix: immediate templates are preferred consistently (danger: breaks code)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/astalgo.nim33
-rw-r--r--compiler/lookups.nim14
2 files changed, 38 insertions, 9 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 2505bc687..64c1b717c 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -561,14 +561,31 @@ proc strTableContains(t: TStrTable, n: PSym): bool =
 
 proc strTableRawInsert(data: var TSymSeq, n: PSym) = 
   var h: THash = n.name.h and high(data)
-  while data[h] != nil: 
-    if data[h] == n:
-      # allowed for 'export' feature:
-      #InternalError(n.info, "StrTableRawInsert: " & n.name.s)
-      return
-    h = nextTry(h, high(data))
-  assert(data[h] == nil)
-  data[h] = n
+  if sfImmediate notin n.flags:
+    # fast path:
+    while data[h] != nil:
+      if data[h] == n:
+        # allowed for 'export' feature:
+        #InternalError(n.info, "StrTableRawInsert: " & n.name.s)
+        return
+      h = nextTry(h, high(data))
+    assert(data[h] == nil)
+    data[h] = n
+  else:
+    # slow path; we have to ensure immediate symbols are preferred for
+    # symbol lookups.
+    # consider the chain: foo (immediate), foo, bar, bar (immediate)
+    # then bar (immediate) gets replaced with foo (immediate) and the non
+    # immediate foo is picked! Thus we need to replace it with the first
+    # slot that has in fact the same identifier stored in it!
+    var favPos = -1
+    while data[h] != nil:
+      if data[h] == n: return
+      if favPos < 0 and data[h].name.id == n.name.id: favPos = h
+      h = nextTry(h, high(data))
+    assert(data[h] == nil)
+    data[h] = n
+    if favPos >= 0: swap data[h], data[favPos]
 
 proc symTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) =
   assert prevSym.name.h == newSym.name.h
diff --git a/compiler/lookups.nim b/compiler/lookups.nim
index 6dfd25968..c31eb3121 100644
--- a/compiler/lookups.nim
+++ b/compiler/lookups.nim
@@ -339,4 +339,16 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
                                    n.sons[0].sym.name, o.inSymChoice)
   
   if result != nil and result.kind == skStub: loadStub(result)
-  
+
+when false:
+  proc qualifiedLookUpPreferImmediate*(c: PContext, n: PNode,
+                                       flags = {checkUndeclared}): PSym =
+    var o: TOverloadIter
+    result = initOverloadIter(o, c, n)
+    var a = result
+    while a != nil:
+      if sfImmediate in a.flags: return a
+      a = nextOverloadIter(o, c, n)
+    if result == nil and checkUndeclared in flags: 
+      localError(n.info, errUndeclaredIdentifier, n.considerAcc.s)
+      result = errorSym(c, n)