sequtils now support strict effect tracking (#18782)
This commit is contained in:
parent
7c8ea490a2
commit
69cabaa81c
2 changed files with 19 additions and 9 deletions
|
|
@ -84,6 +84,11 @@ import std/private/since
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
|
when defined(nimHasEffectsOf):
|
||||||
|
{.experimental: "strictEffects".}
|
||||||
|
else:
|
||||||
|
{.pragma: effectsOf.}
|
||||||
|
|
||||||
macro evalOnceAs(expAlias, exp: untyped,
|
macro evalOnceAs(expAlias, exp: untyped,
|
||||||
letAssigneable: static[bool]): untyped =
|
letAssigneable: static[bool]): untyped =
|
||||||
## Injects `expAlias` in caller scope, to avoid bugs involving multiple
|
## 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
|
first = last
|
||||||
|
|
||||||
proc map*[T, S](s: openArray[T], op: proc (x: T): S {.closure.}):
|
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
|
## Returns a new sequence with the results of the `op` proc applied to every
|
||||||
## item in the container `s`.
|
## 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])
|
result[i] = op(s[i])
|
||||||
|
|
||||||
proc apply*[T](s: var openArray[T], op: proc (x: var T) {.closure.})
|
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.
|
## Applies `op` to every item in `s`, modifying it directly.
|
||||||
##
|
##
|
||||||
## Note that the container `s` must be declared as a `var`,
|
## 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])
|
for i in 0 ..< s.len: op(s[i])
|
||||||
|
|
||||||
proc apply*[T](s: var openArray[T], op: proc (x: T): T {.closure.})
|
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.
|
## Applies `op` to every item in `s` modifying it directly.
|
||||||
##
|
##
|
||||||
## Note that the container `s` must be declared as a `var`
|
## 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])
|
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
|
## Same as `apply` but for a proc that does not return anything
|
||||||
## and does not mutate `s` directly.
|
## and does not mutate `s` directly.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
|
|
@ -429,7 +434,7 @@ proc apply*[T](s: openArray[T], op: proc (x: T) {.closure.}) {.inline, since: (1
|
||||||
assert message == "01234"
|
assert message == "01234"
|
||||||
for i in 0 ..< s.len: op(s[i])
|
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
|
## Iterates through a container `s` and yields every item that fulfills the
|
||||||
## predicate `pred` (a function that returns a `bool`).
|
## 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]
|
yield s[i]
|
||||||
|
|
||||||
proc filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): seq[T]
|
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
|
## Returns a new sequence with all the items of `s` that fulfill the
|
||||||
## predicate `pred` (a function that returns a `bool`).
|
## 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])
|
result.add(s[i])
|
||||||
|
|
||||||
proc keepIf*[T](s: var seq[T], pred: proc(x: T): bool {.closure.})
|
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
|
## Keeps the items in the passed sequence `s` if they fulfill the
|
||||||
## predicate `pred` (a function that returns a `bool`).
|
## predicate `pred` (a function that returns a `bool`).
|
||||||
##
|
##
|
||||||
|
|
@ -685,7 +690,7 @@ since (1, 1):
|
||||||
if pred: result += 1
|
if pred: result += 1
|
||||||
result
|
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
|
## Iterates through a container and checks if every item fulfills the
|
||||||
## predicate.
|
## predicate.
|
||||||
##
|
##
|
||||||
|
|
@ -727,7 +732,7 @@ template allIt*(s, pred: untyped): bool =
|
||||||
break
|
break
|
||||||
result
|
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
|
## Iterates through a container and checks if at least one item
|
||||||
## fulfills the predicate.
|
## fulfills the predicate.
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ import std/sequtils
|
||||||
import strutils
|
import strutils
|
||||||
from algorithm import sorted
|
from algorithm import sorted
|
||||||
|
|
||||||
|
{.experimental: "strictEffects".}
|
||||||
|
{.push warningAsError[Effect]: on.}
|
||||||
|
|
||||||
# helper for testing double substitution side effects which are handled
|
# helper for testing double substitution side effects which are handled
|
||||||
# by `evalOnceAs`
|
# by `evalOnceAs`
|
||||||
var counter = 0
|
var counter = 0
|
||||||
|
|
@ -507,3 +510,5 @@ template main =
|
||||||
|
|
||||||
static: main()
|
static: main()
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue