Fix #5962
During the instantiation of a generic type A, some other generic type B may be instantiated multiple times with different parameters. We can think about each instantiation as a function call that should temporary bind the parameter names to concrete types. The problem with the existing implementation in semtypinst was that it was performing this binding within a shared global table. In this sense, it was executing the code as a programming language featuring only global variables. In such a language, re-entrant functions cannot be defined properly and hence this was leading to problems with similar types. The solution is simple - just like we need to introduce stack frames to handle re-entrant functions, we introduce a stack of type bindings that are pushed and popped during the generic instantiations.
This commit is contained in:
parent
cd02561368
commit
f0999de9dc
3 changed files with 133 additions and 16 deletions
|
|
@ -174,10 +174,14 @@ proc sideEffectsCheck(c: PContext, s: PSym) =
|
|||
|
||||
proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
|
||||
allowMetaTypes = false): PType =
|
||||
var cl: TReplTypeVars
|
||||
var
|
||||
typeMap: LayeredIdTable
|
||||
cl: TReplTypeVars
|
||||
|
||||
initIdTable(cl.symMap)
|
||||
initIdTable(cl.typeMap)
|
||||
initIdTable(cl.localCache)
|
||||
initIdTable(typeMap.topLayer)
|
||||
cl.typeMap = addr(typeMap)
|
||||
cl.info = info
|
||||
cl.c = c
|
||||
cl.allowMetaTypes = allowMetaTypes
|
||||
|
|
@ -201,7 +205,8 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
|||
#addDecl(c, prc)
|
||||
|
||||
pushInfoContext(info)
|
||||
var cl = initTypeVars(c, pt, info, nil)
|
||||
var typeMap = initLayeredTypeMap(pt)
|
||||
var cl = initTypeVars(c, addr(typeMap), info, nil)
|
||||
var result = instCopyType(cl, prc.typ)
|
||||
let originalParams = result.n
|
||||
result.n = originalParams.shallowCopy
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue