sequtils now support strict effect tracking (#18782)

This commit is contained in:
Andreas Rumpf
2021-09-02 14:35:25 +02:00
committed by GitHub
parent 7c8ea490a2
commit 69cabaa81c
2 changed files with 19 additions and 9 deletions

View File

@@ -84,6 +84,11 @@ import std/private/since
import macros
when defined(nimHasEffectsOf):
{.experimental: "strictEffects".}
else:
{.pragma: effectsOf.}
macro evalOnceAs(expAlias, exp: untyped,
letAssigneable: static[bool]): untyped =
## Injects `expAlias` in caller scope, to avoid bugs involving multiple
@@ -356,7 +361,7 @@ func distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] =
first = last
proc map*[T, S](s: openArray[T], op: proc (x: T): S {.closure.}):
seq[S]{.inline.} =
seq[S] {.inline, effectsOf: op.} =
## Returns a new sequence with the results of the `op` proc applied to every
## item in the container `s`.
##
@@ -382,7 +387,7 @@ proc map*[T, S](s: openArray[T], op: proc (x: T): S {.closure.}):
result[i] = op(s[i])
proc apply*[T](s: var openArray[T], op: proc (x: var T) {.closure.})
{.inline.} =
{.inline, effectsOf: op.} =
## Applies `op` to every item in `s`, modifying it directly.
##
## Note that the container `s` must be declared as a `var`,
@@ -401,7 +406,7 @@ proc apply*[T](s: var openArray[T], op: proc (x: var T) {.closure.})
for i in 0 ..< s.len: op(s[i])
proc apply*[T](s: var openArray[T], op: proc (x: T): T {.closure.})
{.inline.} =
{.inline, effectsOf: op.} =
## Applies `op` to every item in `s` modifying it directly.
##
## Note that the container `s` must be declared as a `var`
@@ -420,7 +425,7 @@ proc apply*[T](s: var openArray[T], op: proc (x: T): T {.closure.})
for i in 0 ..< s.len: s[i] = op(s[i])
proc apply*[T](s: openArray[T], op: proc (x: T) {.closure.}) {.inline, since: (1, 3).} =
proc apply*[T](s: openArray[T], op: proc (x: T) {.closure.}) {.inline, since: (1, 3), effectsOf: op.} =
## Same as `apply` but for a proc that does not return anything
## and does not mutate `s` directly.
runnableExamples:
@@ -429,7 +434,7 @@ proc apply*[T](s: openArray[T], op: proc (x: T) {.closure.}) {.inline, since: (1
assert message == "01234"
for i in 0 ..< s.len: op(s[i])
iterator filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): T =
iterator filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): T {.effectsOf: pred.} =
## Iterates through a container `s` and yields every item that fulfills the
## predicate `pred` (a function that returns a `bool`).
##
@@ -453,7 +458,7 @@ iterator filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): T =
yield s[i]
proc filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): seq[T]
{.inline.} =
{.inline, effectsOf: pred.} =
## Returns a new sequence with all the items of `s` that fulfill the
## predicate `pred` (a function that returns a `bool`).
##
@@ -480,7 +485,7 @@ proc filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): seq[T]
result.add(s[i])
proc keepIf*[T](s: var seq[T], pred: proc(x: T): bool {.closure.})
{.inline.} =
{.inline, effectsOf: pred.} =
## Keeps the items in the passed sequence `s` if they fulfill the
## predicate `pred` (a function that returns a `bool`).
##
@@ -685,7 +690,7 @@ since (1, 1):
if pred: result += 1
result
proc all*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool =
proc all*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool {.effectsOf: pred.} =
## Iterates through a container and checks if every item fulfills the
## predicate.
##
@@ -727,7 +732,7 @@ template allIt*(s, pred: untyped): bool =
break
result
proc any*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool =
proc any*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool {.effectsOf: pred.} =
## Iterates through a container and checks if at least one item
## fulfills the predicate.
##

View File

@@ -8,6 +8,9 @@ import std/sequtils
import strutils
from algorithm import sorted
{.experimental: "strictEffects".}
{.push warningAsError[Effect]: on.}
# helper for testing double substitution side effects which are handled
# by `evalOnceAs`
var counter = 0
@@ -507,3 +510,5 @@ template main =
static: main()
main()
{.pop.}