diff options
author | Araq <rumpf_a@web.de> | 2015-01-12 01:43:25 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-01-12 02:00:37 +0100 |
commit | b9079b87134864a478ac453fd31363e6d8d86794 (patch) | |
tree | 0092602d8d248c4be2b300e9699a1bc710099ba9 /compiler | |
parent | c87f1eb5813cca9ce5c1f251d9b3af3a2d47be71 (diff) | |
download | Nim-b9079b87134864a478ac453fd31363e6d8d86794.tar.gz |
fixes #1915
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgexprs.nim | 4 | ||||
-rw-r--r-- | compiler/evaltempl.nim | 2 | ||||
-rw-r--r-- | compiler/semdata.nim | 1 | ||||
-rw-r--r-- | compiler/semexprs.nim | 13 | ||||
-rw-r--r-- | compiler/semstmts.nim | 3 | ||||
-rw-r--r-- | compiler/semtempl.nim | 15 |
6 files changed, 29 insertions, 9 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 4a3be0027..2d3cf562b 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1977,7 +1977,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of skParam: if sym.loc.r == nil or sym.loc.t == nil: #echo "FAILED FOR PRCO ", p.prc.name.s - internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id) + #debug p.prc.typ.n + #echo renderTree(p.prc.ast, {renderIds}) + internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id) putLocIntoDest(p, d, sym.loc) else: internalError(n.info, "expr(" & $sym.kind & "); unknown symbol") of nkNilLit: diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 78cc691c0..946be68f8 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -29,7 +29,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = of nkSym: var s = templ.sym if s.owner.id == c.owner.id: - if s.kind == skParam: + if s.kind == skParam and sfGenSym notin s.flags: let x = actual.sons[s.position] if x.kind == nkArgList: for y in items(x): result.add(y) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 623f9b633..bb82db292 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -35,6 +35,7 @@ type inTryStmt*: int # whether we are in a try statement; works also # in standalone ``except`` and ``finally`` next*: PProcCon # used for stacking procedure contexts + wasForwarded*: bool # whether the current proc has a separate header TInstantiationPair* = object genericSym*: PSym diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index f9889eee1..a3ae0263d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -109,9 +109,16 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = # if a proc accesses a global variable, it is not side effect free: if sfGlobal in s.flags: incl(c.p.owner.flags, sfSideEffect) - elif s.kind == skParam and s.typ.kind == tyStatic and s.typ.n != nil: - # XXX see the hack in sigmatch.nim ... - return s.typ.n + elif s.kind == skParam: + if s.typ.kind == tyStatic and s.typ.n != nil: + # XXX see the hack in sigmatch.nim ... + return s.typ.n + elif sfGenSym in s.flags and c.p.wasForwarded: + # gensym'ed parameters that nevertheless have been forward declared + # need a special fixup: + let realParam = c.p.owner.typ.n[s.position+1] + internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam + return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info) result = newSymNode(s, n.info) # We cannot check for access to outer vars for example because it's still # not sure the symbol really ends up being used: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 44f14afd8..3b90337e5 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -982,7 +982,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, # process parameters: if n.sons[paramsPos].kind != nkEmpty: semParamList(c, n.sons[paramsPos], gp, s) - if sonsLen(gp) > 0: + if sonsLen(gp) > 0: if n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: n.sons[genericParamsPos] = gp @@ -1049,6 +1049,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if n.sons[genericParamsPos].kind == nkEmpty or usePseudoGenerics: if not usePseudoGenerics: paramsTypeCheck(c, s.typ) pushProcCon(c, s) + c.p.wasForwarded = proto != nil maybeAddResult(c, s, n) if sfImportc notin s.flags: # no semantic checking for importc: diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 81e4f2463..e2c46d3ab 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -127,7 +127,7 @@ proc getIdentNode(c: var TemplCtx, n: PNode): PNode = proc isTemplParam(c: TemplCtx, n: PNode): bool {.inline.} = result = n.kind == nkSym and n.sym.kind == skParam and - n.sym.owner == c.owner + n.sym.owner == c.owner and sfGenSym notin n.sym.flags proc semTemplBody(c: var TemplCtx, n: PNode): PNode @@ -246,8 +246,8 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode = n.sons[i] = semTemplBody(c, n.sons[i]) closeScope(c) -proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind) = - for i in countup(0, sonsLen(n) - 1): +proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind; start=0) = + for i in countup(start, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a) @@ -348,6 +348,10 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = a.sons[L-1] = semTemplBodyScope(c, a.sons[L-1]) of nkVarSection: semTemplSomeDecl(c, n, skVar) of nkLetSection: semTemplSomeDecl(c, n, skLet) + of nkFormalParams: + checkMinSonsLen(n, 1) + n.sons[0] = semTemplBody(c, n.sons[0]) + semTemplSomeDecl(c, n, skParam, 1) of nkConstSection: for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] @@ -485,6 +489,11 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = # process parameters: if n.sons[paramsPos].kind != nkEmpty: semParamList(c, n.sons[paramsPos], gp, s) + # a template's parameters are not gensym'ed even if that was originally the + # case as we determine whether it's a template parameter in the template + # body by the absense of the skGenSym flag: + for i in 1 .. s.typ.n.len-1: + s.typ.n.sons[i].sym.flags.excl sfGenSym if sonsLen(gp) > 0: if n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: |