diff options
Diffstat (limited to 'tests/effects')
-rw-r--r-- | tests/effects/tdiagnostic_messages.nim | 2 | ||||
-rw-r--r-- | tests/effects/teffects1.nim | 9 | ||||
-rw-r--r-- | tests/effects/teffects11.nim | 2 | ||||
-rw-r--r-- | tests/effects/teffects19.nim | 2 | ||||
-rw-r--r-- | tests/effects/teffects6.nim | 2 | ||||
-rw-r--r-- | tests/effects/teffectsmisc.nim | 39 | ||||
-rw-r--r-- | tests/effects/tfuncs_cannot_mutate.nim | 10 | ||||
-rw-r--r-- | tests/effects/tfuncs_cannot_mutate2.nim | 7 | ||||
-rw-r--r-- | tests/effects/tfuncs_cannot_mutate3.nim | 35 | ||||
-rw-r--r-- | tests/effects/tfuncs_cannot_mutate_simple.nim | 5 | ||||
-rw-r--r-- | tests/effects/tgcsafe.nim | 4 | ||||
-rw-r--r-- | tests/effects/tgcsafe2.nim | 2 | ||||
-rw-r--r-- | tests/effects/thooks.nim | 16 | ||||
-rw-r--r-- | tests/effects/tlaxeffects.nim | 11 | ||||
-rw-r--r-- | tests/effects/tnosideeffect.nim | 2 | ||||
-rw-r--r-- | tests/effects/toutparam.nim | 28 | ||||
-rw-r--r-- | tests/effects/tstrict_caseobjects.nim | 47 | ||||
-rw-r--r-- | tests/effects/tstrict_effects3.nim | 11 | ||||
-rw-r--r-- | tests/effects/tstrict_funcs_imports.nim | 19 | ||||
-rw-r--r-- | tests/effects/tstrictfuncs_misc.nim | 65 |
20 files changed, 255 insertions, 63 deletions
diff --git a/tests/effects/tdiagnostic_messages.nim b/tests/effects/tdiagnostic_messages.nim index 2ce4895a3..b1acf8c5c 100644 --- a/tests/effects/tdiagnostic_messages.nim +++ b/tests/effects/tdiagnostic_messages.nim @@ -12,7 +12,7 @@ tdiagnostic_messages.nim(36, 6) Error: 'a' can have side effects >>> tdiagnostic_messages.nim(32, 33) Hint: 'callWithSideEffects' calls `.sideEffect` 'indirectCallViaPointer' >>>> tdiagnostic_messages.nim(27, 6) Hint: 'indirectCallViaPointer' called by 'callWithSideEffects' >>>>> tdiagnostic_messages.nim(28, 32) Hint: 'indirectCallViaPointer' calls routine via pointer indirection ->>> tdiagnostic_messages.nim(33, 10) Hint: 'callWithSideEffects' calls `.sideEffect` 'myEcho' +>>> tdiagnostic_messages.nim(33, 3) Hint: 'callWithSideEffects' calls `.sideEffect` 'myEcho' >>>> tdiagnostic_messages.nim(24, 6) Hint: 'myEcho' called by 'callWithSideEffects' >>> tdiagnostic_messages.nim(34, 3) Hint: 'callWithSideEffects' accesses global state 'globalVar' >>>> tdiagnostic_messages.nim(23, 5) Hint: 'globalVar' accessed by 'callWithSideEffects' diff --git a/tests/effects/teffects1.nim b/tests/effects/teffects1.nim index ca9021999..1d267b5fa 100644 --- a/tests/effects/teffects1.nim +++ b/tests/effects/teffects1.nim @@ -17,11 +17,16 @@ proc forw: int {. .} proc lier(): int {.raises: [IO2Error].} = #[tt.Hint ^ 'lier' cannot raise 'IO2Error' [XCannotRaiseY] ]# writeLine stdout, "arg" #[tt.Error - ^ writeLine stdout, ["arg"] can raise an unlisted exception: ref IOError ]# + ^ writeLine stdout, ["arg"] can raise an unlisted exception: ref IOError ]# proc forw: int = raise newException(IOError, "arg") +block: + proc someProc(t: string) {.raises: [Defect].} = + discard + let vh: proc(topic: string) {.raises: [].} = someProc + {.push raises: [Defect].} type @@ -34,7 +39,7 @@ proc foo(x: int): string {.nimcall, raises: [ValueError].} = var p: MyProcType = foo #[tt.Error ^ -type mismatch: got <proc (x: int): string{.nimcall, noSideEffect, gcsafe, locks: 0.}> but expected 'MyProcType = proc (x: int): string{.closure.}' +type mismatch: got <proc (x: int): string{.nimcall, raises: [ValueError], noSideEffect, gcsafe.}> but expected 'MyProcType = proc (x: int): string{.closure.}' Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'. .raise effects differ ]# diff --git a/tests/effects/teffects11.nim b/tests/effects/teffects11.nim index e4098e959..20b7026ab 100644 --- a/tests/effects/teffects11.nim +++ b/tests/effects/teffects11.nim @@ -1,6 +1,6 @@ discard """ action: compile -errormsg: "type mismatch: got <proc (x: int){.gcsafe, locks: 0.}>" +errormsg: "type mismatch: got <proc (x: int){.gcsafe.}>" line: 21 """ diff --git a/tests/effects/teffects19.nim b/tests/effects/teffects19.nim index 49fb87523..6b4ab0819 100644 --- a/tests/effects/teffects19.nim +++ b/tests/effects/teffects19.nim @@ -1,6 +1,6 @@ discard """ action: compile -errormsg: "type mismatch: got <proc (i: int){.gcsafe, locks: 0.}>" +errormsg: "type mismatch: got <proc (i: int){.gcsafe.}>" line: 23 """ diff --git a/tests/effects/teffects6.nim b/tests/effects/teffects6.nim index 4a39e0dca..d3af22434 100644 --- a/tests/effects/teffects6.nim +++ b/tests/effects/teffects6.nim @@ -21,7 +21,7 @@ createMenuItem(s, "Go to definition...", ) -proc noRaise(x: proc()) {.raises: [].} = +proc noRaise(x: proc()) {.raises: [], effectsOf: x.} = # unknown call that might raise anything, but valid: x() diff --git a/tests/effects/teffectsmisc.nim b/tests/effects/teffectsmisc.nim new file mode 100644 index 000000000..8fb95b275 --- /dev/null +++ b/tests/effects/teffectsmisc.nim @@ -0,0 +1,39 @@ +discard """ + output: ''' +printing from adder +''' +""" + +import std/sugar + +block: + proc makeAdder(a: int): (int) -> void = + proc discard_adder(x: int) {.closure.} = + discard a + x + + proc echo_adder(x: int) {.closure.} = + echo("printing from adder") + + if a > 0: + discard_adder + else: + echo_adder + + let newAdder = makeAdder(0) + newAdder(5) + +block: + proc makeAdder(a: int): (int) -> void = + proc discard_adder(x: int) {.closure.} = + discard a + x + + proc echo_adder(x: int) {.closure.} = + echo("printing from adder") + + if a > 0: + echo_adder + else: + discard_adder + + let newAdder = makeAdder(0) + newAdder(5) diff --git a/tests/effects/tfuncs_cannot_mutate.nim b/tests/effects/tfuncs_cannot_mutate.nim index 8784cbbb1..9934d27a7 100644 --- a/tests/effects/tfuncs_cannot_mutate.nim +++ b/tests/effects/tfuncs_cannot_mutate.nim @@ -1,9 +1,6 @@ discard """ - errormsg: "'mutate' can have side effects" - nimout: '''an object reachable from 'n' is potentially mutated -tfuncs_cannot_mutate.nim(39, 15) the mutation is here -tfuncs_cannot_mutate.nim(37, 7) is the statement that connected the mutation to the parameter -''' + errormsg: "cannot mutate location select(x, z).data within a strict func" + line: 35 """ {.experimental: "strictFuncs".} @@ -25,8 +22,7 @@ func len(n: Node): int = it = it.ri func doNotDistract(n: Node) = - var m = Node() - m.data = "abc" + var m = Node(data: "abc") func select(a, b: Node): Node = b diff --git a/tests/effects/tfuncs_cannot_mutate2.nim b/tests/effects/tfuncs_cannot_mutate2.nim index d5082e57b..86f811017 100644 --- a/tests/effects/tfuncs_cannot_mutate2.nim +++ b/tests/effects/tfuncs_cannot_mutate2.nim @@ -1,9 +1,6 @@ discard """ - errormsg: "'copy' can have side effects" - nimout: '''an object reachable from 'y' is potentially mutated -tfuncs_cannot_mutate2.nim(15, 7) the mutation is here -tfuncs_cannot_mutate2.nim(13, 10) is the statement that connected the mutation to the parameter -''' + errormsg: "cannot mutate location x[0].a within a strict func" + line: 12 """ {.experimental: "strictFuncs".} diff --git a/tests/effects/tfuncs_cannot_mutate3.nim b/tests/effects/tfuncs_cannot_mutate3.nim new file mode 100644 index 000000000..029152029 --- /dev/null +++ b/tests/effects/tfuncs_cannot_mutate3.nim @@ -0,0 +1,35 @@ +discard """ + errormsg: "cannot mutate location kid.parent within a strict func" + line: 16 +""" + +{.experimental: "strictFuncs".} + +type + Node = ref object + name: string + kids: seq[Node] + parent: Node + +func initParents(tree: Node) = + for kid in tree.kids: + kid.parent = tree + initParents(kid) + +proc process(intro: Node): Node = + var tree = Node(name: "root", kids: @[ + intro, + Node(name: "one", kids: @[ + Node(name: "two"), + Node(name: "three"), + ]), + Node(name: "four"), + ]) + initParents(tree) + +proc main() = + var intro = Node(name: "intro") + var tree = process(intro) + echo intro.parent.name + +main() diff --git a/tests/effects/tfuncs_cannot_mutate_simple.nim b/tests/effects/tfuncs_cannot_mutate_simple.nim index a94a8d746..0ae4a0db9 100644 --- a/tests/effects/tfuncs_cannot_mutate_simple.nim +++ b/tests/effects/tfuncs_cannot_mutate_simple.nim @@ -1,7 +1,6 @@ discard """ - errormsg: "'edit' can have side effects" - nimout: '''an object reachable from 'x' is potentially mutated -tfuncs_cannot_mutate_simple.nim(16, 4) the mutation is here''' + errormsg: '''cannot mutate location x.data within a strict func''' + line: 15 """ {.experimental: "strictFuncs".} diff --git a/tests/effects/tgcsafe.nim b/tests/effects/tgcsafe.nim index 363624f19..cfac3ddd8 100644 --- a/tests/effects/tgcsafe.nim +++ b/tests/effects/tgcsafe.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "'mainUnsafe' is not GC-safe" + errormsg: "'mainUnsafe' is not GC-safe as it performs an indirect call here" line: 26 cmd: "nim $target --hints:on --threads:on $options $file" """ @@ -13,7 +13,7 @@ proc myproc(i: int) {.gcsafe.} = if isNil(global_proc): return -proc mymap(x: proc ()) = +proc mymap(x: proc ()) {.effectsOf: x.} = x() var diff --git a/tests/effects/tgcsafe2.nim b/tests/effects/tgcsafe2.nim index 07da4e3f8..6268592a9 100644 --- a/tests/effects/tgcsafe2.nim +++ b/tests/effects/tgcsafe2.nim @@ -1,5 +1,5 @@ discard """ - errormsg: '''type mismatch: got <proc (s: string){.locks: 0.}>''' + errormsg: '''type mismatch: got <proc (s: string)>''' line: 11 """ #5620 diff --git a/tests/effects/thooks.nim b/tests/effects/thooks.nim new file mode 100644 index 000000000..23cc005cd --- /dev/null +++ b/tests/effects/thooks.nim @@ -0,0 +1,16 @@ +discard """ + matrix: "--warningAsError:Effect" +""" + +import std/isolation + +# bug #23129 +type + Thing = object + x: string + +proc send(x: string) = + let wrapper = Thing(x: x) + discard isolate(wrapper) + +send("la") \ No newline at end of file diff --git a/tests/effects/tlaxeffects.nim b/tests/effects/tlaxeffects.nim new file mode 100644 index 000000000..7eedc372a --- /dev/null +++ b/tests/effects/tlaxeffects.nim @@ -0,0 +1,11 @@ +discard """ + cmd: "nim $target $options --legacy:laxEffects $file" +""" + + +type + Foo = object + bar: seq[Foo] + +proc `==`(a, b: Foo): bool = + a.bar == b.bar diff --git a/tests/effects/tnosideeffect.nim b/tests/effects/tnosideeffect.nim index 9cabb35a2..9fc2f74d4 100644 --- a/tests/effects/tnosideeffect.nim +++ b/tests/effects/tnosideeffect.nim @@ -1,5 +1,5 @@ block: # `.noSideEffect` - func foo(bar: proc(): int): int = bar() + func foo(bar: proc(): int): int {.effectsOf: bar.} = bar() var count = 0 proc fn1(): int = 1 proc fn2(): int = (count.inc; count) diff --git a/tests/effects/toutparam.nim b/tests/effects/toutparam.nim deleted file mode 100644 index 1126aa77e..000000000 --- a/tests/effects/toutparam.nim +++ /dev/null @@ -1,28 +0,0 @@ -discard """ - cmd: '''nim c --warningAsError:Uninit:on --skipCfg --skipParentCfg $file''' - errormsg: "use explicit initialization of 'x' for clarity [Uninit]" - line: 24 - disabled: "true" -""" - -proc gah[T](x: out T) = - x = 3 - -proc main = - var a: array[2, int] - var x: int - gah(x) - a[0] = 3 - a[x] = 3 - echo x - -main() - -proc mainB = - var a: array[2, int] - var x: int - a[0] = 3 - a[x] = 3 - echo x - -mainB() diff --git a/tests/effects/tstrict_caseobjects.nim b/tests/effects/tstrict_caseobjects.nim new file mode 100644 index 000000000..20bc810e0 --- /dev/null +++ b/tests/effects/tstrict_caseobjects.nim @@ -0,0 +1,47 @@ +discard """ + errormsg: "field access outside of valid case branch: x.x" + line: 45 +""" + +{.experimental: "strictCaseObjects".} + +type + NodeKind = enum + nkParent, + nkChild + + Node {.acyclic.} = ref object + case kind: NodeKind + of nkParent: + children: seq[Node] + of nkChild: + name: string + +let list = @[Node(kind: nkParent, children: @[]), Node(kind: nkChild, name: "hello")] +for node in list: + case node.kind + of nkChild: + echo $node.name # here this time there is a warning + else: discard + + +type + Foo = object + case b: bool + of false: + s: string + of true: + x: int + +var x = Foo(b: true, x: 4) +case x.b +of true: + echo x.x +of false: + echo "no" + +case x.b +of false: + echo x.x +of true: + echo "no" diff --git a/tests/effects/tstrict_effects3.nim b/tests/effects/tstrict_effects3.nim index 027b46474..0d98a0343 100644 --- a/tests/effects/tstrict_effects3.nim +++ b/tests/effects/tstrict_effects3.nim @@ -44,3 +44,14 @@ proc fail() = discard f1() f2() +import std/json + +# bug #22254 +proc senri(a, b: seq[JsonNode]) {.raises: [].} = discard a == b + +# bug #22253 +proc serika() {.raises: [].} = discard default(JsonNode) == nil + +senri(@[newJBool(true)], @[newJBool(false)]) +serika() + diff --git a/tests/effects/tstrict_funcs_imports.nim b/tests/effects/tstrict_funcs_imports.nim index 264771a1a..bf68b61b2 100644 --- a/tests/effects/tstrict_funcs_imports.nim +++ b/tests/effects/tstrict_funcs_imports.nim @@ -7,11 +7,19 @@ discard """ when defined(linux): import linenoise +when defined(nimPreviewSlimSystem): + import std/[ + assertions, + formatfloat, + objectdollar, + syncio, + widestrs, + ] + import algorithm, asyncdispatch, asyncfile, - asyncftpclient, asyncfutures, asynchttpserver, asyncmacro, @@ -31,11 +39,6 @@ import cpuload, critbits, cstrutils, - db_common, - db_mysql, - db_odbc, - db_postgres, - db_sqlite, deques, distros, dynlib, @@ -63,7 +66,6 @@ import macros, marshal, math, - md5, memfiles, mersenne, mimetypes, @@ -87,7 +89,6 @@ import pegs, posix_utils, prelude, - punycode, random, rationals, rdstdin, @@ -102,7 +103,6 @@ import sets, sharedlist, sharedtables, - smtp, ssl_certs, ssl_config, stats, @@ -154,7 +154,6 @@ import std/[ monotimes, packedsets, setutils, - sha1, socketstreams, stackframes, sums, diff --git a/tests/effects/tstrictfuncs_misc.nim b/tests/effects/tstrictfuncs_misc.nim new file mode 100644 index 000000000..8c573bb3a --- /dev/null +++ b/tests/effects/tstrictfuncs_misc.nim @@ -0,0 +1,65 @@ +discard """ + action: compile +""" + +{.experimental: "strictFuncs".} + +func sortedFake1[T](a: openArray[T]): seq[T] = + for i in 0 .. a.high: result.add a[i] +func sortedFake2[T](a: openArray[T]): seq[T] = + result = newSeq[T](a.len) + for i in 0 .. a.high: result[i] = a[i] +type Foo1 = object +type Foo2 = ref object +block: + let a1 = sortedFake1([Foo1()]) # ok + let a2 = sortedFake1([Foo2()]) # ok +block: + let a1 = sortedFake2([Foo1()]) # ok + let a2 = sortedFake2([Foo2()]) # error: Error: 'sortedFake2' can have side effects + + +import std/sequtils +type Foob = ref object + x: int +let a1 = zip(@[1,2], @[1,2]) # ok +let a2 = zip(@[Foob(x: 1)], @[Foob(x: 2)]) # error in 1.6.0 RC2, but not 1.4.x + + +# bug #20863 +type + Fooc = ref object + +func twice(foo: Fooc) = + var a = newSeq[Fooc](2) + a[0] = foo # No error. + a[1] = foo # Error: 'twice' can have side effects. + +let foo = Fooc() +twice(foo) + +# bug #17387 +import json + +func parseColumn(columnNode: JsonNode) = + let columnName = columnNode["name"].str + +parseColumn(%*{"a": "b"}) + +type + MyTable = object + data: seq[int] + + JsonNode3 = ref object + fields: MyTable + +proc `[]`(t: MyTable, key: string): int = + result = t.data[0] + +proc `[]`(x: JsonNode3, key: string): int = + result = x.fields[key] + +func parseColumn(columnNode: JsonNode3) = + var columnName = columnNode["test"] + +parseColumn(JsonNode3()) |