Skip to content

Commit 3b1a601

Browse files
authored
sequtils: fix errors from strictFuncs use (#18998)
Nim 1.4.x compiled the below code without error when using `--experimental:strictFuncs` import std/sequtils type Foo = ref object let foo1 = Foo() let foo2 = Foo() let foos = @[foo1, foo2] let fooTuples = @[(foo1, 1), (foo2, 2)] discard repeat(foo1, 3) discard zip(foos, foos) discard unzip(fooTuples) However, since 2020-12-09, devel Nim produced errors like /tmp/bar.nim(11, 15) template/generic instantiation of `repeat` from here /foo/nim/pure/collections/sequtils.nim(172, 6) Error: 'repeat' can have side effects an object reachable from 'x' is potentially mutated /foo/nim/pure/collections/sequtils.nim(183, 15) the mutation is here /foo/nim/pure/collections/sequtils.nim(183, 15) is the statement that connected the mutation to the parameter This commit reverts some `proc` to `func` changes so that code that: - calls `repeat`, `zip`, or `unzip` - and instantiates them with types containing `ref` can once again be compiled with `strictFuncs`. Otherwise, a user might be forced to drop or alter their `strictFuncs` use when upgrading from Nim 1.4.x, or when writing new code that uses these procedures (at least for now, with the current `strictFuncs` implementation). This commit also adds tests to assert that the remaining funcs in this module can be compiled with `strictFuncs` when used with types containing `ref`. The original batch of `proc` to `func` changes in `sequtils.nim` was in commit 6f57eba, which was partially reverted in 38eb021. See also: #16305
1 parent f4525ef commit 3b1a601

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

lib/pure/collections/sequtils.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ func cycle*[T](s: openArray[T], n: Natural): seq[T] =
169169
result[o] = e
170170
inc o
171171

172-
func repeat*[T](x: T, n: Natural): seq[T] =
172+
proc repeat*[T](x: T, n: Natural): seq[T] =
173173
## Returns a new sequence with the item `x` repeated `n` times.
174174
## `n` must be a non-negative number (zero or more).
175175
##
@@ -246,7 +246,7 @@ func maxIndex*[T](s: openArray[T]): int {.since: (1, 1).} =
246246

247247

248248
template zipImpl(s1, s2, retType: untyped): untyped =
249-
func zip*[S, T](s1: openArray[S], s2: openArray[T]): retType =
249+
proc zip*[S, T](s1: openArray[S], s2: openArray[T]): retType =
250250
## Returns a new sequence with a combination of the two input containers.
251251
##
252252
## The input containers can be of different types.
@@ -289,7 +289,7 @@ when (NimMajor, NimMinor) <= (1, 0):
289289
else:
290290
zipImpl(s1, s2, seq[(S, T)])
291291

292-
func unzip*[S, T](s: openArray[(S, T)]): (seq[S], seq[T]) {.since: (1, 1).} =
292+
proc unzip*[S, T](s: openArray[(S, T)]): (seq[S], seq[T]) {.since: (1, 1).} =
293293
## Returns a tuple of two sequences split out from a sequence of 2-field tuples.
294294
runnableExamples:
295295
let

tests/stdlib/tsequtils.nim

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ from algorithm import sorted
1010

1111
{.experimental: "strictEffects".}
1212
{.push warningAsError[Effect]: on.}
13+
{.experimental: "strictFuncs".}
1314

1415
# helper for testing double substitution side effects which are handled
1516
# by `evalOnceAs`
@@ -456,6 +457,31 @@ block:
456457
# xxx: obscure CT error: basic_types.nim(16, 16) Error: internal error: symbol has no generated name: true
457458
doAssert: iter(3).mapIt(2*it).foldl(a + b) == 6
458459

460+
block: # strictFuncs tests with ref object
461+
type Foo = ref object
462+
463+
let foo1 = Foo()
464+
let foo2 = Foo()
465+
let foos = @[foo1, foo2]
466+
467+
# Procedures that are `func`
468+
discard concat(foos, foos)
469+
discard count(foos, foo1)
470+
discard cycle(foos, 3)
471+
discard deduplicate(foos)
472+
discard minIndex(foos)
473+
discard maxIndex(foos)
474+
discard distribute(foos, 2)
475+
var mutableFoos = foos
476+
mutableFoos.delete(0..1)
477+
mutableFoos.insert(foos)
478+
479+
# Some procedures that are `proc`, but were reverted from `func`
480+
discard repeat(foo1, 3)
481+
discard zip(foos, foos)
482+
let fooTuples = @[(foo1, 1), (foo2, 2)]
483+
discard unzip(fooTuples)
484+
459485
template main =
460486
# xxx move all tests here
461487
block: # delete tests

0 commit comments

Comments
 (0)