diff options
author | Araq <rumpf_a@web.de> | 2017-05-17 22:13:57 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2017-05-17 22:13:57 +0200 |
commit | 8f67b90997d1c0416c4991ecec666a63339103c2 (patch) | |
tree | 45053004503995b050d04620705df209df8f2af7 /compiler/sem.nim | |
parent | 68573630340f60f452d5f206da37017e47bd8f6e (diff) | |
parent | c8cec27c0a503d6703536d54b9cc48684dc69086 (diff) | |
download | Nim-8f67b90997d1c0416c4991ecec666a63339103c2.tar.gz |
Merge branch 'araq2' into devel
Diffstat (limited to 'compiler/sem.nim')
-rw-r--r-- | compiler/sem.nim | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim index ab3c5cec8..9f80e1399 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -351,8 +351,8 @@ when false: for i in 0 ..< n.safeLen: resetSemFlag(n[i]) -proc semAfterMacroCall(c: PContext, n: PNode, s: PSym, - flags: TExprFlags): PNode = +proc semAfterMacroCall(c: PContext, call, macroResult: PNode, + s: PSym, flags: TExprFlags): PNode = ## Semantically check the output of a macro. ## This involves processes such as re-checking the macro output for type ## coherence, making sure that variables declared with 'let' aren't @@ -363,8 +363,8 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym, globalError(s.info, errTemplateInstantiationTooNested) c.friendModules.add(s.owner.getModule) - result = n - excl(n.flags, nfSem) + result = macroResult + excl(result.flags, nfSem) #resetSemFlag n if s.typ.sons[0] == nil: result = semStmt(c, result) @@ -378,13 +378,26 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym, of tyStmt: result = semStmt(c, result) of tyTypeDesc: - if n.kind == nkStmtList: result.kind = nkStmtListType + if result.kind == nkStmtList: result.kind = nkStmtListType var typ = semTypeNode(c, result, nil) result.typ = makeTypeDesc(c, typ) #result = symNodeFromType(c, typ, n.info) else: + var retType = s.typ.sons[0] + if s.ast[genericParamsPos] != nil and retType.isMetaType: + # The return type may depend on the Macro arguments + # e.g. template foo(T: typedesc): seq[T] + # We will instantiate the return type here, because + # we now know the supplied arguments + var paramTypes = newIdTable() + for param, value in genericParamsInMacroCall(s, call): + idTablePut(paramTypes, param.typ, value.typ) + + retType = generateTypeInstance(c, paramTypes, + macroResult.info, retType) + result = semExpr(c, result, flags) - result = fitNode(c, s.typ.sons[0], result, result.info) + result = fitNode(c, retType, result, result.info) #GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0])) dec(evalTemplateCounter) discard c.friendModules.pop() @@ -409,7 +422,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, # c.evalContext = c.createEvalContext(emStatic) result = evalMacroCall(c.module, c.cache, n, nOrig, sym) if efNoSemCheck notin flags: - result = semAfterMacroCall(c, result, sym, flags) + result = semAfterMacroCall(c, n, result, sym, flags) result = wrapInComesFrom(nOrig.info, result) popInfoContext() |