summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJason Beetham <beefers331@gmail.com>2021-07-23 00:46:13 -0600
committerGitHub <noreply@github.com>2021-07-23 08:46:13 +0200
commit5386ae75ba91ee2fe280f1fe807676a7c9af4b13 (patch)
tree1fd7bc78d3e8b37281a428986d8429a4da7cd6e5
parent0c4582c66524d58a3c72827d9546a5c5f1c40286 (diff)
downloadNim-5386ae75ba91ee2fe280f1fe807676a7c9af4b13.tar.gz
Fixed template const tuple unpacking (#18562)
-rw-r--r--compiler/semtempl.nim40
-rw-r--r--tests/vm/tconst.nim10
2 files changed, 28 insertions, 22 deletions
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 92cc0be8c..a2b0f99ba 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -209,7 +209,7 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
       let pragmaNode = n[1]
       for i in 0..<pragmaNode.len:
         openScope(c)
-        pragmaNode[i] = semTemplBody(c,pragmaNode[i])
+        pragmaNode[i] = semTemplBody(c, pragmaNode[i])
         closeScope(c)
     let ident = getIdentNode(c, n)
     if not isTemplParam(c, ident):
@@ -306,20 +306,24 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
   # close scope for parameters
   closeScope(c)
 
-proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind; start=0) =
+proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind; start = 0) =
   for i in start..<n.len:
     var a = n[i]
-    if a.kind == nkCommentStmt: continue
-    if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a, c.c.config)
-    checkMinSonsLen(a, 3, c.c.config)
-    when defined(nimsuggest):
-      inc c.c.inTypeContext
-    a[^2] = semTemplBody(c, a[^2])
-    when defined(nimsuggest):
-      dec c.c.inTypeContext
-    a[^1] = semTemplBody(c, a[^1])
-    for j in 0..<a.len-2:
-      addLocalDecl(c, a[j], symKind)
+    case a.kind:
+    of nkCommentStmt: continue
+    of nkIdentDefs, nkVarTuple, nkConstDef:
+      checkMinSonsLen(a, 3, c.c.config)
+      when defined(nimsuggest):
+        inc c.c.inTypeContext
+      a[^2] = semTemplBody(c, a[^2])
+      when defined(nimsuggest):
+        dec c.c.inTypeContext
+      a[^1] = semTemplBody(c, a[^1])
+      for j in 0..<a.len-2:
+        addLocalDecl(c, a[j], symKind)
+    else:
+      illFormedAst(a, c.c.config)
+
 
 proc semPattern(c: PContext, n: PNode): PNode
 
@@ -434,15 +438,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
     checkMinSonsLen(n, 1, c.c.config)
     semTemplSomeDecl(c, n, skParam, 1)
     n[0] = semTemplBody(c, n[0])
-  of nkConstSection:
-    for i in 0..<n.len:
-      var a = n[i]
-      if a.kind == nkCommentStmt: continue
-      if (a.kind != nkConstDef): illFormedAst(a, c.c.config)
-      checkSonsLen(a, 3, c.c.config)
-      addLocalDecl(c, a[0], skConst)
-      a[1] = semTemplBody(c, a[1])
-      a[2] = semTemplBody(c, a[2])
+  of nkConstSection: semTemplSomeDecl(c, n, skConst)
   of nkTypeSection:
     for i in 0..<n.len:
       var a = n[i]
diff --git a/tests/vm/tconst.nim b/tests/vm/tconst.nim
index bb9ad2117..c2bcf78b5 100644
--- a/tests/vm/tconst.nim
+++ b/tests/vm/tconst.nim
@@ -34,5 +34,15 @@ template main() =
     doAssert ct in b, $(b, ct)
     doAssert NimVersion in b
 
+  block: # Test for fix on broken const unpacking
+    template mytemp() =
+      const
+        (x, increment) = (4, true)
+        a = 100
+      discard (x, increment, a)
+    mytemp()
+
+
+
 static: main()
 main()