bugfix: immediate templates are preferred consistently (danger: breaks code)

This commit is contained in:
Araq
2014-02-04 17:29:34 +01:00
parent 96e616198d
commit c097acedd3
4 changed files with 55 additions and 10 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -0,0 +1,17 @@
discard """
output: '''immediate'''
"""
# Test that immediate templates are preferred over non-immediate templates
template foo(a, b: expr) = echo "foo expr"
template foo(a, b: int) = echo "foo int"
template foo(a, b: float) = echo "foo float"
template foo(a, b: string) = echo "foo string"
template foo(a, b: expr) {.immediate.} = echo "immediate"
template foo(a, b: bool) = echo "foo bool"
template foo(a, b: char) = echo "foo char"
foo(undeclaredIdentifier, undeclaredIdentifier2)

View File

@@ -22,7 +22,6 @@ Bugs
- compilation of niminst takes way too long. looks like a regression
- docgen: sometimes effects are listed twice
- 'result' is not properly cleaned for NRVO --> use uninit checking instead
- sneaking with qualifiedLookup() is really broken!
- blocks can "export" an identifier but the CCG generates {} for them ...
- osproc execProcesses can deadlock if all processes fail (as experienced
in c++ mode)