diff options
Diffstat (limited to 'compiler/semtypinst.nim')
-rw-r--r-- | compiler/semtypinst.nim | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 61d92bb19..22ea09af1 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -9,7 +9,8 @@ # This module does the instantiation of generic types. -import ast, astalgo, msgs, types, magicsys, semdata, renderer, options +import ast, astalgo, msgs, types, magicsys, semdata, renderer, options, + lineinfos const tfInstClearedFlags = {tfHasMeta, tfUnresolved} @@ -27,7 +28,7 @@ proc checkConstructedType*(conf: ConfigRef; info: TLineInfo, typ: PType) = localError(conf, info, "invalid pragma: acyclic") elif t.kind in {tyVar, tyLent} and t.sons[0].kind in {tyVar, tyLent}: localError(conf, info, "type 'var var' is not allowed") - elif computeSize(t) == szIllegalRecursion: + elif computeSize(conf, t) == szIllegalRecursion: localError(conf, info, "illegal recursion in type '" & typeToString(t) & "'") when false: if t.kind == tyObject and t.sons[0] != nil: @@ -143,17 +144,6 @@ proc isTypeParam(n: PNode): bool = (n.sym.kind == skGenericParam or (n.sym.kind == skType and sfFromGeneric in n.sym.flags)) -proc hasGenericArguments*(n: PNode): bool = - if n.kind == nkSym: - return n.sym.kind == skGenericParam or - tfInferrableStatic in n.sym.typ.flags or - (n.sym.kind == skType and - n.sym.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} != {}) - else: - for i in 0..<n.safeLen: - if hasGenericArguments(n.sons[i]): return true - return false - proc reResolveCallsWithTypedescParams(cl: var TReplTypeVars, n: PNode): PNode = # This is needed for tgenericshardcases # It's possible that a generic param will be used in a proc call to a @@ -230,6 +220,17 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = # symbol is not our business: if cl.owner != nil and s.owner != cl.owner: return s + + # XXX: Bound symbols in default parameter expressions may reach here. + # We cannot process them, becase `sym.n` may point to a proc body with + # cyclic references that will lead to an infinite recursion. + # Perhaps we should not use a black-list here, but a whitelist instead + # (e.g. skGenericParam and skType). + # Note: `s.magic` may be `mType` in an example such as: + # proc foo[T](a: T, b = myDefault(type(a))) + if s.kind == skProc or s.magic != mNone: + return s + #result = PSym(idTableGet(cl.symMap, s)) #if result == nil: result = copySym(s, false) @@ -277,7 +278,8 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = # is difficult to handle: const eqFlags = eqTypeFlags + {tfGcSafe} var body = t.sons[0] - if body.kind != tyGenericBody: internalError(cl.c.config, cl.info, "no generic body") + if body.kind != tyGenericBody: + internalError(cl.c.config, cl.info, "no generic body") var header: PType = t # search for some instantiation here: if cl.allowMetaTypes: @@ -568,35 +570,35 @@ proc replaceTypesInBody*(p: PContext, pt: TIdTable, n: PNode; var typeMap = initLayeredTypeMap(pt) var cl = initTypeVars(p, addr(typeMap), n.info, owner) cl.allowMetaTypes = allowMetaTypes - pushInfoContext(n.info) + pushInfoContext(p.config, n.info) result = replaceTypeVarsN(cl, n) - popInfoContext() + popInfoContext(p.config) proc replaceTypesForLambda*(p: PContext, pt: TIdTable, n: PNode; original, new: PSym): PNode = var typeMap = initLayeredTypeMap(pt) var cl = initTypeVars(p, addr(typeMap), n.info, original) idTablePut(cl.symMap, original, new) - pushInfoContext(n.info) + pushInfoContext(p.config, n.info) result = replaceTypeVarsN(cl, n) - popInfoContext() + popInfoContext(p.config) proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo, t: PType): PType = var typeMap = initLayeredTypeMap(pt) var cl = initTypeVars(p, addr(typeMap), info, nil) - pushInfoContext(info) + pushInfoContext(p.config, info) result = replaceTypeVarsT(cl, t) - popInfoContext() + popInfoContext(p.config) proc prepareMetatypeForSigmatch*(p: PContext, pt: TIdTable, info: TLineInfo, t: PType): PType = var typeMap = initLayeredTypeMap(pt) var cl = initTypeVars(p, addr(typeMap), info, nil) cl.allowMetaTypes = true - pushInfoContext(info) + pushInfoContext(p.config, info) result = replaceTypeVarsT(cl, t) - popInfoContext() + popInfoContext(p.config) template generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode, t: PType): untyped = |