diff options
Diffstat (limited to 'compiler/seminst.nim')
-rw-r--r-- | compiler/seminst.nim | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 2c767ffc6..4a45dee9d 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -10,6 +10,47 @@ # This module implements the instantiation of generic procs. # included from sem.nim +proc addObjFieldsToLocalScope(c: PContext; n: PNode) = + template rec(n) = addObjFieldsToLocalScope(c, n) + case n.kind + of nkRecList: + for i in countup(0, len(n)-1): + rec n[i] + of nkRecCase: + if n.len > 0: rec n.sons[0] + for i in countup(1, len(n)-1): + if n[i].kind in {nkOfBranch, nkElse}: rec lastSon(n[i]) + of nkSym: + let f = n.sym + if f.kind == skField and fieldVisible(c, f): + c.currentScope.symbols.strTableIncl(f, onConflictKeepOld=true) + incl(f.flags, sfUsed) + # it is not an error to shadow fields via parameters + else: discard + +proc rawPushProcCon(c: PContext, owner: PSym) = + var x: PProcCon + new(x) + x.owner = owner + x.next = c.p + c.p = x + +proc rawHandleSelf(c: PContext; owner: PSym) = + if c.selfName != nil and owner.kind in {skProc, skMethod, skConverter, skIterator, skMacro} and owner.typ != nil: + let params = owner.typ.n + if params.len > 1: + let arg = params[1].sym + if arg.name.id == c.selfName.id: + c.p.selfSym = arg + arg.flags.incl sfIsSelf + let t = c.p.selfSym.typ.skipTypes(abstractPtrs) + if t.kind == tyObject: + addObjFieldsToLocalScope(c, t.n) + +proc pushProcCon*(c: PContext; owner: PSym) = + rawPushProcCon(c, owner) + rawHandleSelf(c, owner) + iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym = internalAssert n.kind == nkGenericParams for i, a in n.pairs: @@ -248,7 +289,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, addDecl(c, s) entry.concreteTypes[i] = s.typ inc i - pushProcCon(c, result) + rawPushProcCon(c, result) instantiateProcType(c, pt, result, info) for j in 1 .. result.typ.len-1: entry.concreteTypes[i] = result.typ.sons[j] @@ -263,6 +304,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, # a ``compiles`` context but this is the lesser evil. See # bug #1055 (tevilcompiles). #if c.compilesContextId == 0: + rawHandleSelf(c, result) entry.compilesId = c.compilesContextId fn.procInstCache.safeAdd(entry) c.generics.add(makeInstPair(fn, entry)) |