diff options
author | Saem Ghani <saemghani+github@gmail.com> | 2021-03-22 04:46:34 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-22 12:46:34 +0100 |
commit | e5873b3a9300897443f0f2e2db128e3463089003 (patch) | |
tree | cce53a09190b9cc2ee5bdec6fdb50338507a550e | |
parent | c8dda867f2a2607d4049759d09593a66b1697d02 (diff) | |
download | Nim-e5873b3a9300897443f0f2e2db128e3463089003.tar.gz |
semTemplateDef and t17433 clean-ups (#17448)
- use `doAssert` in t17433 - use setGenericParamsMisc in semTemplateDef akin to semProcAux - pragma handling in semTemplateDef inline with semProcAux
-rw-r--r-- | compiler/sem.nim | 24 | ||||
-rw-r--r-- | compiler/semstmts.nim | 18 | ||||
-rw-r--r-- | compiler/semtempl.nim | 38 | ||||
-rw-r--r-- | tests/template/t17433.nim | 6 |
4 files changed, 44 insertions, 42 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim index 5593f8b02..bb42b5c1b 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -485,11 +485,31 @@ proc semConstBoolExpr(c: PContext, n: PNode): PNode = if result.kind != nkIntLit: localError(c.config, n.info, errConstExprExpected) - proc semGenericStmt(c: PContext, n: PNode): PNode proc semConceptBody(c: PContext, n: PNode): PNode -include semtypes, semtempl, semgnrc, semstmts, semexprs +include semtypes + +proc setGenericParamsMisc(c: PContext; n: PNode) = + ## used by call defs (procs, templates, macros, ...) to analyse their generic + ## params, and store the originals in miscPos for better error reporting. + let orig = n[genericParamsPos] + + doAssert orig.kind in {nkEmpty, nkGenericParams} + + if n[genericParamsPos].kind == nkEmpty: + n[genericParamsPos] = newNodeI(nkGenericParams, n.info) + else: + # we keep the original params around for better error messages, see + # issue https://github.com/nim-lang/Nim/issues/1713 + n[genericParamsPos] = semGenericParamList(c, orig) + + if n[miscPos].kind == nkEmpty: + n[miscPos] = newTree(nkBracket, c.graph.emptyNode, orig) + else: + n[miscPos][1] = orig + +include semtempl, semgnrc, semstmts, semexprs proc addCodeForGenerics(c: PContext, n: PNode) = for i in c.lastGenericIdx..<c.generics.len: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index a98103478..ff8f68ed0 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1769,23 +1769,6 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) = else: localError(c.config, n.info, "'method' needs a parameter that has an object type") -proc setGenericParamsMisc(c: PContext; n: PNode) = - let orig = n[genericParamsPos] - - doAssert orig.kind in {nkEmpty, nkGenericParams} - - if n[genericParamsPos].kind == nkEmpty: - n[genericParamsPos] = newNodeI(nkGenericParams, n.info) - else: - # we keep the original params around for better error messages, see - # issue https://github.com/nim-lang/Nim/issues/1713 - n[genericParamsPos] = semGenericParamList(c, orig) - - if n[miscPos].kind == nkEmpty: - n[miscPos] = newTree(nkBracket, c.graph.emptyNode, orig) - else: - n[miscPos][1] = orig - proc semProcAux(c: PContext, n: PNode, kind: TSymKind, validPragmas: TSpecialWords, flags: TExprFlags = {}): PNode = result = semProcAnnotation(c, n, validPragmas) @@ -1839,7 +1822,6 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if n[paramsPos].kind != nkEmpty: semParamList(c, n[paramsPos], n[genericParamsPos], s) - # we maybe have implicit type parameters: else: s.typ = newProcType(c, n.info) diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 4bb9f3e6b..40502daf4 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -595,12 +595,14 @@ proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode = result[i] = semTemplBodyDirty(c, n[i]) proc semTemplateDef(c: PContext, n: PNode): PNode = + result = n var s: PSym if isTopLevel(c): - s = semIdentVis(c, skTemplate, n[0], {sfExported}) + s = semIdentVis(c, skTemplate, n[namePos], {sfExported}) incl(s.flags, sfGlobal) else: - s = semIdentVis(c, skTemplate, n[0], {}) + s = semIdentVis(c, skTemplate, n[namePos], {}) + assert s.kind == skTemplate if s.owner != nil: const names = ["!=", ">=", ">", "incl", "excl", "in", "notin", "isnot"] @@ -608,26 +610,23 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = s.owner.name.s == "vm" and s.name.s == "stackTrace": incl(s.flags, sfCallsite) + s.ast = n + styleCheckDef(c.config, s) - onDef(n[0].info, s) + onDef(n[namePos].info, s) # check parameter list: #s.scope = c.currentScope pushOwner(c, s) openScope(c) - n[namePos] = newSymNode(s, n[namePos].info) - if n[pragmasPos].kind != nkEmpty: - pragma(c, s, n[pragmasPos], templatePragmas) - - var gp: PNode - if n[genericParamsPos].kind != nkEmpty: - n[genericParamsPos] = semGenericParamList(c, n[genericParamsPos]) - gp = n[genericParamsPos] - else: - gp = newNodeI(nkGenericParams, n.info) + n[namePos] = newSymNode(s) + pragmaCallable(c, s, n, templatePragmas) + implicitPragmas(c, s, n.info, templatePragmas) + + setGenericParamsMisc(c, n) # process parameters: var allUntyped = true if n[paramsPos].kind != nkEmpty: - semParamList(c, n[paramsPos], gp, s) + semParamList(c, n[paramsPos], n[genericParamsPos], 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 absence of the sfGenSym flag: @@ -636,18 +635,21 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = param.flags.incl sfTemplateParam param.flags.excl sfGenSym if param.typ.kind != tyUntyped: allUntyped = false - if gp.len > 0 and n[genericParamsPos].kind == nkEmpty: - # we have a list of implicit type parameters: - n[genericParamsPos] = gp else: s.typ = newTypeS(tyProc, c) # XXX why do we need tyTyped as a return type again? s.typ.n = newNodeI(nkFormalParams, n.info) rawAddSon(s.typ, newTypeS(tyTyped, c)) s.typ.n.add newNodeIT(nkType, n.info, s.typ[0]) + if n[genericParamsPos].safeLen == 0: + # restore original generic type params as no explicit or implicit were found + n[genericParamsPos] = n[miscPos][1] + n[miscPos] = c.graph.emptyNode if allUntyped: incl(s.flags, sfAllUntyped) + if n[patternPos].kind != nkEmpty: n[patternPos] = semPattern(c, n[patternPos]) + var ctx: TemplCtx ctx.toBind = initIntSet() ctx.toMixin = initIntSet() @@ -662,8 +664,6 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = semIdeForTemplateOrGeneric(c, n[bodyPos], ctx.cursorInBody) closeScope(c) popOwner(c) - s.ast = n - result = n if sfCustomPragma in s.flags: if n[bodyPos].kind != nkEmpty: localError(c.config, n[bodyPos].info, errImplOfXNotAllowed % s.name.s) diff --git a/tests/template/t17433.nim b/tests/template/t17433.nim index 121f3c471..053d33ff0 100644 --- a/tests/template/t17433.nim +++ b/tests/template/t17433.nim @@ -7,10 +7,10 @@ from std/macros import expandMacros proc bar(a: typedesc): a = default(a) -assert bar(float) == 0.0 -assert bar(string) == "" +doAssert bar(float) == 0.0 +doAssert bar(string) == "" template main = proc baz(a: typedesc): a = default(a) - assert baz(float) == 0.0 + doAssert baz(float) == 0.0 main() |