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
commit e5873b3a93
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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: if result.kind != nkIntLit:
localError(c.config, n.info, errConstExprExpected) localError(c.config, n.info, errConstExprExpected)
proc semGenericStmt(c: PContext, n: PNode): PNode proc semGenericStmt(c: PContext, n: PNode): PNode
proc semConceptBody(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) = proc addCodeForGenerics(c: PContext, n: PNode) =
for i in c.lastGenericIdx..<c.generics.len: for i in c.lastGenericIdx..<c.generics.len:

View file

@ -1769,23 +1769,6 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
else: else:
localError(c.config, n.info, "'method' needs a parameter that has an object type") 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, proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
validPragmas: TSpecialWords, flags: TExprFlags = {}): PNode = validPragmas: TSpecialWords, flags: TExprFlags = {}): PNode =
result = semProcAnnotation(c, n, validPragmas) result = semProcAnnotation(c, n, validPragmas)
@ -1839,7 +1822,6 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
if n[paramsPos].kind != nkEmpty: if n[paramsPos].kind != nkEmpty:
semParamList(c, n[paramsPos], n[genericParamsPos], s) semParamList(c, n[paramsPos], n[genericParamsPos], s)
# we maybe have implicit type parameters:
else: else:
s.typ = newProcType(c, n.info) 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]) result[i] = semTemplBodyDirty(c, n[i])
proc semTemplateDef(c: PContext, n: PNode): PNode = proc semTemplateDef(c: PContext, n: PNode): PNode =
result = n
var s: PSym var s: PSym
if isTopLevel(c): if isTopLevel(c):
s = semIdentVis(c, skTemplate, n[0], {sfExported}) s = semIdentVis(c, skTemplate, n[namePos], {sfExported})
incl(s.flags, sfGlobal) incl(s.flags, sfGlobal)
else: else:
s = semIdentVis(c, skTemplate, n[0], {}) s = semIdentVis(c, skTemplate, n[namePos], {})
assert s.kind == skTemplate
if s.owner != nil: if s.owner != nil:
const names = ["!=", ">=", ">", "incl", "excl", "in", "notin", "isnot"] 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": s.owner.name.s == "vm" and s.name.s == "stackTrace":
incl(s.flags, sfCallsite) incl(s.flags, sfCallsite)
s.ast = n
styleCheckDef(c.config, s) styleCheckDef(c.config, s)
onDef(n[0].info, s) onDef(n[namePos].info, s)
# check parameter list: # check parameter list:
#s.scope = c.currentScope #s.scope = c.currentScope
pushOwner(c, s) pushOwner(c, s)
openScope(c) openScope(c)
n[namePos] = newSymNode(s, n[namePos].info) n[namePos] = newSymNode(s)
if n[pragmasPos].kind != nkEmpty: pragmaCallable(c, s, n, templatePragmas)
pragma(c, s, n[pragmasPos], templatePragmas) implicitPragmas(c, s, n.info, templatePragmas)
var gp: PNode setGenericParamsMisc(c, n)
if n[genericParamsPos].kind != nkEmpty:
n[genericParamsPos] = semGenericParamList(c, n[genericParamsPos])
gp = n[genericParamsPos]
else:
gp = newNodeI(nkGenericParams, n.info)
# process parameters: # process parameters:
var allUntyped = true var allUntyped = true
if n[paramsPos].kind != nkEmpty: 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 # 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 # case as we determine whether it's a template parameter in the template
# body by the absence of the sfGenSym flag: # 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.incl sfTemplateParam
param.flags.excl sfGenSym param.flags.excl sfGenSym
if param.typ.kind != tyUntyped: allUntyped = false 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: else:
s.typ = newTypeS(tyProc, c) s.typ = newTypeS(tyProc, c)
# XXX why do we need tyTyped as a return type again? # XXX why do we need tyTyped as a return type again?
s.typ.n = newNodeI(nkFormalParams, n.info) s.typ.n = newNodeI(nkFormalParams, n.info)
rawAddSon(s.typ, newTypeS(tyTyped, c)) rawAddSon(s.typ, newTypeS(tyTyped, c))
s.typ.n.add newNodeIT(nkType, n.info, s.typ[0]) 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 allUntyped: incl(s.flags, sfAllUntyped)
if n[patternPos].kind != nkEmpty: if n[patternPos].kind != nkEmpty:
n[patternPos] = semPattern(c, n[patternPos]) n[patternPos] = semPattern(c, n[patternPos])
var ctx: TemplCtx var ctx: TemplCtx
ctx.toBind = initIntSet() ctx.toBind = initIntSet()
ctx.toMixin = initIntSet() ctx.toMixin = initIntSet()
@ -662,8 +664,6 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
semIdeForTemplateOrGeneric(c, n[bodyPos], ctx.cursorInBody) semIdeForTemplateOrGeneric(c, n[bodyPos], ctx.cursorInBody)
closeScope(c) closeScope(c)
popOwner(c) popOwner(c)
s.ast = n
result = n
if sfCustomPragma in s.flags: if sfCustomPragma in s.flags:
if n[bodyPos].kind != nkEmpty: if n[bodyPos].kind != nkEmpty:
localError(c.config, n[bodyPos].info, errImplOfXNotAllowed % s.name.s) localError(c.config, n[bodyPos].info, errImplOfXNotAllowed % s.name.s)

View file

@ -7,10 +7,10 @@
from std/macros import expandMacros from std/macros import expandMacros
proc bar(a: typedesc): a = default(a) proc bar(a: typedesc): a = default(a)
assert bar(float) == 0.0 doAssert bar(float) == 0.0
assert bar(string) == "" doAssert bar(string) == ""
template main = template main =
proc baz(a: typedesc): a = default(a) proc baz(a: typedesc): a = default(a)
assert baz(float) == 0.0 doAssert baz(float) == 0.0
main() main()