summary refs log tree commit diff stats
path: root/tests/stdlib/tsequtils.nim
diff options
context:
space:
mode:
authoree7 <45465154+ee7@users.noreply.github.com>2021-10-16 11:25:05 +0200
committerGitHub <noreply@github.com>2021-10-16 11:25:05 +0200
commit3b1a601fe1ad6ac27a21b5f28442474d47c60a2f (patch)
tree3ce673affa99e190c8e23bdf0a318d92f937f845 /tests/stdlib/tsequtils.nim
parentf4525efcf3b915be8e17c9730e9e0ffd0afe3a0f (diff)
downloadNim-3b1a601fe1ad6ac27a21b5f28442474d47c60a2f.tar.gz
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 6f57ebae349f, which was partially reverted in 38eb021f8158.

See also: https://github.com/nim-lang/Nim/issues/16305
Diffstat (limited to 'tests/stdlib/tsequtils.nim')
-rw-r--r--tests/stdlib/tsequtils.nim26
1 files changed, 26 insertions, 0 deletions
diff --git a/tests/stdlib/tsequtils.nim b/tests/stdlib/tsequtils.nim
index 338473407..179f619f0 100644
--- a/tests/stdlib/tsequtils.nim
+++ b/tests/stdlib/tsequtils.nim
@@ -10,6 +10,7 @@ from algorithm import sorted
 
 {.experimental: "strictEffects".}
 {.push warningAsError[Effect]: on.}
+{.experimental: "strictFuncs".}
 
 # helper for testing double substitution side effects which are handled
 # by `evalOnceAs`
@@ -456,6 +457,31 @@ block:
     # xxx: obscure CT error: basic_types.nim(16, 16) Error: internal error: symbol has no generated name: true
     doAssert: iter(3).mapIt(2*it).foldl(a + b) == 6
 
+block: # strictFuncs tests with ref object
+  type Foo = ref object
+
+  let foo1 = Foo()
+  let foo2 = Foo()
+  let foos = @[foo1, foo2]
+
+  # Procedures that are `func`
+  discard concat(foos, foos)
+  discard count(foos, foo1)
+  discard cycle(foos, 3)
+  discard deduplicate(foos)
+  discard minIndex(foos)
+  discard maxIndex(foos)
+  discard distribute(foos, 2)
+  var mutableFoos = foos
+  mutableFoos.delete(0..1)
+  mutableFoos.insert(foos)
+
+  # Some procedures that are `proc`, but were reverted from `func`
+  discard repeat(foo1, 3)
+  discard zip(foos, foos)
+  let fooTuples = @[(foo1, 1), (foo2, 2)]
+  discard unzip(fooTuples)
+
 template main =
   # xxx move all tests here
   block: # delete tests