diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-11-28 22:11:43 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-28 15:11:43 +0100 |
commit | 30cf33f04dfb768182accb3ad35ec6364c998664 (patch) | |
tree | 63dc0d6a36bc662b94246392e03a26b7eaeb116d /tests/method | |
parent | 8cad6ac0487800f7d41e38303e52129777e6c22e (diff) | |
download | Nim-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.cfg | 1 | ||||
-rw-r--r-- | tests/method/tcompilegenerics.nim | 24 | ||||
-rw-r--r-- | tests/method/tgeneric_methods.nim | 84 | ||||
-rw-r--r-- | tests/method/tmethod_various.nim | 7 | ||||
-rw-r--r-- | tests/method/tmethods_old.nim | 12 | ||||
-rw-r--r-- | tests/method/tmultim.nim | 193 | ||||
-rw-r--r-- | tests/method/tvtable.nim | 19 |
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 |