diff options
-rw-r--r-- | changelog.md | 8 | ||||
-rw-r--r-- | compiler/extccomp.nim | 2 | ||||
-rw-r--r-- | compiler/sem.nim | 7 | ||||
-rw-r--r-- | compiler/semexprs.nim | 2 | ||||
-rw-r--r-- | compiler/semstmts.nim | 19 | ||||
-rw-r--r-- | compiler/semtempl.nim | 5 | ||||
-rw-r--r-- | compiler/semtypes.nim | 15 | ||||
-rw-r--r-- | compiler/vm.nim | 2 | ||||
-rw-r--r-- | lib/core/macros.nim | 2 | ||||
-rw-r--r-- | lib/pure/pegs.nim | 2 | ||||
-rw-r--r-- | lib/system/assertions.nim | 2 | ||||
-rw-r--r-- | nimsuggest/tests/tsug_template.nim | 2 | ||||
-rw-r--r-- | tests/ccgbugs/tnocodegen_for_compiletime.nim | 2 | ||||
-rw-r--r-- | tests/fields/tfields.nim | 2 | ||||
-rw-r--r-- | tests/lookups/test.nim | 2 | ||||
-rw-r--r-- | tests/macros/tcomplexecho.nim | 2 | ||||
-rw-r--r-- | tests/macros/tgettypeinst.nim | 2 | ||||
-rw-r--r-- | tests/macros/tmacro5.nim | 4 | ||||
-rw-r--r-- | tests/macros/tmacro6.nim | 75 | ||||
-rw-r--r-- | tests/macros/tmacrostmt.nim | 22 | ||||
-rw-r--r-- | tests/metatype/tmetatype_issues.nim | 2 | ||||
-rw-r--r-- | tests/template/template_various.nim | 12 | ||||
-rw-r--r-- | tests/vm/texcl.nim | 2 | ||||
-rw-r--r-- | tests/vm/tstaticprintseq.nim | 4 | ||||
-rw-r--r-- | tests/vm/ttouintconv.nim | 4 |
25 files changed, 143 insertions, 60 deletions
diff --git a/changelog.md b/changelog.md index 886dc8006..afb21f9f1 100644 --- a/changelog.md +++ b/changelog.md @@ -36,8 +36,12 @@ - Compile time checks for integer and float conversions are now stricter. For example, `const x = uint32(-1)` now gives a compile time error instead of being equivalent to `const x = 0xFFFFFFFF'u32`. -- A bug allowed ``macro foo(): int = 123`` to compile even though a - macros has to return a ``NimNode``. This has been fixed. +- Using `typed` as the result type in templates/macros now means + "expression with a type". The old meaning of `typed` is preserved + as `void` or no result type at all. + +- A bug allowed `macro foo(): int = 123` to compile even though a + macros has to return a `NimNode`. This has been fixed. #### Breaking changes in the standard library diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index ae2971b65..473911b84 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -759,7 +759,7 @@ proc getLinkCmd(conf: ConfigRef; output: AbsoluteFile, template getLinkCmd(conf: ConfigRef; output: AbsoluteFile, objfiles: string): string = getLinkCmd(conf, output, objfiles, optGenDynLib in conf.globalOptions) -template tryExceptOSErrorMessage(conf: ConfigRef; errorPrefix: string = "", body: untyped): typed = +template tryExceptOSErrorMessage(conf: ConfigRef; errorPrefix: string = "", body: untyped) = try: body except OSError: diff --git a/compiler/sem.nim b/compiler/sem.nim index d4e944028..a4e6a427b 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -407,12 +407,11 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode, else: case s.typ.sons[0].kind of tyUntyped: - # BUGFIX: we cannot expect a type here, because module aliases would not - # work then (see the ``tmodulealias`` test) - # semExprWithType(c, result) + # Not expecting a type here allows templates like in ``tmodulealias.in``. result = semExpr(c, result, flags) of tyTyped: - result = semStmt(c, result, flags) + # More restrictive version. + result = semExprWithType(c, result, flags) of tyTypeDesc: if result.kind == nkStmtList: result.kind = nkStmtListType var typ = semTypeNode(c, result, nil) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 6261efaaa..767a13f3e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1985,7 +1985,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode = if ids.len > 0: dummyTemplate.sons[paramsPos] = newNodeI(nkFormalParams, n.info) - dummyTemplate[paramsPos].add getSysSym(c.graph, n.info, "typed").newSymNode # return type + dummyTemplate[paramsPos].add getSysSym(c.graph, n.info, "untyped").newSymNode # return type ids.add getSysSym(c.graph, n.info, "untyped").newSymNode # params type ids.add c.graph.emptyNode # no default value dummyTemplate[paramsPos].add newNode(nkIdentDefs, n.info, ids) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 7f0910429..be7d9a1bf 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1356,7 +1356,7 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) = localError(c.config, n.info, errNoSymbolToBorrowFromFound) proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) = - if t != nil: + if owner == skMacro or t != nil: var s = newSym(skResult, getIdent(c.cache, "result"), getCurrOwner(c), info) s.typ = t incl(s.flags, sfUsed) @@ -1550,17 +1550,17 @@ proc activate(c: PContext, n: PNode) = discard proc maybeAddResult(c: PContext, s: PSym, n: PNode) = - if s.typ.sons[0] != nil and not isInlineIterator(s): + if s.kind == skMacro: let resultType = - if s.kind == skMacro: - if s.typ.sons[0].kind == tyTypeDesc: - s.typ.sons[0] - else: - sysTypeFromName(c.graph, n.info, "NimNode") - else: + if s.typ.sons[0] != nil and s.typ.sons[0].kind == tyTypeDesc: s.typ.sons[0] + else: + sysTypeFromName(c.graph, n.info, "NimNode") addResult(c, resultType, n.info, s.kind) addResultNode(c, n) + elif s.typ.sons[0] != nil and not isInlineIterator(s): + addResult(c, s.typ.sons[0], n.info, s.kind) + addResultNode(c, n) proc canonType(c: PContext, t: PType): PType = if t.kind == tySequence: @@ -1888,7 +1888,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, # context as it may even be evaluated in 'system.compiles': trackProc(c, s, s.ast[bodyPos]) else: - if s.typ.sons[0] != nil and kind != skIterator: + if (s.typ.sons[0] != nil and kind != skIterator) or kind == skMacro: addDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nil, n.info)) openScope(c) @@ -2015,7 +2015,6 @@ proc semMacroDef(c: PContext, n: PNode): PNode = let param = t.n.sons[i].sym if param.typ.kind != tyUntyped: allUntyped = false if allUntyped: incl(s.flags, sfAllUntyped) - if t.sons[0] == nil: localError(c.config, n.info, "macro needs a return type") if n.sons[bodyPos].kind == nkEmpty: localError(c.config, n.info, errImplOfXexpected % s.name.s) diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 2cbbd7b54..7a56f8c45 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -606,11 +606,6 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = if n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: n.sons[genericParamsPos] = gp - # no explicit return type? -> use tyTyped - if n.sons[paramsPos].sons[0].kind == nkEmpty: - # use ``stmt`` as implicit result type - s.typ.sons[0] = newTypeS(tyTyped, c) - s.typ.n.sons[0] = newNodeIT(nkType, n.info, s.typ.sons[0]) else: s.typ = newTypeS(tyProc, c) # XXX why do we need tyTyped as a return type again? diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 86cb0f35b..dd9aea0f8 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -855,6 +855,7 @@ proc findEnforcedStaticType(t: PType): PType = # This handles types such as `static[T] and Foo`, # which are subset of `static[T]`, hence they could # be treated in the same way + if t == nil: return nil if t.kind == tyStatic: return t if t.kind == tyAnd: for s in t.sons: @@ -868,7 +869,7 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) = var a = copySym(param) a.typ = staticType.base addDecl(c, a) - elif param.typ.kind == tyTypeDesc: + elif param.typ != nil and param.typ.kind == tyTypeDesc: addDecl(c, param) else: # within a macro, every param has the type NimNode! @@ -1194,6 +1195,18 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if n.sons[0].kind != nkEmpty: r = semTypeNode(c, n.sons[0], nil) + if r != nil and kind in {skMacro, skTemplate} and r.kind == tyTyped: + # XXX: To implement the propesed change in the warning, just + # delete this entire if block. The rest is (at least at time of + # writing this comment) already implemented. + let info = n.sons[0].info + const msg = "`typed` will change its meaning in future versions of Nim. " & + "`void` or no return type declaration at all has the same " & + "meaning as the current meaning of `typed` as return type " & + "declaration." + message(c.config, info, warnDeprecated, msg) + r = nil + if r != nil: # turn explicit 'void' return type into 'nil' because the rest of the # compiler only checks for 'nil': diff --git a/compiler/vm.nim b/compiler/vm.nim index 6fc2626f7..aa8203a92 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1104,7 +1104,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = #echo "new pc ", newPc, " calling: ", prc.name.s var newFrame = PStackFrame(prc: prc, comesFrom: pc, next: tos) newSeq(newFrame.slots, prc.offset+ord(isClosure)) - if not isEmptyType(prc.typ.sons[0]) or prc.kind == skMacro: + if not isEmptyType(prc.typ.sons[0]): putIntoReg(newFrame.slots[0], getNullValue(prc.typ.sons[0], prc.info, c.config)) for i in 1 .. rc-1: newFrame.slots[i] = regs[rb+i] diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 847e17c56..dfda43625 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -567,7 +567,7 @@ proc quote*(bl: typed, op = "``"): NimNode {.magic: "QuoteAst", noSideEffect.} ## ## .. code-block:: nim ## - ## macro check(ex: untyped): typed = + ## macro check(ex: untyped) = ## # this is a simplified version of the check macro from the ## # unittest module. ## diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index 644de6007..26ebb916e 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -572,7 +572,7 @@ when not useUnicode: proc isTitle(a: char): bool {.inline.} = return false proc isWhiteSpace(a: char): bool {.inline.} = return a in {' ', '\9'..'\13'} -template matchOrParse(mopProc: untyped): typed = +template matchOrParse(mopProc: untyped) = # Used to make the main matcher proc *rawMatch* as well as event parser # procs. For the former, *enter* and *leave* event handler code generators # are provided which just return *discard*. diff --git a/lib/system/assertions.nim b/lib/system/assertions.nim index 090f4096c..ca22677b8 100644 --- a/lib/system/assertions.nim +++ b/lib/system/assertions.nim @@ -71,7 +71,7 @@ template onFailedAssert*(msg, code: untyped): untyped {.dirty.} = let msg = msgIMPL code -template doAssertRaises*(exception: typedesc, code: untyped): typed = +template doAssertRaises*(exception: typedesc, code: untyped) = ## Raises ``AssertionError`` if specified ``code`` does not raise the ## specified exception. Example: ## diff --git a/nimsuggest/tests/tsug_template.nim b/nimsuggest/tests/tsug_template.nim index 3fa69322f..0f258fcc6 100644 --- a/nimsuggest/tests/tsug_template.nim +++ b/nimsuggest/tests/tsug_template.nim @@ -8,5 +8,5 @@ $nimsuggest --tester $file >sug $1 sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe, locks: 0.};;$file;;2;;6;;"";;0;;Prefix sug;;skConverter;;tsug_template.tmpc;;converter ();;$file;;3;;10;;"";;0;;Prefix -sug;;skTemplate;;tsug_template.tmpa;;template (): typed;;$file;;1;;9;;"";;0;;Prefix +sug;;skTemplate;;tsug_template.tmpa;;template ();;$file;;1;;9;;"";;0;;Prefix """ diff --git a/tests/ccgbugs/tnocodegen_for_compiletime.nim b/tests/ccgbugs/tnocodegen_for_compiletime.nim index b44e9f8c9..3a952e303 100644 --- a/tests/ccgbugs/tnocodegen_for_compiletime.nim +++ b/tests/ccgbugs/tnocodegen_for_compiletime.nim @@ -1,7 +1,7 @@ # bug #1679 import macros, tables, hashes proc hash(v: NimNode): Hash = 4 # performance is for suckers -macro test(body: untyped): typed = +macro test(body: untyped) = var a = initCountTable[NimNode]() a.inc(body) diff --git a/tests/fields/tfields.nim b/tests/fields/tfields.nim index d52b5e8d2..0bf3a4e1a 100644 --- a/tests/fields/tfields.nim +++ b/tests/fields/tfields.nim @@ -46,7 +46,7 @@ block ttemplate: for name, value in (n: "v").fieldPairs: echo name - template wrapper: typed = + template wrapper(): void = for name, value in (n: "v").fieldPairs: echo name wrapper() diff --git a/tests/lookups/test.nim b/tests/lookups/test.nim index 56f39a4d7..97dfa131a 100644 --- a/tests/lookups/test.nim +++ b/tests/lookups/test.nim @@ -12,7 +12,7 @@ import unittest, macros # bug #4555 -macro memo(n: untyped): typed = +macro memo(n: untyped) = result = n proc fastFib(n: int): int {.memo.} = 40 diff --git a/tests/macros/tcomplexecho.nim b/tests/macros/tcomplexecho.nim index 0b70a3ef7..d58fa561c 100644 --- a/tests/macros/tcomplexecho.nim +++ b/tests/macros/tcomplexecho.nim @@ -32,7 +32,7 @@ proc foo(): seq[NimNode] {.compiletime.} = result.add test() result.add parseExpr("echo(5+56)") -macro bar(): typed = +macro bar() = result = newNimNode(nnkStmtList) let x = foo() for xx in x: diff --git a/tests/macros/tgettypeinst.nim b/tests/macros/tgettypeinst.nim index c2cde9a43..00e9865fa 100644 --- a/tests/macros/tgettypeinst.nim +++ b/tests/macros/tgettypeinst.nim @@ -22,7 +22,7 @@ proc symToIdent(x: NimNode): NimNode = result.add symToIdent(c) # check getTypeInst and getTypeImpl for given symbol x -macro testX(x,inst0: typed; recurse: static[bool]; implX: typed): typed = +macro testX(x,inst0: typed; recurse: static[bool]; implX: typed) = # check that getTypeInst(x) equals inst0 let inst = x.getTypeInst let instr = inst.symToIdent.treeRepr diff --git a/tests/macros/tmacro5.nim b/tests/macros/tmacro5.nim index 1c60e1ffd..802fb28d5 100644 --- a/tests/macros/tmacro5.nim +++ b/tests/macros/tmacro5.nim @@ -38,7 +38,7 @@ macro importImpl_forward(name, returns: untyped): untyped = decls.add res echo(repr(res)) -macro importImpl(name, returns, body: untyped): typed = +macro importImpl(name, returns, body: untyped) = #var res = getAST(importImpl_forward(name, returns)) discard getAST(importImpl_forward(name, returns)) var res = copyNimTree(decls[decls.high]) @@ -46,7 +46,7 @@ macro importImpl(name, returns, body: untyped): typed = echo repr(res) impls.add res -macro okayy: typed = +macro okayy() = result = newNimNode(nnkStmtList) for node in decls: result.add node for node in impls: result.add node diff --git a/tests/macros/tmacro6.nim b/tests/macros/tmacro6.nim new file mode 100644 index 000000000..0b6423100 --- /dev/null +++ b/tests/macros/tmacro6.nim @@ -0,0 +1,75 @@ +discard """ +errormsg: "expression '123' is of type 'int literal(123)' and has to be discarded" +line: 71 +""" + +import macros + +proc foo(a,b,c: int): int = + result += a + result += b + result += c + +macro bar(a,b,c: int): int = + result = newCall(ident"echo") + result.add a + result.add b + result.add c + +macro baz(a,b,c: int): int = + let stmt = nnkStmtListExpr.newTree() + stmt.add newCall(ident"echo", a) + stmt.add newCall(ident"echo", b) + stmt.add newCall(ident"echo", c) + stmt.add newLit(123) + return c + +# test no result type with explicit return + +macro baz2(a,b,c: int) = + let stmt = nnkStmtListExpr.newTree() + stmt.add newCall(ident"echo", a) + stmt.add newCall(ident"echo", b) + stmt.add newCall(ident"echo", c) + return stmt + +# test explicit void type with explicit return + +macro baz3(a,b,c: int): void = + let stmt = nnkStmtListExpr.newTree() + stmt.add newCall(ident"echo", a) + stmt.add newCall(ident"echo", b) + stmt.add newCall(ident"echo", c) + return stmt + +# test no result type with result variable + +macro baz4(a,b,c: int) = + result = nnkStmtListExpr.newTree() + result.add newCall(ident"echo", a) + result.add newCall(ident"echo", b) + result.add newCall(ident"echo", c) + +# test explicit void type with result variable + +macro baz5(a,b,c: int): void = + let result = nnkStmtListExpr.newTree() + result.add newCall(ident"echo", a) + result.add newCall(ident"echo", b) + result.add newCall(ident"echo", c) + +macro foobar1(): int = + result = quote do: + echo "Hello World" + 1337 + +echo foobar1() + +# this should create an error message, because 123 has to be discarded. + +macro foobar2() = + result = quote do: + echo "Hello World" + 123 + +echo foobar2() diff --git a/tests/macros/tmacrostmt.nim b/tests/macros/tmacrostmt.nim index dc936042f..bf67a9fc3 100644 --- a/tests/macros/tmacrostmt.nim +++ b/tests/macros/tmacrostmt.nim @@ -18,15 +18,16 @@ case_token: inc i #bug #488 -macro foo: typed = +macro foo() = var exp = newCall("whatwhat", newIntLitNode(1)) - if compiles(getAst(exp)): return exp + if compiles(getAst(exp)): + return exp else: echo "Does not compute! (test OK)" foo() #------------------------------------ -# bug #8287 +# bug #8287 type MyString = distinct string proc `$` (c: MyString): string {.borrow.} @@ -37,7 +38,7 @@ proc `!!` (c: cstring): int = proc f(name: MyString): int = !! $ name -macro repr_and_parse(fn: typed): typed = +macro repr_and_parse(fn: typed) = let fn_impl = fn.getImpl fn_impl.name = genSym(nskProc, $fn_impl.name) echo fn_impl.repr @@ -51,7 +52,7 @@ repr_and_parse(f) #------------------------------------ -# bugs #8343 and #8344 +# bugs #8343 and #8344 proc one_if_proc(x, y : int): int = if x < y: result = x else: result = y @@ -76,7 +77,7 @@ proc test_cond_stmtlist(x, y: int): int = #------------------------------------ # bug #8762 -proc t2(a, b: int): int = +proc t2(a, b: int): int = `+`(a, b) @@ -92,23 +93,23 @@ proc fn2(x, y: float): float = proc fn3(x, y: int): bool = (((x and 3) div 4) or (x mod (y xor -1))) == 0 or y notin [1,2] -proc fn4(x: int): int = +proc fn4(x: int): int = if x mod 2 == 0: return x + 2 else: return 0 #------------------------------------ # bug #10807 -proc fn_unsafeaddr(x: int): int = +proc fn_unsafeaddr(x: int): int = cast[int](unsafeAddr(x)) static: - echo fn_unsafeaddr.repr_to_string + echo fn_unsafeaddr.repr_to_string let fn1s = "proc fn1(x, y: int): int =\n result = 2 * (x + y)\n" let fn2s = "proc fn2(x, y: float): float =\n result = (y + 2 * x) / (x - y)\n" let fn3s = "proc fn3(x, y: int): bool =\n result = ((x and 3) div 4 or x mod (y xor -1)) == 0 or not contains([1, 2], y)\n" let fn4s = "proc fn4(x: int): int =\n if x mod 2 == 0:\n return x + 2\n else:\n return 0\n" let fnAddr = "proc fn_unsafeaddr(x: int): int =\n result = cast[int](unsafeAddr(x))\n" - + doAssert fn1.repr_to_string == fn1s doAssert fn2.repr_to_string == fn2s doAssert fn3.repr_to_string == fn3s @@ -134,4 +135,3 @@ repr_and_parse(test_block) repr_and_parse(test_cond_stmtlist) repr_and_parse(t2) repr_and_parse(test_pure_enums) - diff --git a/tests/metatype/tmetatype_issues.nim b/tests/metatype/tmetatype_issues.nim index c184689a1..21c5c02f1 100644 --- a/tests/metatype/tmetatype_issues.nim +++ b/tests/metatype/tmetatype_issues.nim @@ -34,7 +34,7 @@ block t898: block t7528: - macro bar(n: untyped): typed = + macro bar(n: untyped) = result = newNimNode(nnkStmtList, n) result.add(newCall("write", newIdentNode("stdout"), n)) diff --git a/tests/template/template_various.nim b/tests/template/template_various.nim index 029942621..50003254a 100644 --- a/tests/template/template_various.nim +++ b/tests/template/template_various.nim @@ -77,7 +77,7 @@ block generic_templates: block tgetast_typeliar: proc error(s: string) = quit s - macro assertOrReturn(condition: bool; message: string): typed = + macro assertOrReturn2(condition: bool; message: string) = var line = condition.lineInfo() result = quote do: block: @@ -86,8 +86,10 @@ block tgetast_typeliar: return macro assertOrReturn(condition: bool): typed = - var message = condition.toStrLit() - result = getAst assertOrReturn(condition, message) + var message : NimNode = newLit(condition.repr) + # echo message + result = getAst assertOrReturn2(condition, message) + echo result.repr proc point(size: int16): tuple[x, y: int16] = # returns random point in square area with given `size` @@ -245,7 +247,3 @@ block ttempl5: block templreturntype: template `=~` (a: int, b: int): bool = false var foo = 2 =~ 3 - - - - diff --git a/tests/vm/texcl.nim b/tests/vm/texcl.nim index e23a423fe..41975f27b 100644 --- a/tests/vm/texcl.nim +++ b/tests/vm/texcl.nim @@ -18,7 +18,7 @@ proc initOpts(): set[nlOptions] = const cOpts = initOpts() -macro nlo(): typed = +macro nlo() = nlOpts.incl(nloNone) nlOpts.excl(nloDebug) result = newEmptyNode() diff --git a/tests/vm/tstaticprintseq.nim b/tests/vm/tstaticprintseq.nim index 37bf62246..f4aab6b7e 100644 --- a/tests/vm/tstaticprintseq.nim +++ b/tests/vm/tstaticprintseq.nim @@ -24,7 +24,7 @@ bb const s = @[1,2,3] -macro foo: typed = +macro foo() = for e in s: echo e @@ -55,7 +55,7 @@ static: var m2: TData = data for x in m2.numbers: echo x -macro ff(d: static[TData]): typed = +macro ff(d: static[TData]) = for x in d.letters: echo x diff --git a/tests/vm/ttouintconv.nim b/tests/vm/ttouintconv.nim index dd4c597ba..403de8f41 100644 --- a/tests/vm/ttouintconv.nim +++ b/tests/vm/ttouintconv.nim @@ -20,7 +20,7 @@ nimout: ''' #bug #2514 -macro foo(): typed = +macro foo() = var x = 8'u8 var y = 9'u16 var z = 17'u32 @@ -58,7 +58,7 @@ macro foo(): typed = var zz = 0x7FFFFFFF'u32 echo zz -macro foo2(): typed = +macro foo2() = var xx = 0x7FFFFFFFFFFFFFFF echo xx |