summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorArne Döring <arne.doering@gmx.net>2019-06-07 14:34:59 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-06-07 14:34:59 +0200
commit99a4fed96b4e703ff490edfaa65e0832ad41ce34 (patch)
tree76ca77d8426ae4e712d648da8d4b9e4f77b6a4a9
parent12fc1dfb2ccb8409fbfe17898e173e8629dbf095 (diff)
downloadNim-99a4fed96b4e703ff490edfaa65e0832ad41ce34.tar.gz
fix for passing tuples as static params to macros (#11423); fixes #10751 [bugfix]
* add vm value preparation proc

* small optimization
-rw-r--r--compiler/vm.nim23
-rw-r--r--tests/macros/tmacros1.nim12
2 files changed, 32 insertions, 3 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index e1e75135a..a2af0e7b8 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -2031,12 +2031,29 @@ proc evalStaticStmt*(module: PSym; g: ModuleGraph; e: PNode, prc: PSym) =
 proc setupCompileTimeVar*(module: PSym; g: ModuleGraph; n: PNode) =
   discard evalConstExprAux(module, g, nil, n, emStaticStmt)
 
+proc prepareVMValue(arg: PNode): PNode =
+  ## strip nkExprColonExpr from tuple values recurively. That is how
+  ## they are expected to be stored in the VM.
+
+  # Early abort without copy. No transformation takes place.
+  if arg.kind in nkLiterals:
+    return arg
+
+  result = copyNode(arg)
+  if arg.kind == nkTupleConstr:
+    for child in arg:
+      if child.kind == nkExprColonExpr:
+        result.add prepareVMValue(child[1])
+      else:
+        result.add prepareVMValue(child)
+  else:
+    for child in arg:
+      result.add prepareVMValue(child)
+
 proc setupMacroParam(x: PNode, typ: PType): TFullReg =
   case typ.kind
   of tyStatic:
-    putIntoReg(result, x)
-  #of tyTypeDesc:
-  #  putIntoReg(result, x)
+    putIntoReg(result, prepareVMValue(x))
   else:
     result.kind = rkNode
     var n = x
diff --git a/tests/macros/tmacros1.nim b/tests/macros/tmacros1.nim
index a50465e1c..706281d13 100644
--- a/tests/macros/tmacros1.nim
+++ b/tests/macros/tmacros1.nim
@@ -49,3 +49,15 @@ myEnums = enumerators2()
 echo myEnums
 myEnums = enumerators3()
 echo myEnums
+
+#10751
+
+type Tuple = tuple
+  a: string
+  b: int
+
+macro foo(t: static Tuple): untyped =
+  doAssert t.a == "foo"
+  doAssert t.b == 12345
+
+foo((a: "foo", b: 12345))