diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/evaltempl.nim | 13 | ||||
-rw-r--r-- | compiler/semexprs.nim | 2 | ||||
-rw-r--r-- | compiler/semtempl.nim | 11 | ||||
-rw-r--r-- | compiler/semtypes.nim | 5 |
4 files changed, 30 insertions, 1 deletions
diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 5895368bb..77c136d63 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -33,6 +33,19 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = let x = param if x.kind == nkArgList: for y in items(x): result.add(y) + elif nfDefaultRefsParam in x.flags: + # value of default param needs to be evaluated like template body + # if it contains other template params + var res: PNode + if isAtom(x): + res = newNodeI(nkPar, x.info) + evalTemplateAux(x, actual, c, res) + if res.len == 1: res = res[0] + else: + res = copyNode(x) + for i in 0..<x.safeLen: + evalTemplateAux(x[i], actual, c, res) + result.add res else: result.add copyTree(x) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 1307b0ab7..a83da5849 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -813,7 +813,7 @@ proc isUnresolvedSym(s: PSym): bool = result = s.kind == skGenericParam if not result and s.typ != nil: result = tfInferrableStatic in s.typ.flags or - (s.kind == skParam and s.typ.isMetaType) or + (s.kind == skParam and (s.typ.isMetaType or sfTemplateParam in s.flags)) or (s.kind == skType and s.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} != {}) diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index aef0ce9b3..7546d095d 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -743,6 +743,17 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = c: c, owner: s ) + # handle default params: + for i in 1..<s.typ.n.len: + let param = s.typ.n[i].sym + if param.ast != nil: + # param default values need to be treated like template body: + if sfDirty in s.flags: + param.ast = semTemplBodyDirty(ctx, param.ast) + else: + param.ast = semTemplBody(ctx, param.ast) + if param.ast.referencesAnotherParam(s): + param.ast.flags.incl nfDefaultRefsParam if sfDirty in s.flags: n[bodyPos] = semTemplBodyDirty(ctx, n[bodyPos]) else: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 5faefc9aa..8cba88747 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1365,6 +1365,11 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, "either use ';' (semicolon) or explicitly write each default value") message(c.config, a.info, warnImplicitDefaultValue, msg) block determineType: + if kind == skTemplate and hasUnresolvedArgs(c, def): + # template default value depends on other parameter + # don't do any typechecking + def.typ = makeTypeFromExpr(c, def.copyTree) + break determineType let isGeneric = isCurrentlyGeneric() inc c.inGenericContext, ord(isGeneric) def = semExprWithType(c, def, {efDetermineType, efAllowSymChoice}, typ) |