diff options
author | Araq <rumpf_a@web.de> | 2014-02-04 17:29:34 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-02-04 17:29:34 +0100 |
commit | c097acedd30602fba903ed4ee132b5e5bae91017 (patch) | |
tree | 9f9699827b48c3c0d3b2c98b19881c361467a239 /compiler | |
parent | 96e616198d100f0e10337c0210b088730d66d91e (diff) | |
download | Nim-c097acedd30602fba903ed4ee132b5e5bae91017.tar.gz |
bugfix: immediate templates are preferred consistently (danger: breaks code)
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/astalgo.nim | 33 | ||||
-rw-r--r-- | compiler/lookups.nim | 14 |
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) |