mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-10 06:54:16 +00:00
fixes #3313
This commit is contained in:
@@ -738,6 +738,8 @@ type
|
||||
name*: Rope
|
||||
path*: PNode # can be a string literal!
|
||||
|
||||
CompilesId* = int ## id that is used for the caching logic within
|
||||
## ``system.compiles``. See the seminst module.
|
||||
TInstantiation* = object
|
||||
sym*: PSym
|
||||
concreteTypes*: seq[PType]
|
||||
@@ -745,6 +747,7 @@ type
|
||||
# needed in caas mode for purging the cache
|
||||
# XXX: it's possible to switch to a
|
||||
# simple ref count here
|
||||
compilesId*: CompilesId
|
||||
|
||||
PInstantiation* = ref TInstantiation
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ type
|
||||
inGenericContext*: int # > 0 if we are in a generic type
|
||||
inUnrolledContext*: int # > 0 if we are unrolling a loop
|
||||
inCompilesContext*: int # > 0 if we are in a ``compiles`` magic
|
||||
compilesContextIdGenerator*: int
|
||||
inGenericInst*: int # > 0 if we are instantiating a generic
|
||||
converters*: TSymSeq # sequence of converters
|
||||
patterns*: TSymSeq # sequence of pattern matchers
|
||||
|
||||
@@ -1636,7 +1636,9 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
# watch out, hacks ahead:
|
||||
let oldErrorCount = msgs.gErrorCounter
|
||||
let oldErrorMax = msgs.gErrorMax
|
||||
inc c.inCompilesContext
|
||||
let oldCompilesId = c.inCompilesContext
|
||||
inc c.compilesContextIdGenerator
|
||||
c.inCompilesContext = c.compilesContextIdGenerator
|
||||
# do not halt after first error:
|
||||
msgs.gErrorMax = high(int)
|
||||
|
||||
@@ -1660,6 +1662,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
except ERecoverableError:
|
||||
discard
|
||||
# undo symbol table changes (as far as it's possible):
|
||||
c.inCompilesContext = oldCompilesId
|
||||
c.generics = oldGenerics
|
||||
c.inGenericContext = oldInGenericContext
|
||||
c.inUnrolledContext = oldInUnrolledContext
|
||||
@@ -1668,7 +1671,6 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
msgs.setInfoContextLen(oldContextLen)
|
||||
setLen(gOwners, oldOwnerLen)
|
||||
c.currentScope = oldScope
|
||||
dec c.inCompilesContext
|
||||
errorOutputs = oldErrorOutputs
|
||||
msgs.gErrorCounter = oldErrorCount
|
||||
msgs.gErrorMax = oldErrorMax
|
||||
|
||||
@@ -47,10 +47,11 @@ proc sameInstantiation(a, b: TInstantiation): bool =
|
||||
flags = {ExactTypeDescValues}): return
|
||||
result = true
|
||||
|
||||
proc genericCacheGet(genericSym: PSym, entry: TInstantiation): PSym =
|
||||
proc genericCacheGet(genericSym: PSym, entry: TInstantiation;
|
||||
id: CompilesId): PSym =
|
||||
if genericSym.procInstCache != nil:
|
||||
for inst in genericSym.procInstCache:
|
||||
if sameInstantiation(entry, inst[]):
|
||||
if inst.compilesId == id and sameInstantiation(entry, inst[]):
|
||||
return inst.sym
|
||||
|
||||
proc removeDefaultParamValues(n: PNode) =
|
||||
@@ -249,13 +250,15 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||
if tfTriggersCompileTime in result.typ.flags:
|
||||
incl(result.flags, sfCompileTime)
|
||||
n.sons[genericParamsPos] = ast.emptyNode
|
||||
var oldPrc = genericCacheGet(fn, entry[])
|
||||
var oldPrc = genericCacheGet(fn, entry[], c.inCompilesContext)
|
||||
if oldPrc == nil:
|
||||
# we MUST not add potentially wrong instantiations to the caching mechanism.
|
||||
# This means recursive instantiations behave differently when in
|
||||
# a ``compiles`` context but this is the lesser evil. See
|
||||
# bug #1055 (tevilcompiles).
|
||||
if c.inCompilesContext == 0: fn.procInstCache.safeAdd(entry)
|
||||
#if c.inCompilesContext == 0:
|
||||
entry.compilesId = c.inCompilesContext
|
||||
fn.procInstCache.safeAdd(entry)
|
||||
c.generics.add(makeInstPair(fn, entry))
|
||||
if n.sons[pragmasPos].kind != nkEmpty:
|
||||
pragma(c, result, n.sons[pragmasPos], allRoutinePragmas)
|
||||
|
||||
Reference in New Issue
Block a user