summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2023-09-30 12:32:27 +0800
committerGitHub <noreply@github.com>2023-09-30 06:32:27 +0200
commit714630782371565e3982a3e70e288c7d1e2dd88b (patch)
tree38e7da8e3207cced998e8a375dd3b3d89ab9bfd4
parenta38e3dcb1f0c47b89f07b343a259c4b10a333ac9 (diff)
downloadNim-714630782371565e3982a3e70e288c7d1e2dd88b.tar.gz
fixes #22554; makes `newSeqWith` use `newSeqUninit` (#22771)
fixes #22554
-rw-r--r--lib/pure/collections/sequtils.nim7
-rw-r--r--lib/system.nim13
2 files changed, 13 insertions, 7 deletions
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index eb9ff32c6..9c33b2eb6 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -83,6 +83,7 @@ runnableExamples:
 import std/private/since
 
 import macros
+from typetraits import supportsCopyMem
 
 when defined(nimPreviewSlimSystem):
   import std/assertions
@@ -1114,8 +1115,12 @@ template newSeqWith*(len: int, init: untyped): untyped =
     import std/random
     var seqRand = newSeqWith(20, rand(1.0))
     assert seqRand[0] != seqRand[1]
+  type T = typeof(init)
   let newLen = len
-  var result = newSeq[typeof(init)](newLen)
+  when supportsCopyMem(T) and declared(newSeqUninit):
+    var result = newSeqUninit[T](newLen)
+  else: # TODO: use `newSeqUnsafe` when that's available
+    var result = newSeq[T](newLen)
   for i in 0 ..< newLen:
     result[i] = init
   move(result) # refs bug #7295
diff --git a/lib/system.nim b/lib/system.nim
index b9dd7f143..3e7d84b1d 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1615,11 +1615,12 @@ when notJSnotNims and defined(nimSeqsV2):
 when not defined(js):
   template newSeqImpl(T, len) =
     result = newSeqOfCap[T](len)
-    when defined(nimSeqsV2):
-      cast[ptr int](addr result)[] = len
-    else:
-      var s = cast[PGenericSeq](result)
-      s.len = len
+    {.cast(noSideEffect).}:
+      when defined(nimSeqsV2):
+        cast[ptr int](addr result)[] = len
+      else:
+        var s = cast[PGenericSeq](result)
+        s.len = len
 
   proc newSeqUninitialized*[T: SomeNumber](len: Natural): seq[T] {.deprecated: "Use `newSeqUninit` instead".} =
     ## Creates a new sequence of type `seq[T]` with length `len`.
@@ -1640,7 +1641,7 @@ when not defined(js):
       var s = cast[PGenericSeq](result)
       s.len = len
 
-  proc newSeqUninit*[T](len: Natural): seq[T] =
+  func newSeqUninit*[T](len: Natural): seq[T] =
     ## Creates a new sequence of type `seq[T]` with length `len`.
     ##
     ## Only available for types, which don't contain