summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJason Beetham <beefers331@gmail.com>2022-10-21 22:37:23 -0600
committerGitHub <noreply@github.com>2022-10-22 06:37:23 +0200
commitda0a2fdca20eb48f73fe72d777ec142674debed2 (patch)
tree41e91e75565320709c797e2968ccccef73e91bcb
parent0faae4d5e29ea4eb55f3b53b1f01b91637f2c6c7 (diff)
downloadNim-da0a2fdca20eb48f73fe72d777ec142674debed2.tar.gz
Unpack mSlice tupleconstr for static openarrays (#20615)
-rw-r--r--compiler/semmacrosanity.nim21
-rw-r--r--tests/views/tconst_views.nim11
-rw-r--r--tests/vm/topenarrays.nim4
3 files changed, 36 insertions, 0 deletions
diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim
index aebee8998..12d7d32e0 100644
--- a/compiler/semmacrosanity.nim
+++ b/compiler/semmacrosanity.nim
@@ -67,6 +67,27 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
         else: annotateType(n[i], x[i], conf)
     elif x.kind == tyProc and x.callConv == ccClosure:
       n.typ = t
+    elif x.kind == tyOpenArray: # `opcSlice` transforms slices into tuples
+      if n.kind == nkTupleConstr:
+        let
+          bracketExpr = newNodeI(nkBracket, n.info)
+          left = int n[1].intVal
+          right = int n[2].intVal
+        bracketExpr.flags = n.flags
+        case n[0].kind # is this a string slice or a array slice
+        of nkStrKinds:
+          for i in left..right:
+            bracketExpr.add newIntNode(nkCharLit, BiggestInt n[0].strVal[i])
+            annotateType(bracketExpr[^1], t[0], conf)
+        of nkBracket:
+          for i in left..right:
+            bracketExpr.add n[0][i]
+            annotateType(bracketExpr[^1], t[0], conf)
+        else:
+          globalError(conf, n.info, "Incorrectly generated tuple constr")
+        n[] = bracketExpr[]
+
+      n.typ = t
     else:
       globalError(conf, n.info, "() must have a tuple type")
   of nkBracket:
diff --git a/tests/views/tconst_views.nim b/tests/views/tconst_views.nim
index d7f1fc481..a85b03864 100644
--- a/tests/views/tconst_views.nim
+++ b/tests/views/tconst_views.nim
@@ -24,3 +24,14 @@ proc `$`(x: openArray[int]): string =
 echo c
 echo c2.data
 
+
+type MyObj = object
+  data: openarray[char]
+
+const
+  val1 = Foo(data: toOpenArray([1, 2, 3], 1, 1))
+  val2 = Foo(data: toOpenArray([1, 2, 3], 0, 2))
+  val3 = MyObj(data: "Hello".toOpenArray(0, 2))
+assert val1.data == [2]
+assert val2.data == [1, 2, 3]
+assert val3.data == "Hel"
diff --git a/tests/vm/topenarrays.nim b/tests/vm/topenarrays.nim
index 639e0c35b..0a822f583 100644
--- a/tests/vm/topenarrays.nim
+++ b/tests/vm/topenarrays.nim
@@ -35,6 +35,10 @@ static:
   assert arr.toOpenArray(3, 4).toOpenArray(0, 0) == [1]
 
 
+proc doThing(s: static openArray[int]) = discard
+
+doThing([10, 20, 30].toOpenArray(0, 0))
+
 # bug #19969
 proc f(): array[1, byte] =
   var a: array[1, byte]