summary refs log tree commit diff stats
path: root/tests/effects
diff options
context:
space:
mode:
Diffstat (limited to 'tests/effects')
-rw-r--r--tests/effects/teffects11.nim21
-rw-r--r--tests/effects/teffects12.nim52
-rw-r--r--tests/effects/teffects13.nim19
-rw-r--r--tests/effects/teffects14.nim15
-rw-r--r--tests/effects/teffects15.nim18
-rw-r--r--tests/effects/teffects16.nim20
-rw-r--r--tests/effects/teffects17.nim17
-rw-r--r--tests/effects/teffects18.nim19
-rw-r--r--tests/effects/teffects19.nim23
9 files changed, 204 insertions, 0 deletions
diff --git a/tests/effects/teffects11.nim b/tests/effects/teffects11.nim
new file mode 100644
index 000000000..e4098e959
--- /dev/null
+++ b/tests/effects/teffects11.nim
@@ -0,0 +1,21 @@
+discard """
+action: compile
+errormsg: "type mismatch: got <proc (x: int){.gcsafe, locks: 0.}>"
+line: 21
+"""
+
+type
+  Effect1 = object
+  Effect2 = object
+  Effect3 = object
+
+proc test(fnc: proc(x: int): void {.forbids: [Effect2].}) {.tags: [Effect1, Effect3, RootEffect].} =
+  fnc(1)
+
+proc t1(x: int): void = echo $x
+proc t2(x: int): void {.tags: [Effect2].} = echo $x
+proc t3(x: int): void {.tags: [Effect3].} = echo $x
+
+test(t1)
+test(t3)
+test(t2)
diff --git a/tests/effects/teffects12.nim b/tests/effects/teffects12.nim
new file mode 100644
index 000000000..5f5499c38
--- /dev/null
+++ b/tests/effects/teffects12.nim
@@ -0,0 +1,52 @@
+discard """
+action: compile
+"""
+
+import std/locks
+
+type
+  Test2Effect* = object
+  Test2* = object
+    value2*: int
+  Test1Effect* = object
+  Test1* = object
+    value1*: int
+  Main* = object
+    test1Lock: Lock
+    test1: Test1
+    test2Lock: Lock
+    test2: Test2
+
+proc `=copy`(obj1: var Test2, obj2: Test2) {.error.}
+proc `=copy`(obj1: var Test1, obj2: Test1) {.error.}
+proc `=copy`(obj1: var Main, obj2: Main) {.error.}
+
+proc withTest1(main: var Main,
+               fn: proc(test1: var Test1) {.gcsafe, forbids: [Test1Effect].}) {.gcsafe, tags: [Test1Effect, RootEffect].} =
+  withLock(main.test1Lock):
+    fn(main.test1)
+
+proc withTest2(main: var Main,
+               fn: proc(test1: var Test2) {.gcsafe, forbids: [Test2Effect].}) {.gcsafe, tags: [Test2Effect, RootEffect].} =
+  withLock(main.test2Lock):
+    fn(main.test2)
+
+proc newMain(): Main =
+  var test1lock: Lock
+  initLock(test1Lock)
+  var test2lock: Lock
+  initLock(test2Lock)
+  var main = Main(test1Lock: move(test1Lock), test1: Test1(value1: 1),
+                  test2Lock: move(test2Lock), test2: Test2(value2: 2))
+  main.withTest1(proc(test1: var Test1) = test1.value1 += 1)
+  main.withTest2(proc(test2: var Test2) = test2.value2 += 1)
+  move main
+
+var main = newMain()
+main.withTest1(proc(test1: var Test1) =
+  test1.value1 += 1
+  main.withTest2(proc(test2: var Test2) = test2.value2 += 1)
+)
+
+main.withTest1(proc(test1: var Test1) {.tags: [].} = echo $test1.value1)
+main.withTest2(proc(test2: var Test2) {.tags: [].} = echo $test2.value2)
diff --git a/tests/effects/teffects13.nim b/tests/effects/teffects13.nim
new file mode 100644
index 000000000..73082f997
--- /dev/null
+++ b/tests/effects/teffects13.nim
@@ -0,0 +1,19 @@
+discard """
+action: compile
+errormsg: "writeSomething() has an illegal effect: WriteIO"
+line: 19
+"""
+
+type
+  IO = object of RootEffect ## input/output effect
+  ReadIO = object of IO     ## input effect
+  WriteIO = object of IO    ## output effect
+
+proc readSomething(): string {.tags: [ReadIO].} = ""
+proc writeSomething(): void {.tags: [WriteIO].} = echo "..."
+
+proc noWritesPlease() {.forbids: [WriteIO].} =
+  # this is OK:
+  echo readSomething()
+  # the compiler prevents this:
+  writeSomething()
diff --git a/tests/effects/teffects14.nim b/tests/effects/teffects14.nim
new file mode 100644
index 000000000..6291d9569
--- /dev/null
+++ b/tests/effects/teffects14.nim
@@ -0,0 +1,15 @@
+discard """
+action: compile
+errormsg: "func1() has an illegal effect: IO"
+line: 15
+"""
+
+type IO = object ## input/output effect
+proc func1(): string {.tags: [IO].} = discard
+proc func2(): string = discard
+
+proc no_IO_please() {.forbids: [IO].} =
+  # this is OK because it didn't define any tag:
+  discard func2()
+  # the compiler prevents this:
+  let y = func1()
diff --git a/tests/effects/teffects15.nim b/tests/effects/teffects15.nim
new file mode 100644
index 000000000..c3079cdbc
--- /dev/null
+++ b/tests/effects/teffects15.nim
@@ -0,0 +1,18 @@
+discard """
+action: compile
+errormsg: "method1(c) has an illegal effect: IO"
+line: 18
+"""
+
+type
+  IO = object ## input/output effect
+  CustomObject* = object of RootObj
+    text: string
+
+method method1(obj: var CustomObject): string {.tags: [IO].} = obj.text & "."
+method method2(obj: var CustomObject): string = obj.text & ":"
+
+proc noIO() {.forbids: [IO].} =
+  var c = CustomObject(text: "a")
+  echo c.method2()
+  echo c.method1()
diff --git a/tests/effects/teffects16.nim b/tests/effects/teffects16.nim
new file mode 100644
index 000000000..ee8f782a3
--- /dev/null
+++ b/tests/effects/teffects16.nim
@@ -0,0 +1,20 @@
+discard """
+action: compile
+errormsg: "writeSomething(\"a\") can have an unlisted effect: WriteIO"
+line: 20
+"""
+
+type
+  IO = object of RootEffect ## input/output effect
+  ReadIO = object of IO     ## input effect
+  WriteIO = object of IO    ## output effect
+  LogIO = object of IO      ## another output effect
+
+proc readSomething(): string {.tags: [ReadIO].} = ""
+proc writeSomething(msg: string): void {.tags: [WriteIO].} = echo msg
+proc logSomething(msg: string): void {.tags: [LogIo].} = echo msg
+
+proc noWritesPlease() {.forbids: [WriteIO], tags: [LogIO, ReadIO].} =
+  echo readSomething()
+  logSomething("a")
+  writeSomething("a")
diff --git a/tests/effects/teffects17.nim b/tests/effects/teffects17.nim
new file mode 100644
index 000000000..5e6b83896
--- /dev/null
+++ b/tests/effects/teffects17.nim
@@ -0,0 +1,17 @@
+discard """
+action: compile
+errormsg: "writeSomething(\"a\") has an illegal effect: WriteIO"
+line: 17
+"""
+
+type
+  IO = object of RootEffect ## input/output effect
+  ReadIO = object of IO     ## input effect
+  WriteIO = object of IO    ## output effect
+
+proc readSomething(): string {.tags: [ReadIO].} = ""
+proc writeSomething(msg: string): void {.tags: [WriteIO].} = echo msg
+
+proc illegalEffectNegation() {.forbids: [WriteIO], tags: [ReadIO, WriteIO].} =
+  echo readSomething()
+  writeSomething("a")
diff --git a/tests/effects/teffects18.nim b/tests/effects/teffects18.nim
new file mode 100644
index 000000000..576e76635
--- /dev/null
+++ b/tests/effects/teffects18.nim
@@ -0,0 +1,19 @@
+discard """
+action: compile
+errormsg: "type mismatch: got <ProcType2>"
+line: 19
+"""
+
+type MyEffect = object
+type ProcType1 = proc (i: int): void {.forbids: [MyEffect].}
+type ProcType2 = proc (i: int): void
+
+proc testFunc(p: ProcType1): void = p(1)
+
+proc toBeCalled(i: int): void {.tags: [MyEffect].} = echo $i
+
+let emptyTags = proc(i: int): void {.tags: [].} = echo $i
+let noTags: ProcType2 = proc(i: int): void = toBeCalled(i)
+
+testFunc(emptyTags)
+testFunc(noTags)
diff --git a/tests/effects/teffects19.nim b/tests/effects/teffects19.nim
new file mode 100644
index 000000000..49fb87523
--- /dev/null
+++ b/tests/effects/teffects19.nim
@@ -0,0 +1,23 @@
+discard """
+action: compile
+errormsg: "type mismatch: got <proc (i: int){.gcsafe, locks: 0.}>"
+line: 23
+"""
+
+type MyEffect = object
+type ProcType1 = proc (i: int): void {.forbids: [MyEffect].}
+type ProcType2 = proc (i: int): void
+
+proc caller1(p: ProcType1): void = p(1)
+proc caller2(p: ProcType2): void = p(1)
+
+proc effectful(i: int): void {.tags: [MyEffect].} = echo $i
+proc effectless(i: int): void {.forbids: [MyEffect].} = echo $i
+
+proc toBeCalled1(i: int): void = effectful(i)
+proc toBeCalled2(i: int): void = effectless(i)
+
+caller1(toBeCalled2)
+caller2(toBeCalled1)
+caller2(toBeCalled2)
+caller1(toBeCalled1)