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:
Zahary Karadjov 2017-06-10 17:00:54 +03:00 • committed by Andreas Rumpf
commit f0999de9dc
3 changed files with 133 additions and 16 deletions

View file

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