bugfix: immediate templates are preferred consistently (danger: breaks code)
This commit is contained in:
parent
96e616198d
commit
c097acedd3
4 changed files with 55 additions and 10 deletions
|
|
@ -561,14 +561,31 @@ proc strTableContains(t: TStrTable, n: PSym): bool =
|
||||||
|
|
||||||
proc strTableRawInsert(data: var TSymSeq, n: PSym) =
|
proc strTableRawInsert(data: var TSymSeq, n: PSym) =
|
||||||
var h: THash = n.name.h and high(data)
|
var h: THash = n.name.h and high(data)
|
||||||
while data[h] != nil:
|
if sfImmediate notin n.flags:
|
||||||
if data[h] == n:
|
# fast path:
|
||||||
# allowed for 'export' feature:
|
while data[h] != nil:
|
||||||
#InternalError(n.info, "StrTableRawInsert: " & n.name.s)
|
if data[h] == n:
|
||||||
return
|
# allowed for 'export' feature:
|
||||||
h = nextTry(h, high(data))
|
#InternalError(n.info, "StrTableRawInsert: " & n.name.s)
|
||||||
assert(data[h] == nil)
|
return
|
||||||
data[h] = n
|
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) =
|
proc symTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) =
|
||||||
assert prevSym.name.h == newSym.name.h
|
assert prevSym.name.h == newSym.name.h
|
||||||
|
|
|
||||||
|
|
@ -339,4 +339,16 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||||
n.sons[0].sym.name, o.inSymChoice)
|
n.sons[0].sym.name, o.inSymChoice)
|
||||||
|
|
||||||
if result != nil and result.kind == skStub: loadStub(result)
|
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)
|
||||||
|
|
|
||||||
17
tests/template/tprefer_immediate.nim
Normal file
17
tests/template/tprefer_immediate.nim
Normal 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)
|
||||||
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -22,7 +22,6 @@ Bugs
|
||||||
- compilation of niminst takes way too long. looks like a regression
|
- compilation of niminst takes way too long. looks like a regression
|
||||||
- docgen: sometimes effects are listed twice
|
- docgen: sometimes effects are listed twice
|
||||||
- 'result' is not properly cleaned for NRVO --> use uninit checking instead
|
- '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 ...
|
- blocks can "export" an identifier but the CCG generates {} for them ...
|
||||||
- osproc execProcesses can deadlock if all processes fail (as experienced
|
- osproc execProcesses can deadlock if all processes fail (as experienced
|
||||||
in c++ mode)
|
in c++ mode)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue