semTemplateDef and t17433 clean-ups (#17448)

- use `doAssert` in t17433
- use setGenericParamsMisc in semTemplateDef akin to semProcAux
- pragma handling in semTemplateDef inline with semProcAux
This commit is contained in:
Saem Ghani
2021-03-22 04:46:34 -07:00
committed by GitHub
parent c8dda867f2
commit e5873b3a93
4 changed files with 43 additions and 41 deletions

View File

@@ -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:

View File

@@ -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)

View File

@@ -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)
n[namePos] = newSymNode(s)
pragmaCallable(c, s, n, templatePragmas)
implicitPragmas(c, s, n.info, templatePragmas)
var gp: PNode
if n[genericParamsPos].kind != nkEmpty:
n[genericParamsPos] = semGenericParamList(c, n[genericParamsPos])
gp = n[genericParamsPos]
else:
gp = newNodeI(nkGenericParams, n.info)
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)

View File

@@ -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()