From aeb6ec27dec21509eebf5aa1a78b82b184117450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Mon, 20 May 2019 12:18:54 +0200 Subject: [PATCH] fix for return in macro (#9666); fixes #5874 --- changelog.md | 5 ++++- compiler/semstmts.nim | 10 +++++++++- tests/macros/tmacrogenerics.nim | 8 ++++---- tests/macros/tmacros1.nim | 24 +++++++++++++++++++++++- tests/macros/tmacros_various.nim | 2 +- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/changelog.md b/changelog.md index 385c8fecfa..886dc80062 100644 --- a/changelog.md +++ b/changelog.md @@ -36,6 +36,9 @@ - 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. + #### Breaking changes in the standard library - `osproc.execProcess` now also takes a `workingDir` parameter. @@ -161,7 +164,7 @@ proc enumToString*(enums: openArray[enum]): string = - Added `system.default`. -- Added `sequtils.items` for closure iterators, allows closure iterators +- Added `sequtils.items` for closure iterators, allows closure iterators to be used by the the mapIt, filterIt, allIt, anyIt, etc. diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 5d1990e330..935934962f 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1550,7 +1550,15 @@ proc activate(c: PContext, n: PNode) = proc maybeAddResult(c: PContext, s: PSym, n: PNode) = if s.typ.sons[0] != nil and not isInlineIterator(s): - addResult(c, s.typ.sons[0], n.info, s.kind) + 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: + s.typ.sons[0] + addResult(c, resultType, n.info, s.kind) addResultNode(c, n) proc canonType(c: PContext, t: PType): PType = diff --git a/tests/macros/tmacrogenerics.nim b/tests/macros/tmacrogenerics.nim index bb562cacb5..c31b5564c2 100644 --- a/tests/macros/tmacrogenerics.nim +++ b/tests/macros/tmacrogenerics.nim @@ -1,8 +1,8 @@ discard """ nimout: ''' -instantiation 1 with None and None -instantiation 2 with None and None -instantiation 3 with None and None +instantiation 1 with typeDesc[int] and typeDesc[float] +instantiation 2 with typeDesc[float] and typeDesc[string] +instantiation 3 with typeDesc[string] and typeDesc[string] counter: 3 ''' output: "int\nfloat\nint\nstring" @@ -14,7 +14,7 @@ var counter {.compileTime.} = 0 macro makeBar(A, B: typedesc): typedesc = inc counter - echo "instantiation ", counter, " with ", A.name, " and ", B.name + echo "instantiation ", counter, " with ", A.getTypeInst.repr, " and ", B.getTypeInst.repr result = A type diff --git a/tests/macros/tmacros1.nim b/tests/macros/tmacros1.nim index 80afb66410..a50465e1cf 100644 --- a/tests/macros/tmacros1.nim +++ b/tests/macros/tmacros1.nim @@ -1,5 +1,8 @@ discard """ - output: "Got: 'nnkCall' hi" + output: '''Got: 'nnkCall' hi +{a} +{b} +{a, b}''' """ import @@ -27,3 +30,22 @@ var str: string outterMacro(str): "hellow" echo str + +type E = enum a b +macro enumerators1(): set[E] = newLit({a}) + +macro enumerators2(): set[E] = + return newLit({b}) + +macro enumerators3(): set[E] = + result = newLit({E.low .. E.high}) + +var myEnums: set[E] + + +myEnums = enumerators1() +echo myEnums +myEnums = enumerators2() +echo myEnums +myEnums = enumerators3() +echo myEnums diff --git a/tests/macros/tmacros_various.nim b/tests/macros/tmacros_various.nim index 9eece00bda..b722298dc4 100644 --- a/tests/macros/tmacros_various.nim +++ b/tests/macros/tmacros_various.nim @@ -47,7 +47,7 @@ block tgenericparams: let expr0 = "proc foo[T, N: static[int]]()" let expr1 = "proc foo[T; N: static[int]]()" - $toStrLit(parseExpr(expr0)) & "\n" & $toStrLit(parseExpr(expr1)) + newLit($toStrLit(parseExpr(expr0)) & "\n" & $toStrLit(parseExpr(expr1))) echo test()