summary refs log tree commit diff stats
path: root/tests/method
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2023-11-28 22:11:43 +0800
committerGitHub <noreply@github.com>2023-11-28 15:11:43 +0100
commit30cf33f04dfb768182accb3ad35ec6364c998664 (patch)
tree63dc0d6a36bc662b94246392e03a26b7eaeb116d /tests/method
parent8cad6ac0487800f7d41e38303e52129777e6c22e (diff)
downloadNim-30cf33f04dfb768182accb3ad35ec6364c998664.tar.gz
rework the vtable implementation embedding the vtable array directly with new strictions on methods (#22991)
**TODO**
- [x] fixes changelog
With the new option `nimPreviewVtables`, `methods` are confined in the
same module where the type of the first parameter is defined

- [x] make it opt in after CI checks its feasibility

## In the following-up PRs

- [ ] in the following PRs, refactor code into a more efficient one

- [ ] cpp needs special treatments since it cannot embed array in light
of the preceding limits: ref
https://github.com/nim-lang/Nim/pull/20977#discussion_r1035528927; we
can support cpp backends with vtable implementations later on the
comprise that uses indirect vtable access

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
Diffstat (limited to 'tests/method')
-rw-r--r--tests/method/nim.cfg1
-rw-r--r--tests/method/tcompilegenerics.nim24
-rw-r--r--tests/method/tgeneric_methods.nim84
-rw-r--r--tests/method/tmethod_various.nim7
-rw-r--r--tests/method/tmethods_old.nim12
-rw-r--r--tests/method/tmultim.nim193
-rw-r--r--tests/method/tvtable.nim19
7 files changed, 195 insertions, 145 deletions
diff --git a/tests/method/nim.cfg b/tests/method/nim.cfg
deleted file mode 100644
index 57698b028..000000000
--- a/tests/method/nim.cfg
+++ /dev/null
@@ -1 +0,0 @@
-multimethods:on
diff --git a/tests/method/tcompilegenerics.nim b/tests/method/tcompilegenerics.nim
new file mode 100644
index 000000000..d0732895b
--- /dev/null
+++ b/tests/method/tcompilegenerics.nim
@@ -0,0 +1,24 @@
+discard """
+  matrix: "--mm:arc; --mm:refc"
+  output: '''
+newDNode base
+'''
+"""
+
+type
+  SNodeAny = ref object of RootObj
+  SNode[T] = ref object of SNodeAny
+    m: T
+  DNode[T] = ref object
+
+method getStr(s: SNode[float]): string {.base.} = "blahblah"
+
+method newDNode(s: SNodeAny) {.base.} =
+  echo "newDNode base"
+
+method newDNode[T](s: SNode[T]) =
+  echo "newDNode generic"
+
+let m = SNode[float]()
+let s = SNodeAny(m)
+newDnode(s)
\ No newline at end of file
diff --git a/tests/method/tgeneric_methods.nim b/tests/method/tgeneric_methods.nim
index ab92c66d8..0f1e7e1f0 100644
--- a/tests/method/tgeneric_methods.nim
+++ b/tests/method/tgeneric_methods.nim
@@ -1,42 +1,42 @@
-discard """
-  matrix: "--mm:arc; --mm:refc"
-  output: '''wow2
-X 1
-X 3'''
-"""
-type
-  First[T] = ref object of RootObj
-    value: T
-
-  Second[T] = ref object of First[T]
-    value2: T
-
-method wow[T](y: int; x: First[T]) {.base.} =
-  echo "wow1"
-
-method wow[T](y: int; x: Second[T]) =
-  echo "wow2"
-
-var
-  x: Second[int]
-new(x)
-
-proc takeFirst(x: First[int]) =
-  wow(2, x)
-
-takeFirst(x)
-
-
-# bug #5479
-type
-  Base[T: static[int]] = ref object of RootObj
-
-method test[T](t: Base[T]) {.base.} =
-  echo "X ", t.T
-
-let ab = Base[1]()
-
-ab.test()
-
-let ac = Base[3]()
-ac.test()
+discard """

+  matrix: "--mm:arc --multimethods:on -u:nimPreviewVtables; --mm:refc --multimethods:on -u:nimPreviewVtables"

+  output: '''wow2

+X 1

+X 3'''

+"""

+type

+  First[T] = ref object of RootObj

+    value: T

+

+  Second[T] = ref object of First[T]

+    value2: T

+

+method wow[T](y: int; x: First[T]) {.base.} =

+  echo "wow1"

+

+method wow[T](y: int; x: Second[T]) =

+  echo "wow2"

+

+var

+  x: Second[int]

+new(x)

+

+proc takeFirst(x: First[int]) =

+  wow(2, x)

+

+takeFirst(x)

+

+

+# bug #5479

+type

+  Base[T: static[int]] = ref object of RootObj

+

+method test[T](t: Base[T]) {.base.} =

+  echo "X ", t.T

+

+let ab = Base[1]()

+

+ab.test()

+

+let ac = Base[3]()

+ac.test()

diff --git a/tests/method/tmethod_various.nim b/tests/method/tmethod_various.nim
index c41d04983..3b64aea8d 100644
--- a/tests/method/tmethod_various.nim
+++ b/tests/method/tmethod_various.nim
@@ -1,15 +1,12 @@
 discard """
   matrix: "--mm:arc; --mm:refc"
   output: '''
-do nothing
 HELLO WORLD!
 '''
 """
 
 
-# tmethods1
-method somethin(obj: RootObj) {.base.} =
-  echo "do nothing"
+
 
 type
   TNode* {.inheritable.} = object
@@ -23,8 +20,6 @@ type
 method foo(a: PNode, b: PSomethingElse) {.base.} = discard
 method foo(a: PNodeFoo, b: PSomethingElse) = discard
 
-var o: RootObj
-o.somethin()
 
 
 
diff --git a/tests/method/tmethods_old.nim b/tests/method/tmethods_old.nim
new file mode 100644
index 000000000..cd3f67217
--- /dev/null
+++ b/tests/method/tmethods_old.nim
@@ -0,0 +1,12 @@
+discard """
+  matrix: "--mm:arc -u:nimPreviewVtables"
+  output: '''
+do nothing
+'''
+"""
+
+# tmethods1
+method somethin(obj: RootObj) {.base.} =
+  echo "do nothing"
+var o: RootObj
+o.somethin()
diff --git a/tests/method/tmultim.nim b/tests/method/tmultim.nim
index 126eb7526..bba4d8c5c 100644
--- a/tests/method/tmultim.nim
+++ b/tests/method/tmultim.nim
@@ -1,96 +1,97 @@
-discard """
-  output: '''
-collide: unit, thing
-collide: unit, thing
-collide: thing, unit
-collide: thing, thing
-collide: unit, thing |
-collide: unit, thing |
-collide: thing, unit |
-do nothing
-'''
-  joinable: false
-  disabled: true
-"""
-
-
-# tmultim2
-type
-  TThing {.inheritable.} = object
-  TUnit = object of TThing
-    x: int
-  TParticle = object of TThing
-    a, b: int
-
-method collide(a, b: TThing) {.base, inline.} =
-  echo "collide: thing, thing"
-
-method collide(a: TThing, b: TUnit) {.inline.} =
-  echo "collide: thing, unit"
-
-method collide(a: TUnit, b: TThing) {.inline.} =
-  echo "collide: unit, thing"
-
-proc test(a, b: TThing) {.inline.} =
-  collide(a, b)
-
-proc staticCollide(a, b: TThing) {.inline.} =
-  procCall collide(a, b)
-
-var
-  a: TThing
-  b, c: TUnit
-collide(b, c) # ambiguous (unit, thing) or (thing, unit)? -> prefer unit, thing!
-test(b, c)
-collide(a, b)
-staticCollide(a, b)
-
-
-
-# tmultim6
-type
-  Thing {.inheritable.} = object
-  Unit[T] = object of Thing
-    x: T
-  Particle = object of Thing
-    a, b: int
-
-method collide(a, b: Thing) {.base, inline.} =
-  quit "to override!"
-
-method collide[T](a: Thing, b: Unit[T]) {.inline.} =
-  echo "collide: thing, unit |"
-
-method collide[T](a: Unit[T], b: Thing) {.inline.} =
-  echo "collide: unit, thing |"
-
-proc test(a, b: Thing) {.inline.} =
-  collide(a, b)
-
-var
-  aaa: Thing
-  bbb, ccc: Unit[string]
-collide(bbb, Thing(ccc))
-test(bbb, ccc)
-collide(aaa, bbb)
-
-
-
-# tmethods1
-method somethin(obj: RootObj) {.base.} =
-  echo "do nothing"
-
-type
-  TNode* {.inheritable.} = object
-  PNode* = ref TNode
-
-  PNodeFoo* = ref object of TNode
-
-  TSomethingElse = object
-  PSomethingElse = ref TSomethingElse
-
-method foo(a: PNode, b: PSomethingElse) {.base.} = discard
-method foo(a: PNodeFoo, b: PSomethingElse) = discard
-
-var o: RootObj
-o.somethin()
+discard """

+  matrix: "--multimethods:on"

+  output: '''

+collide: unit, thing

+collide: unit, thing

+collide: thing, unit

+collide: thing, thing

+collide: unit, thing |

+collide: unit, thing |

+collide: thing, unit |

+do nothing

+'''

+  joinable: false

+  disabled: true

+"""

+

+

+# tmultim2

+type

+  TThing {.inheritable.} = object

+  TUnit = object of TThing

+    x: int

+  TParticle = object of TThing

+    a, b: int

+

+method collide(a, b: TThing) {.base, inline.} =

+  echo "collide: thing, thing"

+

+method collide(a: TThing, b: TUnit) {.inline.} =

+  echo "collide: thing, unit"

+

+method collide(a: TUnit, b: TThing) {.inline.} =

+  echo "collide: unit, thing"

+

+proc test(a, b: TThing) {.inline.} =

+  collide(a, b)

+

+proc staticCollide(a, b: TThing) {.inline.} =

+  procCall collide(a, b)

+

+var

+  a: TThing

+  b, c: TUnit

+collide(b, c) # ambiguous (unit, thing) or (thing, unit)? -> prefer unit, thing!

+test(b, c)

+collide(a, b)

+staticCollide(a, b)

+

+

+

+# tmultim6

+type

+  Thing {.inheritable.} = object

+  Unit[T] = object of Thing

+    x: T

+  Particle = object of Thing

+    a, b: int

+

+method collide(a, b: Thing) {.base, inline.} =

+  quit "to override!"

+

+method collide[T](a: Thing, b: Unit[T]) {.inline.} =

+  echo "collide: thing, unit |"

+

+method collide[T](a: Unit[T], b: Thing) {.inline.} =

+  echo "collide: unit, thing |"

+

+proc test(a, b: Thing) {.inline.} =

+  collide(a, b)

+

+var

+  aaa: Thing

+  bbb, ccc: Unit[string]

+collide(bbb, Thing(ccc))

+test(bbb, ccc)

+collide(aaa, bbb)

+

+

+

+# tmethods1

+method somethin(obj: RootObj) {.base.} =

+  echo "do nothing"

+

+type

+  TNode* {.inheritable.} = object

+  PNode* = ref TNode

+

+  PNodeFoo* = ref object of TNode

+

+  TSomethingElse = object

+  PSomethingElse = ref TSomethingElse

+

+method foo(a: PNode, b: PSomethingElse) {.base.} = discard

+method foo(a: PNodeFoo, b: PSomethingElse) = discard

+

+var o: RootObj

+o.somethin()

diff --git a/tests/method/tvtable.nim b/tests/method/tvtable.nim
new file mode 100644
index 000000000..8d98dd42c
--- /dev/null
+++ b/tests/method/tvtable.nim
@@ -0,0 +1,19 @@
+type FooBase = ref object of RootObj

+  dummy: int

+type Foo = ref object of FooBase

+  value : float32

+type Foo2 = ref object of Foo

+  change : float32

+method bar(x: FooBase, a: float32) {.base.} =

+  discard

+method bar(x: Foo, a: float32)  =

+  x.value += a

+method bar(x: Foo2, a: float32)  =

+  x.value += a

+

+

+proc test() =

+  var x = new Foo2

+  x.bar(2.3)

+

+test()
\ No newline at end of file