diff --git a/compiler/ast.nim b/compiler/ast.nim index a071060d40..883b68d71d 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1341,10 +1341,6 @@ proc skipTypes*(t: PType, kinds: TTypeKinds): PType = result = t while result.kind in kinds: result = lastSon(result) -proc safeSkipTypes*(t: PType, kinds: TTypeKinds): PType = - result = if t != nil: t.skipTypes(kinds) - else: nil - proc isGCedMem*(t: PType): bool {.inline.} = result = t.kind in {tyString, tyRef, tySequence} or t.kind == tyProc and t.callConv == ccClosure diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index ecb898d8ac..78cc691c06 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -25,22 +25,16 @@ proc copyNode(ctx: TemplCtx, a, b: PNode): PNode = if ctx.instLines: result.info = b.info proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = - template handleParam(param) = - let x = param - if x.kind == nkArgList: - for y in items(x): result.add(y) - else: - result.add copyTree(x) - case templ.kind of nkSym: var s = templ.sym if s.owner.id == c.owner.id: - case s.kind - of skParam: - handleParam actual.sons[s.position] - of skGenericParam: - handleParam actual.sons[s.owner.typ.len + s.position - 1] + if s.kind == skParam: + let x = actual.sons[s.position] + if x.kind == nkArgList: + for y in items(x): result.add(y) + else: + result.add copyTree(x) else: internalAssert sfGenSym in s.flags var x = PSym(idTableGet(c.mapping, s)) @@ -62,31 +56,21 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = proc evalTemplateArgs(n: PNode, s: PSym): PNode = # if the template has zero arguments, it can be called without ``()`` # `n` is then a nkSym or something similar - var totalParams = case n.kind - of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: expectedRegularParams + genericParams: - globalError(n.info, errWrongNumberOfArguments) + var a: int + case n.kind + of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: + a = sonsLen(n) + else: a = 0 + var f = s.typ.sonsLen + if a > f: globalError(n.info, errWrongNumberOfArguments) result = newNodeI(nkArgList, n.info) - for i in 1 .. givenRegularParams: - result.addSon n.sons[i] - - for i in givenRegularParams+1 .. expectedRegularParams: - let default = s.typ.n.sons[i].sym.ast - if default.kind == nkEmpty: + for i in countup(1, f - 1): + var arg = if i < a: n.sons[i] else: copyTree(s.typ.n.sons[i].sym.ast) + if arg == nil or arg.kind == nkEmpty: localError(n.info, errWrongNumberOfArguments) - result.addSon default.copyTree + addSon(result, arg) - for i in 1 .. genericParams: - result.addSon n.sons[givenRegularParams + i] - var evalTemplateCounter* = 0 # to prevent endless recursion in templates instantiation diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 961c61c57a..a712cc195e 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -283,21 +283,8 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = if containsGenericType(result.typ) or x.fauxMatch == tyUnknown: result.typ = newTypeS(x.fauxMatch, c) return - let gp = finalCallee.ast.sons[genericParamsPos] - if gp.kind != nkEmpty: - if x.calleeSym.kind notin {skMacro, skTemplate}: - finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info) - else: - # For macros and templates, the resolved generic params - # are added as normal params. - for s in instantiateGenericParamList(c, gp, x.bindings): - case s.kind - of skConst: - x.call.add s.ast - of skType: - x.call.add newSymNode(s, n.info) - else: - internalAssert false + if finalCallee.ast.sons[genericParamsPos].kind != nkEmpty: + finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info) result = x.call instGenericConvertersSons(c, result, x) result.sons[0] = newSymNode(finalCallee, result.sons[0].info) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index dd60e08810..81a4465c59 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -10,10 +10,14 @@ # This module implements the instantiation of generic procs. # included from sem.nim -iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym = - internalAssert n.kind == nkGenericParams +proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, + entry: var TInstantiation) = + if n.kind != nkGenericParams: + internalError(n.info, "instantiateGenericParamList; no generic params") + newSeq(entry.concreteTypes, n.len) for i, a in n.pairs: - internalAssert a.kind == nkSym + if a.kind != nkSym: + internalError(a.info, "instantiateGenericParamList; no symbol") var q = a.sym if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic, tyIter}+tyTypeClasses: continue @@ -38,7 +42,8 @@ iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym #t = ReplaceTypeVarsT(cl, t) s.typ = t if t.kind == tyStatic: s.ast = t.n - yield s + addDecl(c, s) + entry.concreteTypes[i] = t proc sameInstantiation(a, b: TInstantiation): bool = if a.concreteTypes.len == b.concreteTypes.len: @@ -191,7 +196,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, ## The `pt` parameter is a type-unsafe mapping table used to link generic ## parameters to their concrete types within the generic instance. # no need to instantiate generic templates/macros: - internalAssert fn.kind notin {skMacro, skTemplate} + if fn.kind in {skTemplate, skMacro}: return fn # generates an instantiated proc if c.instCounter > 1000: internalError(fn.ast.info, "nesting too deep") inc(c.instCounter) @@ -208,18 +213,12 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, result.ast = n pushOwner(result) openScope(c) - let gp = n.sons[genericParamsPos] - internalAssert gp.kind != nkEmpty + internalAssert n.sons[genericParamsPos].kind != nkEmpty n.sons[namePos] = newSymNode(result) pushInfoContext(info) var entry = TInstantiation.new entry.sym = result - newSeq(entry.concreteTypes, gp.len) - var i = 0 - for s in instantiateGenericParamList(c, gp, pt): - addDecl(c, s) - entry.concreteTypes[i] = s.typ - inc i + instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[]) pushProcCon(c, result) instantiateProcType(c, pt, result, info) n.sons[genericParamsPos] = ast.emptyNode diff --git a/compiler/vm.nim b/compiler/vm.nim index 912cf33311..f69b9281de 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1417,20 +1417,12 @@ proc evalStaticStmt*(module: PSym, e: PNode, prc: PSym) = proc setupCompileTimeVar*(module: PSym, n: PNode) = discard evalConstExprAux(module, nil, n, emStaticStmt) -proc setupMacroParam(x: PNode, typ: PType): TFullReg = - case typ.kind - of tyStatic: - putIntoReg(result, x) - of tyTypeDesc: - putIntoReg(result, x) - else: - result.kind = rkNode - var n = x - if n.kind in {nkHiddenSubConv, nkHiddenStdConv}: n = n.sons[1] - n = n.canonValue - n.flags.incl nfIsRef - n.typ = x.typ - result.node = n +proc setupMacroParam(x: PNode): PNode = + result = x + if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1] + result = canonValue(result) + result.flags.incl nfIsRef + result.typ = x.typ var evalMacroCounter: int @@ -1450,7 +1442,6 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = c.callsite = nOrig let start = genProc(c, sym) - # c.echoCode start var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil) let maxSlots = sym.offset @@ -1466,14 +1457,9 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = tos.slots[0].kind = rkNode tos.slots[0].node = newNodeIT(nkEmpty, n.info, sym.typ.sons[0]) # setup parameters: - for i in 1..