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:
parent
c8dda867f2
commit
e5873b3a93
4 changed files with 43 additions and 41 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue