diff options
Diffstat (limited to 'tests/generics')
65 files changed, 1236 insertions, 1276 deletions
diff --git a/tests/generics/t1050.nim b/tests/generics/t1050.nim deleted file mode 100644 index 9e83b5ff0..000000000 --- a/tests/generics/t1050.nim +++ /dev/null @@ -1,29 +0,0 @@ -discard """ - msg: "int" - output: "4" -""" - -import typetraits - -type ArrayType[T] = distinct T - -proc arrayItem(a: ArrayType): auto = - static: echo(name(type(a).T)) - result = (type(a).T)(4) - -var arr: ArrayType[int] -echo arrayItem(arr) - -# bug #5597 - -template fail() = "what" - -proc g[T](x: var T) = - x.fail = 3 - -type - Obj = object - fail: int - -var y: Obj -g y diff --git a/tests/generics/t1056.nim b/tests/generics/t1056.nim deleted file mode 100644 index de8bde8ef..000000000 --- a/tests/generics/t1056.nim +++ /dev/null @@ -1,25 +0,0 @@ -discard """ - output: '''TMatrix[3, 3, system.int] -3''' -""" - -import typetraits - -type - TMatrix*[N,M: static[int], T] = object - data*: array[0..N*M-1, T] - - TMat2[T] = TMatrix[2,2,T] - -proc echoMatrix(a: TMatrix) = - echo a.type.name - echo TMatrix.N - -proc echoMat2(a: TMat2) = - echo TMat2.M - -var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9]) - -echoMatrix m -#echoMat2 m - diff --git a/tests/generics/t1789.nim b/tests/generics/t1789.nim deleted file mode 100644 index c3fe336af..000000000 --- a/tests/generics/t1789.nim +++ /dev/null @@ -1,44 +0,0 @@ -discard """ - output: "3\n0" -""" - -# https://github.com/Araq/Nim/issues/1789 - -type - Foo[N: static[int]] = object - -proc bindStaticN[N](foo: Foo[N]) = - var ar0: array[3, int] - var ar1: array[N, int] - var ar2: array[1..N, int] - var ar3: array[0..(N+10), float] - echo N - -var f: Foo[3] -f.bindStaticN - -# case 2 - -type - ObjectWithStatic[X, Y: static[int], T] = object - bar: array[X * Y, T] # this one works - - AliasWithStatic[X, Y: static[int], T] = array[X * Y, T] - -var - x: ObjectWithStatic[1, 2, int] - y: AliasWithStatic[2, 3, int] - -# case 3 - -type - Bar[N: static[int], T] = object - bar: array[N, T] - -proc `[]`*[N, T](f: Bar[N, T], n: range[0..(N - 1)]): T = - assert high(n) == N-1 - result = f.bar[n] - -var b: Bar[3, int] -echo b[2] - diff --git a/tests/generics/t3977.nim b/tests/generics/t3977.nim deleted file mode 100644 index eed1a7d63..000000000 --- a/tests/generics/t3977.nim +++ /dev/null @@ -1,14 +0,0 @@ -discard """ - output: "42\n42" -""" - -type - Foo[N: static[int]] = object - -proc foo[N](x: Foo[N]) = - let n = N - echo N - echo n - -var f1: Foo[42] -f1.foo diff --git a/tests/generics/t4884.nim b/tests/generics/t4884.nim deleted file mode 100644 index 9a560f649..000000000 --- a/tests/generics/t4884.nim +++ /dev/null @@ -1,11 +0,0 @@ -type - Vec*[N: static[int], T] = object - arr*: array[N, T] - - Mat*[N,M: static[int], T] = object - arr*: array[N, Vec[M,T]] - -var m : Mat[3,3,float] -var strMat : Mat[m.N, m.M, string] -var lenMat : Mat[m.N, m.M, int] - diff --git a/tests/generics/t5570.nim b/tests/generics/t5570.nim deleted file mode 100644 index e3f9ff415..000000000 --- a/tests/generics/t5570.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - nimout: "type uint32\ntype uint32" - output: "(weight: 17.0, color: 100)" -""" - -import macros - -type - BaseFruit[T] = object of RootObj - color: T - - Banana[T] = object of BaseFruit[uint32] - weight: T - -macro printTypeName(typ: typed): untyped = - echo "type ", getType(typ).repr - -proc setColor[K](self: var BaseFruit[K], c: int) = - printTypeName(self.color) - self.color = uint32(c) - -var x: Banana[float64] -x.weight = 17 -printTypeName(x.color) -x.setColor(100) -echo x - diff --git a/tests/generics/t5643.nim b/tests/generics/t5643.nim deleted file mode 100644 index f303bbc70..000000000 --- a/tests/generics/t5643.nim +++ /dev/null @@ -1,30 +0,0 @@ -type - Matrix*[M, N: static[int], T: SomeFloat] = object - data: ref array[N * M, T] - - Matrix64*[M, N: static[int]] = Matrix[M, N, float64] - -proc zeros64(M,N: static[int]): Matrix64[M,N] = - new result.data - for i in 0 .. < (M * N): - result.data[i] = 0'f64 - -proc bar*[M,N: static[int], T](a: Matrix[M,N,T], b: Matrix[M,N,T]) = - discard - -let a = zeros64(2,2) -bar(a,a) - # https://github.com/nim-lang/Nim/issues/5643 - # - # The test case was failing here, because the compiler failed to - # detect the two matrix instantiations as the same type. - # - # The root cause was that the `T` type variable is a different - # type after the first Matrix type has been matched. - # - # Sigmatch was failing to match the second version of `T`, but - # due to some complex interplay between tyOr, tyTypeDesc and - # tyGenericParam this was allowed to went through. The generic - # instantiation of the second matrix was incomplete and the - # generic cache lookup failed, producing two separate types. - diff --git a/tests/generics/t5683.nim b/tests/generics/t5683.nim deleted file mode 100644 index 38da52ec2..000000000 --- a/tests/generics/t5683.nim +++ /dev/null @@ -1,31 +0,0 @@ -discard """ -output: "perm: 22 det: 22" -""" - -type Matrix[M,N: static[int]] = array[M, array[N, float]] - -proc det[M,N](a: Matrix[M,N]): int = N*10 + M -proc perm[M,N](a: Matrix[M,N]): int = M*10 + N - -const - a = [ [1.0, 2.0] - , [3.0, 4.0] - ] - -echo "perm: ", a.perm, " det: ", a.det - -# This tests multiple instantiations of a generic -# proc involving static params: -type - Vector64*[N: static[int]] = ref array[N, float64] - Array64[N: static[int]] = array[N, float64] - -proc vector*[N: static[int]](xs: Array64[N]): Vector64[N] = - new result - for i in 0 .. < N: - result[i] = xs[i] - -let v1 = vector([1.0, 2.0, 3.0, 4.0, 5.0]) -let v2 = vector([1.0, 2.0, 3.0, 4.0, 5.0]) -let v3 = vector([1.0, 2.0, 3.0, 4.0]) - diff --git a/tests/generics/t7794.nim b/tests/generics/t7794.nim deleted file mode 100644 index b295da865..000000000 --- a/tests/generics/t7794.nim +++ /dev/null @@ -1,15 +0,0 @@ -discard """ -output: ''' -10 -2.0 -''' -""" - -type - Data*[T:SomeNumber, U:SomeReal] = ref object - x*: T - value*: U - -var d = Data[int, float64](x:10.int, value:2'f64) -echo d.x -echo d.value diff --git a/tests/generics/t8403.nim b/tests/generics/t8403.nim deleted file mode 100644 index 47ce9c452..000000000 --- a/tests/generics/t8403.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - output: "6.0" -""" - -proc sum*[T](s: seq[T], R: typedesc): R = - var sum: R = 0 - for x in s: - sum += R(x) - return sum - -echo @[1, 2, 3].sum(float) diff --git a/tests/generics/t8439.nim b/tests/generics/t8439.nim deleted file mode 100644 index 69bd7cfcb..000000000 --- a/tests/generics/t8439.nim +++ /dev/null @@ -1,10 +0,0 @@ -discard """ - output: "1" -""" - -type - Cardinal = enum - north, east, south, west - -proc foo[cardinal: static[Cardinal]](): int = 1 -echo(foo[north]()) diff --git a/tests/generics/t8694.nim b/tests/generics/t8694.nim deleted file mode 100644 index dc5c262ee..000000000 --- a/tests/generics/t8694.nim +++ /dev/null @@ -1,31 +0,0 @@ -discard """ - output: ''' -true -true -true -''' -""" - -when true: - # Error: undeclared identifier: '|' - proc bar*[T](t:T): bool = - runnableExamples: - type Foo = int | float - true - echo bar(0) - -when true: - # ok - proc bar*(t:int): bool = - runnableExamples: - type Foo = int | float - true - echo bar(0) - -when true: - # Error: undeclared identifier: '|' - proc bar*(t:typedesc): bool = - runnableExamples: - type Foo = int | float - true - echo bar(int) diff --git a/tests/generics/t88.nim b/tests/generics/t88.nim deleted file mode 100644 index 280a346c5..000000000 --- a/tests/generics/t88.nim +++ /dev/null @@ -1,33 +0,0 @@ -# Issue 88 - -type - BaseClass[V] = object of RootObj - b: V - -proc new[V](t: typedesc[BaseClass], v: V): BaseClass[V] = - BaseClass[V](b: v) - -proc baseMethod[V](v: BaseClass[V]): V = v.b -proc overriddenMethod[V](v: BaseClass[V]): V = v.baseMethod - -type - ChildClass[V] = object of BaseClass[V] - c: V - -proc new[V](t: typedesc[ChildClass], v1, v2: V): ChildClass[V] = - ChildClass[V](b: v1, c: v2) - -proc overriddenMethod[V](v: ChildClass[V]): V = v.c - -let c = ChildClass[string].new("Base", "Child") - -assert c.baseMethod == "Base" -assert c.overriddenMethod == "Child" - - -# bug #4528 -type GenericBase[T] = ref object of RootObj -type GenericSubclass[T] = ref object of GenericBase[T] -proc foo[T](g: GenericBase[T]) = discard -var bar: GenericSubclass[int] -foo(bar) diff --git a/tests/generics/t9130.nim b/tests/generics/t9130.nim deleted file mode 100644 index a993bc6b2..000000000 --- a/tests/generics/t9130.nim +++ /dev/null @@ -1,33 +0,0 @@ -when true: - # stack overflow - template baz1*(iter: untyped): untyped = - runnableExamples: - import sugar - proc fun(a: proc(x:int): int) = discard - baz1(fun(x:int => x)) - discard - - proc foo1[A](ts: A) = - baz1(ts) - -when true: - # ok - template baz2*(iter: untyped): untyped = - runnableExamples: - import sugar - proc fun(a: proc(x:int): int) = discard - baz2(fun(x:int => x)) - discard - - proc foo2(ts: int) = - baz2(ts) - -when true: - # stack overflow - template baz3*(iter: untyped): untyped = - runnableExamples: - baz3(fun(x:int => x)) - discard - - proc foo3[A](ts: A) = - baz3(ts) diff --git a/tests/generics/tableref_is_nil.nim b/tests/generics/tableref_is_nil.nim deleted file mode 100644 index 1ad4b3b0c..000000000 --- a/tests/generics/tableref_is_nil.nim +++ /dev/null @@ -1,9 +0,0 @@ -discard """ - output: "true" -""" - -# bug #2221 -import tables - -var tblo: TableRef[string, int] -echo tblo == nil diff --git a/tests/generics/tarray_with_somenumber.nim b/tests/generics/tarray_with_somenumber.nim deleted file mode 100644 index 0bf2537a1..000000000 --- a/tests/generics/tarray_with_somenumber.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - output: '''@[0.9, 0.1]''' -""" - -# bug #2304 - -type TV2*[T:SomeNumber] = array[0..1, T] -proc newV2T*[T](x, y: T=0): TV2[T] = [x, y] - -let x = newV2T[float](0.9, 0.1) -echo(@x) diff --git a/tests/generics/tbind_bracket.nim b/tests/generics/tbind_bracket.nim deleted file mode 100644 index d0c5e2c6b..000000000 --- a/tests/generics/tbind_bracket.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - output: "317" -""" - -# bug #2599 - -import mbind_bracket - -# also test that `[]` can be passed now as a first class construct: - -template takeBracket(x, a, i: untyped) = - echo x(a, i) - -var a: array[10, int] -a[8] = 317 - -takeBracket(`[]`, a, 8) - -let reg = newRegistry[UUIDObject]() -reg.register(UUIDObject()) diff --git a/tests/generics/tcan.nim b/tests/generics/tcan.nim new file mode 100644 index 000000000..eea69cdb7 --- /dev/null +++ b/tests/generics/tcan.nim @@ -0,0 +1,46 @@ +discard """ + output: ''' +''' +""" + +# Created by Eric Doughty-Papassideris on 2011-02-16. + +block talias_generic: + type + TGen[T] = object + TGen2[T] = TGen[T] + + +block talias_specialised: + type + TGen[T] = object + TSpef = TGen[string] + var s: TSpef + + +block tinherit: + type + TGen[T] = object of RootObj + x, y: T + TSpef[T] = object of TGen[T] + + var s: TSpef[float] + s.x = 0.4 + s.y = 0.6 + + +block tspecialise: + type + TGen[T] = object {.inheritable.} + TSpef = object of TGen[string] + + +block tspecialised_equivalent: + type + TGen[T] = tuple[a: T] + TSpef = tuple[a: string] + + var + a: TGen[string] + b: TSpef + a = b diff --git a/tests/generics/tcan_alias_generic.nim b/tests/generics/tcan_alias_generic.nim deleted file mode 100644 index b357b33e9..000000000 --- a/tests/generics/tcan_alias_generic.nim +++ /dev/null @@ -1,10 +0,0 @@ -## -## can_alias_generic Nim Module -## -## Created by Eric Doughty-Papassideris on 2011-02-16. - -type - TGen[T] = object - TGen2[T] = TGen[T] - - diff --git a/tests/generics/tcan_alias_specialised_generic.nim b/tests/generics/tcan_alias_specialised_generic.nim deleted file mode 100644 index c94edd611..000000000 --- a/tests/generics/tcan_alias_specialised_generic.nim +++ /dev/null @@ -1,16 +0,0 @@ -discard """ - disabled: false -""" - -## -## can_alias_specialised_generic Nim Module -## -## Created by Eric Doughty-Papassideris on 2011-02-16. - -type - TGen[T] = object - TSpef = TGen[string] - -var - s: TSpef - diff --git a/tests/generics/tcan_inherit_generic.nim b/tests/generics/tcan_inherit_generic.nim deleted file mode 100644 index 69e06c4a5..000000000 --- a/tests/generics/tcan_inherit_generic.nim +++ /dev/null @@ -1,16 +0,0 @@ -## -## can_inherit_generic Nim Module -## -## Created by Eric Doughty-Papassideris on 2011-02-16. - -type - TGen[T] = object of RootObj - x, y: T - - TSpef[T] = object of TGen[T] - - -var s: TSpef[float] -s.x = 0.4 -s.y = 0.6 - diff --git a/tests/generics/tcan_specialise_generic.nim b/tests/generics/tcan_specialise_generic.nim deleted file mode 100644 index 78896db38..000000000 --- a/tests/generics/tcan_specialise_generic.nim +++ /dev/null @@ -1,10 +0,0 @@ -## -## can_specialise_generic Nim Module -## -## Created by Eric Doughty-Papassideris on 2011-02-16. - -type - TGen[T] = object {.inheritable.} - TSpef = object of TGen[string] - - diff --git a/tests/generics/tclosed_sym.nim b/tests/generics/tclosed_sym.nim deleted file mode 100644 index ff620c267..000000000 --- a/tests/generics/tclosed_sym.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - output: "TEST2" -""" - -# bug #2664 - -import mclosed_sym - -proc same(r:R, d:int) = echo "TEST1" - -doIt(Data[int](d:123), R()) diff --git a/tests/generics/tconfusing_arrow.nim b/tests/generics/tconfusing_arrow.nim deleted file mode 100644 index f63a874e0..000000000 --- a/tests/generics/tconfusing_arrow.nim +++ /dev/null @@ -1,15 +0,0 @@ -import algorithm, future - -type Deck = object - value: int - -proc sort(h: var seq[Deck]) = - # works: - h.sort(proc (x, y: Deck): auto = - cmp(x.value, y.value)) - # fails: - h.sort((x, y: Deck) => cmp(ord(x.value), ord(y.value))) - -var player: seq[Deck] = @[] - -player.sort() diff --git a/tests/generics/tdictdestruct.nim b/tests/generics/tdictdestruct.nim deleted file mode 100644 index 228d93e66..000000000 --- a/tests/generics/tdictdestruct.nim +++ /dev/null @@ -1,20 +0,0 @@ - -type - TDict[TK, TV] = object - k: TK - v: TV - PDict[TK, TV] = ref TDict[TK, TV] - -proc fakeNew[T](x: var ref T, destroy: proc (a: ref T) {.nimcall.}) = - discard - -proc destroyDict[TK, TV](a: PDict[TK, TV]) = - return -proc newDict[TK, TV](a: TK, b: TV): PDict[TK, TV] = - fakeNew(result, destroyDict[TK, TV]) - -# Problem: destroyDict is not instantiated when newDict is instantiated! - -discard newDict("a", "b") - - diff --git a/tests/generics/tdont_use_inner_scope.nim b/tests/generics/tdont_use_inner_scope.nim deleted file mode 100644 index 45b11fc22..000000000 --- a/tests/generics/tdont_use_inner_scope.nim +++ /dev/null @@ -1,27 +0,0 @@ - -# bug #2752 - -import future, sequtils - -proc myFilter[T](it: (iterator(): T), f: (proc(anything: T):bool)): (iterator(): T) = - iterator aNameWhichWillConflict(): T {.closure.}= - for x in it(): - if f(x): - yield x - result = aNameWhichWillConflict - - -iterator testIt():int {.closure.}= - yield -1 - yield 2 - -#let unusedVariable = myFilter(testIt, (x: int) => x > 0) - -proc onlyPos(it: (iterator(): int)): (iterator(): int)= - iterator aNameWhichWillConflict(): int {.closure.}= - var filtered = onlyPos(myFilter(it, (x:int) => x > 0)) - for x in filtered(): - yield x - result = aNameWhichWillConflict - -let x = onlyPos(testIt) diff --git a/tests/generics/tdotlookup.nim b/tests/generics/tdotlookup.nim deleted file mode 100644 index 17c60ded2..000000000 --- a/tests/generics/tdotlookup.nim +++ /dev/null @@ -1,10 +0,0 @@ -discard """ - output: '''5 5 5 -false''' -""" - -import mdotlookup - -foo(7) -# bug #1444 -fn(4) diff --git a/tests/generics/tfakedependenttypes.nim b/tests/generics/tfakedependenttypes.nim deleted file mode 100644 index cd4be806c..000000000 --- a/tests/generics/tfakedependenttypes.nim +++ /dev/null @@ -1,61 +0,0 @@ -discard """ -output: ''' -U[3] -U[(f: 3)] -U[[3]] -''' -""" - -# https://github.com/nim-lang/Nim/issues/5106 - -import typetraits - -block: - type T = distinct int - - proc `+`(a, b: T): T = - T(int(a) + int(b)) - - type U[F: static[T]] = distinct int - - proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] = - U[P1 + P2](int(a) + int(b)) - - var a = U[T(1)](1) - var b = U[T(2)](2) - var c = a + b - echo c.type.name - -block: - type T = object - f: int - - proc `+`(a, b: T): T = - T(f: a.f + b.f) - - type U[F: static[T]] = distinct int - - proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] = - U[P1 + P2](int(a) + int(b)) - - var a = U[T(f: 1)](1) - var b = U[T(f: 2)](2) - var c = a + b - echo c.type.name - -block: - type T = distinct array[0..0, int] - - proc `+`(a, b: T): T = - T([array[0..0, int](a)[0] + array[0..0, int](b)[0]]) - - type U[F: static[T]] = distinct int - - proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] = - U[P1 + P2](int(a) + int(b)) - - var a = U[T([1])](1) - var b = U[T([2])](2) - var c = a + b - echo c.type.name - diff --git a/tests/generics/tforward_generic.nim b/tests/generics/tforward_generic.nim deleted file mode 100644 index f43e7455f..000000000 --- a/tests/generics/tforward_generic.nim +++ /dev/null @@ -1,28 +0,0 @@ -discard """ - output: '''b() -720 120.0 -720 120.0''' -""" - -# bug #3055 -proc b(t: int | string) -proc a(t: int) = b(t) -proc b(t: int | string) = echo "b()" -a(1) - -# test recursive generics still work: -proc fac[T](x: T): T = - if x == 0: return 1 - else: return fac(x-1)*x - -echo fac(6), " ", fac(5.0) - -# test recursive generic with forwarding: -proc fac2[T](x: T): T - -echo fac2(6), " ", fac2(5.0) - -proc fac2[T](x: T): T = - if x == 0: return 1 - else: return fac2(x-1)*x - diff --git a/tests/generics/tgeneric0.nim b/tests/generics/tgeneric0.nim index a045b32f8..6698ecec0 100644 --- a/tests/generics/tgeneric0.nim +++ b/tests/generics/tgeneric0.nim @@ -1,27 +1,111 @@ +discard """ + output: ''' +100 0 +''' +""" + + import tables -type - TX = Table[string, int] -proc foo(models: seq[Table[string, float]]): seq[float] = - result = @[] - for model in models.items: - result.add model["foobar"] +block tgeneric0: + type + TX = Table[string, int] + + proc foo(models: seq[Table[string, float]]): seq[float] = + result = @[] + for model in models.items: + result.add model["foobar"] + + # bug #686 + type TType[T; A] = array[A, T] + + proc foo[T](p: TType[T, range[0..1]]) = + echo "foo" + proc foo[T](p: TType[T, range[0..2]]) = + echo "bar" + + #bug #1366 + + proc reversed(x: auto) = + for i in countdown(x.low, x.high): + echo i + + reversed(@[-19, 7, -4, 6]) + + + +block tgeneric1: + type + TNode[T] = tuple[priority: int, data: T] + TBinHeap[T] = object + heap: seq[TNode[T]] + last: int + PBinHeap[T] = ref TBinHeap[T] + + proc newBinHeap[T](heap: var PBinHeap[T], size: int) = + new(heap) + heap.last = 0 + newSeq(heap.heap, size) + #newSeq(heap.seq, size) + + proc parent(elem: int): int {.inline.} = + return (elem-1) div 2 + + proc siftUp[T](heap: PBinHeap[T], elem: int) = + var idx = elem + while idx != 0: + var p = parent(idx) + if heap.heap[idx].priority < heap.heap[p].priority: + swap(heap.heap[idx], heap.heap[p]) + idx = p + else: + break + + proc add[T](heap: PBinHeap[T], priority: int, data: T) = + var node: TNode[T] + node.priority = priority + node.data = data + heap.heap[heap.last] = node + siftUp(heap, heap.last) + inc(heap.last) + + proc print[T](heap: PBinHeap[T]) = + for i in countup(0, heap.last): + stdout.write($heap.heap[i].data, " ") + + var heap: PBinHeap[int] + + newBinHeap(heap, 256) + add(heap, 1, 100) + print(heap) + + + +block tgeneric2: + type + TX = Table[string, int] -# bug #686 -type TType[T; A] = array[A, T] + proc foo(models: seq[TX]): seq[int] = + result = @[] + for model in models.items: + result.add model["foobar"] -proc foo[T](p: TType[T, range[0..1]]) = - echo "foo" -proc foo[T](p: TType[T, range[0..2]]) = - echo "bar" + type + Obj = object + field: Table[string, string] + var t: Obj + discard initTable[type(t.field), string]() -#bug #1366 -proc reversed(x: auto) = - for i in countdown(x.low, x.high): - echo i -reversed(@[-19, 7, -4, 6]) +block tgeneric4: + type + TIDGen[A: Ordinal] = object + next: A + free: seq[A] + proc newIDGen[A]: TIDGen[A] = + newSeq result.free, 0 + var x = newIDGen[int]() diff --git a/tests/generics/tgeneric1.nim b/tests/generics/tgeneric1.nim deleted file mode 100644 index 5349f8f1d..000000000 --- a/tests/generics/tgeneric1.nim +++ /dev/null @@ -1,53 +0,0 @@ -discard """ - output: "100 0" -""" - -# A min-heap. -type - TNode[T] = tuple[priority: int, data: T] - - TBinHeap[T] = object - heap: seq[TNode[T]] - last: int - - PBinHeap[T] = ref TBinHeap[T] - -proc newBinHeap*[T](heap: var PBinHeap[T], size: int) = - new(heap) - heap.last = 0 - newSeq(heap.heap, size) - #newSeq(heap.seq, size) - -proc parent(elem: int): int {.inline.} = - return (elem-1) div 2 - -proc siftUp[T](heap: PBinHeap[T], elem: int) = - var idx = elem - while idx != 0: - var p = parent(idx) - if heap.heap[idx].priority < heap.heap[p].priority: - swap(heap.heap[idx], heap.heap[p]) - idx = p - else: - break - -proc add*[T](heap: PBinHeap[T], priority: int, data: T) = - var node: TNode[T] - node.priority = priority - node.data = data - heap.heap[heap.last] = node - siftUp(heap, heap.last) - inc(heap.last) - -proc print*[T](heap: PBinHeap[T]) = - for i in countup(0, heap.last): - stdout.write($heap.heap[i].data, " ") - -var - heap: PBinHeap[int] - -newBinHeap(heap, 256) -add(heap, 1, 100) -print(heap) - - diff --git a/tests/generics/tgeneric2.nim b/tests/generics/tgeneric2.nim deleted file mode 100644 index 21eb4693e..000000000 --- a/tests/generics/tgeneric2.nim +++ /dev/null @@ -1,15 +0,0 @@ -import tables - -type - TX = Table[string, int] - -proc foo(models: seq[TX]): seq[int] = - result = @[] - for model in models.items: - result.add model["foobar"] - -type - Obj = object - field: Table[string, string] -var t: Obj -discard initTable[type(t.field), string]() diff --git a/tests/generics/tgeneric4.nim b/tests/generics/tgeneric4.nim deleted file mode 100644 index f79096636..000000000 --- a/tests/generics/tgeneric4.nim +++ /dev/null @@ -1,10 +0,0 @@ -type - TIDGen*[A: Ordinal] = object - next: A - free: seq[A] - -proc newIDGen*[A]: TIDGen[A] = - newSeq result.free, 0 - -var x = newIDGen[int]() - diff --git a/tests/generics/tgeneric_closure.nim b/tests/generics/tgeneric_closure.nim deleted file mode 100644 index 8dcd677fd..000000000 --- a/tests/generics/tgeneric_closure.nim +++ /dev/null @@ -1,37 +0,0 @@ -# Test to ensure TEventHandler is '.closure' - -# bug #1187 - -type - TEventArgs* = object - skip*: bool - TEventHandler[T] = proc (e: var TEventArgs, data: T) {.closure.} - TEvent*[T] = object - #handlers: seq[TEventHandler[T]] # Does not work - handlers: seq[proc (e: var TEventArgs, d: T) {.closure.}] # works - - TData = object - x: int - - TSomething = object - s: TEvent[TData] - -proc init*[T](e: var TEvent[T]) = - e.handlers.newSeq(0) - -#proc add*[T](e: var TEvent[T], h: proc (e: var TEventArgs, data: T) {.closure.}) = -# this line works -proc add*[T](e: var TEvent[T], h: TEventHandler[T]) = - # this line does not work - e.handlers.add(h) - -proc main () = - var something: TSomething - something.s.init() - var fromOutside = 4711 - - something.s.add() do (e: var TEventArgs, data: TData): - var x = data.x - x = fromOutside - -main() diff --git a/tests/generics/tgeneric_inheritance.nim b/tests/generics/tgeneric_inheritance.nim deleted file mode 100644 index 432228797..000000000 --- a/tests/generics/tgeneric_inheritance.nim +++ /dev/null @@ -1,19 +0,0 @@ -discard """ - output: "0.0" -""" - -# bug #1919 - -type - Base[M] = object of RootObj - a : M - - Sub1[M] = object of Base[M] - b : int - - Sub2[M] = object of Sub1[M] - c : int - -var x: Sub2[float] - -echo x.a diff --git a/tests/generics/tgenericconst.nim b/tests/generics/tgenericconst.nim deleted file mode 100644 index 3c86888df..000000000 --- a/tests/generics/tgenericconst.nim +++ /dev/null @@ -1,39 +0,0 @@ -discard """ -output: ''' -@[1, 2] -@[3, 4] -1 -''' -""" - -# https://github.com/nim-lang/Nim/issues/5756 - -type - Vec*[N : static[int]] = object - x: int - arr*: array[N, int32] - - Mat*[M,N: static[int]] = object - x: int - arr*: array[M, Vec[N]] - -proc vec2*(x,y:int32) : Vec[2] = - result.arr = [x,y] - result.x = 10 - -proc mat2*(a,b: Vec[2]): Mat[2,2] = - result.arr = [a,b] - result.x = 20 - -const M = mat2(vec2(1, 2), vec2(3, 4)) - -let m1 = M -echo @(m1.arr[0].arr) -echo @(m1.arr[1].arr) - -proc foo = - let m2 = M - echo m1.arr[0].arr[0] - -foo() - diff --git a/tests/generics/tgenericdefaults.nim b/tests/generics/tgenericdefaults.nim deleted file mode 100644 index a4c90a884..000000000 --- a/tests/generics/tgenericdefaults.nim +++ /dev/null @@ -1,29 +0,0 @@ -type - TFoo[T, U, R = int] = object - x: T - y: U - z: R - - TBar[T] = TFoo[T, array[4, T], T] - -var x1: TFoo[int, float] - -static: - assert type(x1.x) is int - assert type(x1.y) is float - assert type(x1.z) is int - -var x2: TFoo[string, R = float, U = seq[int]] - -static: - assert type(x2.x) is string - assert type(x2.y) is seq[int] - assert type(x2.z) is float - -var x3: TBar[float] - -static: - assert type(x3.x) is float - assert type(x3.y) is array[4, float] - assert type(x3.z) is float - diff --git a/tests/generics/tgenericmatcher.nim b/tests/generics/tgenericmatcher.nim index 2edf46187..ca4dc2a4d 100644 --- a/tests/generics/tgenericmatcher.nim +++ b/tests/generics/tgenericmatcher.nim @@ -1,22 +1,40 @@ discard """ - disabled: false + output: ''' +''' """ -type - TMatcherKind = enum - mkTerminal, mkSequence, mkAlternation, mkRepeat - TMatcher[T] = object - case kind: TMatcherKind - of mkTerminal: - value: T - of mkSequence, mkAlternation: - matchers: seq[TMatcher[T]] - of mkRepeat: - matcher: PMatcher[T] - min, max: int - PMatcher[T] = ref TMatcher[T] -var - m: PMatcher[int] +block tmatcher1: + type + TMatcherKind = enum + mkTerminal, mkSequence, mkAlternation, mkRepeat + TMatcher[T] = object + case kind: TMatcherKind + of mkTerminal: + value: T + of mkSequence, mkAlternation: + matchers: seq[TMatcher[T]] + of mkRepeat: + matcher: PMatcher[T] + min, max: int + PMatcher[T] = ref TMatcher[T] + var m: PMatcher[int] + + +block tmatcher2: + type + TMatcherKind = enum + mkTerminal, mkSequence, mkAlternation, mkRepeat + TMatcher[T] = object + case kind: TMatcherKind + of mkTerminal: + value: T + of mkSequence, mkAlternation: + matchers: seq[TMatcher[T]] + of mkRepeat: + matcher: ref TMatcher[T] + min, max: int + + var m: ref TMatcher[int] diff --git a/tests/generics/tgenericmatcher2.nim b/tests/generics/tgenericmatcher2.nim deleted file mode 100644 index 6832f80b7..000000000 --- a/tests/generics/tgenericmatcher2.nim +++ /dev/null @@ -1,18 +0,0 @@ - -type - TMatcherKind = enum - mkTerminal, mkSequence, mkAlternation, mkRepeat - TMatcher[T] = object - case kind: TMatcherKind - of mkTerminal: - value: T - of mkSequence, mkAlternation: - matchers: seq[TMatcher[T]] - of mkRepeat: - matcher: ref TMatcher[T] - min, max: int - -var - m: ref TMatcher[int] - - diff --git a/tests/generics/tgenericprop.nim b/tests/generics/tgenericprop.nim deleted file mode 100644 index 21ffdf289..000000000 --- a/tests/generics/tgenericprop.nim +++ /dev/null @@ -1,12 +0,0 @@ - -type - TProperty[T] = object of RootObj - getProc: proc(property: TProperty[T]): T {.nimcall.} - setProc: proc(property: TProperty[T], value: T) {.nimcall.} - value: T - -proc newProperty[T](value: RootObj): TProperty[T] = - result.getProc = proc (property: TProperty[T]) = - return property.value - - diff --git a/tests/generics/tgenericrefs.nim b/tests/generics/tgenericrefs.nim deleted file mode 100644 index 245789caf..000000000 --- a/tests/generics/tgenericrefs.nim +++ /dev/null @@ -1,38 +0,0 @@ -type - PA[T] = ref TA[T] - TA[T] = object - field: T -var a: PA[string] -new(a) -a.field = "some string" - - -proc someOther[T](len: string): seq[T] = discard -proc someOther[T](len: int): seq[T] = echo "we" - -proc foo[T](x: T) = - var s = someOther[T](34) - #newSeq[T](34) - -foo 23 - - - -when false: - # Compiles unless you use var a: PA[string] - type - PA = ref TA - TA[T] = object - - - # Cannot instantiate: - type - TA[T] = object - a: PA[T] - PA[T] = ref TA[T] - - type - PA[T] = ref TA[T] - TA[T] = object - - diff --git a/tests/generics/tgenerics_and_inheritance.nim b/tests/generics/tgenerics_and_inheritance.nim deleted file mode 100644 index ea776b517..000000000 --- a/tests/generics/tgenerics_and_inheritance.nim +++ /dev/null @@ -1,36 +0,0 @@ - -# bug #7854 - -type - Stream* = ref StreamObj - StreamObj* = object of RootObj - - InhStream* = ref InhStreamObj - InhStreamObj* = object of Stream - f: string - -proc newInhStream*(f: string): InhStream = - new(result) - result.f = f - -var val: int -let str = newInhStream("input_file.json") - -block: - # works: - proc load[T](data: var T, s: Stream) = - discard - load(val, str) - -block: - # works - proc load[T](s: Stream, data: T) = - discard - load(str, val) - -block: - # broken - proc load[T](s: Stream, data: var T) = - discard - load(str, val) - diff --git a/tests/generics/tgenericsdefaultvalues.nim b/tests/generics/tgenericsdefaultvalues.nim deleted file mode 100644 index 2604c1031..000000000 --- a/tests/generics/tgenericsdefaultvalues.nim +++ /dev/null @@ -1,14 +0,0 @@ -discard """ -output: "12" -""" - -# https://github.com/nim-lang/Nim/issues/5864 - -proc defaultStatic(s: openarray, N: static[int] = 1): int = N -proc defaultGeneric[T](a: T = 2): int = a - -let a = [1, 2, 3, 4].defaultStatic() -let b = defaultGeneric() - -echo a, b - diff --git a/tests/generics/tgenericshardcases.nim b/tests/generics/tgenericshardcases.nim deleted file mode 100644 index 72a2f4ec2..000000000 --- a/tests/generics/tgenericshardcases.nim +++ /dev/null @@ -1,42 +0,0 @@ -discard """ - file: "tgenericshardcases.nim" - output: "2\n5\n126\n3" -""" - -import typetraits - -proc typeNameLen(x: typedesc): int {.compileTime.} = - result = x.name.len - -macro selectType(a, b: typedesc): typedesc = - result = a - -type - Foo[T] = object - data1: array[T.high, int] - data2: array[typeNameLen(T), float] - data3: array[0..T.typeNameLen, selectType(float, int)] - - MyEnum = enum A, B, C, D - -var f1: Foo[MyEnum] -var f2: Foo[int8] - -echo high(f1.data1) # (D = 3) - 1 == 2 -echo high(f1.data2) # (MyEnum.len = 6) - 1 == 5 - -echo high(f2.data1) # 127 - 1 == 126 -echo high(f2.data2) # int8.len - 1 == 3 - -static: - assert high(f1.data1) == ord(C) - assert high(f1.data2) == 5 # length of MyEnum minus one, because we used T.high - - assert high(f2.data1) == 126 - assert high(f2.data2) == 3 - - assert high(f1.data3) == 6 # length of MyEnum - assert high(f2.data3) == 4 # length of int8 - - assert f2.data3[0] is float - diff --git a/tests/generics/tgenerictmpl.nim b/tests/generics/tgenerictmpl.nim deleted file mode 100644 index e18f020c2..000000000 --- a/tests/generics/tgenerictmpl.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - output: '''0 -123''' -""" - -# bug #3498 - -template defaultOf[T](t: T): untyped = (var d: T; d) - -echo defaultOf(1) #<- excpected 0 - -# assignment using template - -template tassign[T](x: var seq[T]) = - x = @[1, 2, 3] - -var y: seq[int] -tassign(y) #<- x is expected = @[1, 2, 3] -tassign(y) - -echo y[0], y[1], y[2] diff --git a/tests/generics/timports.nim b/tests/generics/timports.nim new file mode 100644 index 000000000..800ae7f88 --- /dev/null +++ b/tests/generics/timports.nim @@ -0,0 +1,45 @@ +discard """ + output: ''' +317 +TEST2 +5 5 5 +false +''' +""" + +import mbind_bracket, mclosed_sym, mdotlookup, mmodule_same_as_proc + + +block tbind_bracket: + # bug #2599 + # also test that `[]` can be passed now as a first class construct: + + template takeBracket(x, a, i: untyped) = + echo x(a, i) + + var a: array[10, int] + a[8] = 317 + + takeBracket(`[]`, a, 8) + + let reg = newRegistry[UUIDObject]() + reg.register(UUIDObject()) + + +block tclosed_sym: + # bug #2664 + proc same(r:R, d:int) = echo "TEST1" + doIt(Data[int](d:123), R()) + + +block tdotlookup: + foo(7) + # bug #1444 + fn(4) + + +block tmodule_same_as_proc: + # bug #1965 + proc test[T](t: T) = + mmodule_same_as_proc"a" + test(0) diff --git a/tests/generics/tinferredgenericprocs.nim b/tests/generics/tinferredgenericprocs.nim deleted file mode 100644 index 359c71ba8..000000000 --- a/tests/generics/tinferredgenericprocs.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - output: '''123 -1 -2 -3''' -""" - -import sequtils -# https://github.com/Araq/Nim/issues/797 -proc foo[T](s:T):string = $s - -type IntStringProc = proc(x: int): string - -var f1 = IntStringProc(foo) -var f2: proc(x: int): string = foo -var f3: IntStringProc = foo - -echo f1(1), f2(2), f3(3) - -for x in map([1,2,3], foo): echo x - diff --git a/tests/generics/tissues.nim b/tests/generics/tissues.nim new file mode 100644 index 000000000..e958549d6 --- /dev/null +++ b/tests/generics/tissues.nim @@ -0,0 +1,765 @@ +discard """ + output: ''' +4 +3 +(weight: 17.0, color: 100) +perm: 22 det: 22 +TMatrix[3, 3, system.int] +3 +@[0.9, 0.1] +U[3] +U[(f: 3)] +U[[3]] +b() +@[1, 2] +@[3, 4] +1 +concrete 88 +123 +1 +2 +3 +!!Hi!! +G:0,1:0.1 +G:0,1:0.1 +H:1:0.1 +''' +""" + + +import macros, sequtils, sets, sugar, tables, typetraits + + +block t88: + type + BaseClass[V] = object of RootObj + b: V + + proc new[V](t: typedesc[BaseClass], v: V): BaseClass[V] = + BaseClass[V](b: v) + + proc baseMethod[V](v: BaseClass[V]): V = v.b + proc overriddenMethod[V](v: BaseClass[V]): V = v.baseMethod + + type + ChildClass[V] = object of BaseClass[V] + c: V + + proc new[V](t: typedesc[ChildClass], v1, v2: V): ChildClass[V] = + ChildClass[V](b: v1, c: v2) + + proc overriddenMethod[V](v: ChildClass[V]): V = v.c + + let c = ChildClass[string].new("Base", "Child") + + assert c.baseMethod == "Base" + assert c.overriddenMethod == "Child" + + + +block t4528: + type GenericBase[T] = ref object of RootObj + type GenericSubclass[T] = ref object of GenericBase[T] + proc foo[T](g: GenericBase[T]) = discard + var bar: GenericSubclass[int] + foo(bar) + + + +block t1050_5597: + type ArrayType[T] = distinct T + + proc arrayItem(a: ArrayType): auto = + static: echo(name(type(a).T)) + result = (type(a).T)(4) + + var arr: ArrayType[int] + echo arrayItem(arr) + + # bug #5597 + + template fail() = "what" + + proc g[T](x: var T) = + x.fail = 3 + + type + Obj = object + fail: int + + var y: Obj + g y + + + +block t1789: + type + Foo[N: static[int]] = object + + proc bindStaticN[N](foo: Foo[N]) = + var ar0: array[3, int] + var ar1: array[N, int] + var ar2: array[1..N, int] + var ar3: array[0..(N+10), float] + echo N + + var f: Foo[3] + f.bindStaticN + + # case 2 + + type + ObjectWithStatic[X, Y: static[int], T] = object + bar: array[X * Y, T] # this one works + + AliasWithStatic[X, Y: static[int], T] = array[X * Y, T] + + var + x: ObjectWithStatic[1, 2, int] + y: AliasWithStatic[2, 3, int] + + # case 3 + + type + Bar[N: static[int], T] = object + bar: array[N, T] + + proc `[]`[N, T](f: Bar[N, T], n: range[0..(N - 1)]): T = + assert high(n) == N-1 + result = f.bar[n] + + var b: Bar[3, int] + doAssert b[2] == 0 + + + +block t3977: + type Foo[N: static[int]] = object + + proc foo[N](x: Foo[N]) = + let n = N + doAssert N == n + + var f1: Foo[42] + f1.foo + + + +block t5570: + type + BaseFruit[T] = object of RootObj + color: T + + Banana[T] = object of BaseFruit[uint32] + weight: T + + macro printTypeName(typ: typed): untyped = + echo "type ", getType(typ).repr + + proc setColor[K](self: var BaseFruit[K], c: int) = + printTypeName(self.color) + self.color = uint32(c) + + var x: Banana[float64] + x.weight = 17 + printTypeName(x.color) + x.setColor(100) + echo x + + + +block t5643: + type + Matrix[M, N: static[int], T: SomeFloat] = object + data: ref array[N * M, T] + Matrix64[M, N: static[int]] = Matrix[M, N, float64] + + proc zeros64(M,N: static[int]): Matrix64[M,N] = + new result.data + for i in 0 ..< (M * N): + result.data[i] = 0'f64 + + proc bar[M,N: static[int], T](a: Matrix[M,N,T], b: Matrix[M,N,T]) = + discard + + let a = zeros64(2,2) + bar(a,a) + # https://github.com/nim-lang/Nim/issues/5643 + # + # The test case was failing here, because the compiler failed to + # detect the two matrix instantiations as the same type. + # + # The root cause was that the `T` type variable is a different + # type after the first Matrix type has been matched. + # + # Sigmatch was failing to match the second version of `T`, but + # due to some complex interplay between tyOr, tyTypeDesc and + # tyGenericParam this was allowed to went through. The generic + # instantiation of the second matrix was incomplete and the + # generic cache lookup failed, producing two separate types. + + + +block t5683: + type Matrix[M,N: static[int]] = array[M, array[N, float]] + + proc det[M,N](a: Matrix[M,N]): int = N*10 + M + proc perm[M,N](a: Matrix[M,N]): int = M*10 + N + + const + a = [ [1.0, 2.0] + , [3.0, 4.0] + ] + + echo "perm: ", a.perm, " det: ", a.det + + # This tests multiple instantiations of a generic + # proc involving static params: + type + Vector64[N: static[int]] = ref array[N, float64] + Array64[N: static[int]] = array[N, float64] + + proc vector[N: static[int]](xs: Array64[N]): Vector64[N] = + new result + for i in 0 ..< N: + result[i] = xs[i] + + let v1 = vector([1.0, 2.0, 3.0, 4.0, 5.0]) + let v2 = vector([1.0, 2.0, 3.0, 4.0, 5.0]) + let v3 = vector([1.0, 2.0, 3.0, 4.0]) + + + +block t7794: + type + Data[T:SomeNumber, U:SomeFloat] = ref object + x: T + value*: U + + var d = Data[int, float64](x:10.int, value:2'f64) + doAssert d.x == 10 + doAssert d.value == 2.0 + + + +block t8403: + proc sum[T](s: seq[T], R: typedesc): R = + var sum: R = 0 + for x in s: + sum += R(x) + return sum + + doAssert @[1, 2, 3].sum(float) == 6.0 + + + +block t8439: + type + Cardinal = enum + north, east, south, west + + proc foo[cardinal: static[Cardinal]](): int = 1 + doAssert foo[north]() == 1 + + + +block t8694: + when true: + # Error: undeclared identifier: '|' + proc bar[T](t:T): bool = + runnableExamples: + type Foo = int | float + true + doAssert bar(0) + + when true: + # ok + proc bar(t:int): bool = + runnableExamples: + type Foo = int | float + true + doAssert bar(0) + + when true: + # Error: undeclared identifier: '|' + proc bar(t:typedesc): bool = + runnableExamples: + type Foo = int | float + true + doAssert bar(int) + + + +block t9130: + when true: + # stack overflow + template baz1(iter: untyped): untyped = + runnableExamples: + import sugar + proc fun(a: proc(x:int): int) = discard + baz1(fun(x:int => x)) + discard + + proc foo1[A](ts: A) = + baz1(ts) + + when true: + # ok + template baz2(iter: untyped): untyped = + runnableExamples: + import sugar + proc fun(a: proc(x:int): int) = discard + baz2(fun(x:int => x)) + discard + + proc foo2(ts: int) = + baz2(ts) + + when true: + # stack overflow + template baz3(iter: untyped): untyped = + runnableExamples: + baz3(fun(x:int => x)) + discard + + proc foo3[A](ts: A) = + baz3(ts) + + + +block t1056: + type + TMatrix[N,M: static[int], T] = object + data: array[0..N*M-1, T] + + TMat2[T] = TMatrix[2,2,T] + + proc echoMatrix(a: TMatrix) = + echo a.type.name + echo TMatrix.N + + proc echoMat2(a: TMat2) = + echo TMat2.M + + var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9]) + + echoMatrix m + + + +block t4884: + type + Vec[N: static[int], T] = object + arr*: array[N, T] + + Mat[N,M: static[int], T] = object + arr: array[N, Vec[M,T]] + + var m : Mat[3,3,float] + var strMat : Mat[m.N, m.M, string] + var lenMat : Mat[m.N, m.M, int] + + + +block t2221: + var tblo: TableRef[string, int] + doAssert tblo == nil + + + +block t2304: + type TV2[T:SomeNumber] = array[0..1, T] + proc newV2T[T](x, y: T=0): TV2[T] = [x, y] + + let x = newV2T[float](0.9, 0.1) + echo(@x) + + + +block t2752: + proc myFilter[T](it: (iterator(): T), f: (proc(anything: T):bool)): (iterator(): T) = + iterator aNameWhichWillConflict(): T {.closure.}= + for x in it(): + if f(x): + yield x + result = aNameWhichWillConflict + + iterator testIt():int {.closure.}= + yield -1 + yield 2 + + #let unusedVariable = myFilter(testIt, (x: int) => x > 0) + + proc onlyPos(it: (iterator(): int)): (iterator(): int)= + iterator aNameWhichWillConflict(): int {.closure.}= + var filtered = onlyPos(myFilter(it, (x:int) => x > 0)) + for x in filtered(): + yield x + result = aNameWhichWillConflict + + let x = onlyPos(testIt) + + + +block t5106: + block: + type T = distinct int + + proc `+`(a, b: T): T = + T(int(a) + int(b)) + + type U[F: static[T]] = distinct int + + proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] = + U[P1 + P2](int(a) + int(b)) + + var a = U[T(1)](1) + var b = U[T(2)](2) + var c = a + b + echo c.type.name + + block: + type T = object + f: int + + proc `+`(a, b: T): T = + T(f: a.f + b.f) + + type U[F: static[T]] = distinct int + + proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] = + U[P1 + P2](int(a) + int(b)) + + var a = U[T(f: 1)](1) + var b = U[T(f: 2)](2) + var c = a + b + echo c.type.name + + block: + type T = distinct array[0..0, int] + + proc `+`(a, b: T): T = + T([array[0..0, int](a)[0] + array[0..0, int](b)[0]]) + + type U[F: static[T]] = distinct int + + proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] = + U[P1 + P2](int(a) + int(b)) + + var a = U[T([1])](1) + var b = U[T([2])](2) + var c = a + b + echo c.type.name + + + +block t3055: + proc b(t: int | string) + proc a(t: int) = b(t) + proc b(t: int | string) = echo "b()" + a(1) + + # test recursive generics still work: + proc fac[T](x: T): T = + if x == 0: return 1 + else: return fac(x-1)*x + + doAssert fac(6) == 720 + doAssert fac(5.0) == 120.0 + + + # test recursive generic with forwarding: + proc fac2[T](x: T): T + + doAssert fac2(6) == 720 + doAssert fac2(5.0) == 120.0 + + proc fac2[T](x: T): T = + if x == 0: return 1 + else: return fac2(x-1)*x + + + +block t1187: + type + TEventArgs = object + skip: bool + TEventHandler[T] = proc (e: var TEventArgs, data: T) {.closure.} + TEvent[T] = object + #handlers: seq[TEventHandler[T]] # Does not work + handlers: seq[proc (e: var TEventArgs, d: T) {.closure.}] # works + + TData = object + x: int + + TSomething = object + s: TEvent[TData] + + proc init[T](e: var TEvent[T]) = + e.handlers.newSeq(0) + + #proc add*[T](e: var TEvent[T], h: proc (e: var TEventArgs, data: T) {.closure.}) = + # this line works + proc add[T](e: var TEvent[T], h: TEventHandler[T]) = + # this line does not work + e.handlers.add(h) + + proc main () = + var something: TSomething + something.s.init() + var fromOutside = 4711 + + something.s.add() do (e: var TEventArgs, data: TData): + var x = data.x + x = fromOutside + + main() + + + +block t1919: + type + Base[M] = object of RootObj + a : M + Sub1[M] = object of Base[M] + b : int + Sub2[M] = object of Sub1[M] + c : int + + var x: Sub2[float] + doAssert x.a == 0.0 + + + +block t5756: + type + Vec[N : static[int]] = object + x: int + arr: array[N, int32] + + Mat[M,N: static[int]] = object + x: int + arr: array[M, Vec[N]] + + proc vec2(x,y:int32) : Vec[2] = + result.arr = [x,y] + result.x = 10 + + proc mat2(a,b: Vec[2]): Mat[2,2] = + result.arr = [a,b] + result.x = 20 + + const M = mat2(vec2(1, 2), vec2(3, 4)) + + let m1 = M + echo @(m1.arr[0].arr) + echo @(m1.arr[1].arr) + + proc foo = + let m2 = M + echo m1.arr[0].arr[0] + + foo() + + + +block t7854: + type + Stream = ref StreamObj + StreamObj = object of RootObj + + InhStream = ref InhStreamObj + InhStreamObj = object of Stream + f: string + + proc newInhStream(f: string): InhStream = + new(result) + result.f = f + + var val: int + let str = newInhStream("input_file.json") + + block: + # works: + proc load[T](data: var T, s: Stream) = + discard + load(val, str) + + block: + # works + proc load[T](s: Stream, data: T) = + discard + load(str, val) + + block: + # broken + proc load[T](s: Stream, data: var T) = + discard + load(str, val) + + + +block t5864: + proc defaultStatic(s: openarray, N: static[int] = 1): int = N + proc defaultGeneric[T](a: T = 2): int = a + + let a = [1, 2, 3, 4].defaultStatic() + let b = defaultGeneric() + + doAssert a == 1 + doAssert b == 2 + + + +block t3498: + template defaultOf[T](t: T): untyped = (var d: T; d) + + doAssert defaultOf(1) == 0 + + # assignment using template + + template tassign[T](x: var seq[T]) = + x = @[1, 2, 3] + + var y: seq[int] + tassign(y) #<- x is expected = @[1, 2, 3] + tassign(y) + + doAssert y[0] == 1 + doAssert y[1] == 2 + doAssert y[2] == 3 + + + +block t3499: + proc foo[T](x: proc(): T) = + echo "generic ", x() + + proc foo(x: proc(): int) = + echo "concrete ", x() + + # note the following 'proc' is not .closure! + foo(proc (): auto {.nimcall.} = 88) + + # bug #3499 last snippet fixed + # bug 705 last snippet fixed + + + + +block t797: + proc foo[T](s:T):string = $s + + type IntStringProc = proc(x: int): string + + var f1 = IntStringProc(foo) + var f2: proc(x: int): string = foo + var f3: IntStringProc = foo + + echo f1(1), f2(2), f3(3) + + for x in map([1,2,3], foo): echo x + + + +block t4658: + var x = 123 + proc twice[T](f: T -> T): T -> T = (x: T) => f(f(x)) + proc quote(s: string): string = "!" & s & "!" + echo twice(quote)("Hi") + + + +block t4589: + type SimpleTable[TKey, TVal] = TableRef[TKey, TVal] + template newSimpleTable(TKey, TVal: typedesc): SimpleTable[TKey, TVal] = newTable[TKey, TVal]() + var fontCache : SimpleTable[string, SimpleTable[int32, int]] + fontCache = newSimpleTable(string, SimpleTable[int32, int]) + + + +block t4600: + template foo(x: untyped): untyped = echo 1 + template foo(x,y: untyped): untyped = echo 2 + + proc bar1[T](x: T) = foo(x) + proc bar2(x: float) = foo(x,x) + proc bar3[T](x: T) = foo(x,x) + + + +block t4672: + type + EnumContainer[T: enum] = object + v: T + SomeEnum {.pure.} = enum + A,B,C + + proc value[T: enum](this: EnumContainer[T]): T = + this.v + + var enumContainer: EnumContainer[SomeEnum] + discard enumContainer.value() + + + +block t4863: + type + G[i,j: static[int]] = object + v:float + H[j: static[int]] = G[0,j] + proc p[i,j: static[int]](x:G[i,j]) = echo "G:", i, ",", j, ":", x.v + proc q[j: static[int]](x:H[j]) = echo "H:", j, ":", x.v + + var + g0 = G[0,1](v: 0.1) + h0:H[1] = g0 + p(g0) + p(h0) + q(h0) + + + +block t1684: + type + BaseType {.inheritable pure.} = object + idx: int + + DerivedType {.final pure.} = object of BaseType + + proc index[Toohoo: BaseType](h: Toohoo): int {.inline.} = h.idx + proc newDerived(idx: int): DerivedType {.inline.} = DerivedType(idx: idx) + + let d = newDerived(2) + assert(d.index == 2) + + + +block t5632: + type Option[T] = object + + proc point[A](v: A, t: typedesc[Option[A]]): Option[A] = + discard + + discard point(1, Option) + + + +block t7247: + type n8 = range[0'i8..127'i8] + var tab = initSet[n8]() + doAssert tab.contains(8) == false + + + +block t3717: + type + Foo[T] = object + a: T + Foo1[T] = Foo[T] | int + + proc foo[T](s: Foo1[Foo[T]]): T = + 5 + + var f: Foo[Foo[int]] + discard foo(f) diff --git a/tests/generics/tlamba_in_generic.nim b/tests/generics/tlamba_in_generic.nim deleted file mode 100644 index 91d417b5e..000000000 --- a/tests/generics/tlamba_in_generic.nim +++ /dev/null @@ -1,13 +0,0 @@ -discard """ - output: '''!!Hi!!''' -""" -# bug #4658 -import future - -var x = 123 - -proc twice[T](f: T -> T): T -> T = (x: T) => f(f(x)) - -proc quote(s: string): string = "!" & s & "!" - -echo twice(quote)("Hi") diff --git a/tests/generics/tmap_auto.nim b/tests/generics/tmap_auto.nim deleted file mode 100644 index 572556722..000000000 --- a/tests/generics/tmap_auto.nim +++ /dev/null @@ -1,13 +0,0 @@ -import future, sequtils - -let x = map(@[1, 2, 3], x => x+10) -assert x == @[11, 12, 13] - -let y = map(@[(1,"a"), (2,"b"), (3,"c")], x => $x[0] & x[1]) -assert y == @["1a", "2b", "3c"] - -proc eatsTwoArgProc[T,S,U](a: T, b: S, f: proc(t: T, s: S): U): U = - f(a,b) - -let z = eatsTwoArgProc(1, "a", (t,s) => $t & s) -assert z == "1a" diff --git a/tests/generics/tmodule_same_as_proc.nim b/tests/generics/tmodule_same_as_proc.nim deleted file mode 100644 index 113ca1bc3..000000000 --- a/tests/generics/tmodule_same_as_proc.nim +++ /dev/null @@ -1,9 +0,0 @@ - -# bug #1965 - -import mmodule_same_as_proc - -proc test[T](t: T) = - mmodule_same_as_proc"a" - -test(0) diff --git a/tests/generics/tobjecttyperel3.nim b/tests/generics/tobjecttyperel3.nim deleted file mode 100644 index 3d8079e28..000000000 --- a/tests/generics/tobjecttyperel3.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - output: '''OK''' -""" -#bug #5632 -type - Option*[T] = object - -proc point*[A](v: A, t: typedesc[Option[A]]): Option[A] = - discard - -discard point(1, Option) -echo "OK" \ No newline at end of file diff --git a/tests/generics/tproctypecache_falsepositive.nim b/tests/generics/tproctypecache_falsepositive.nim deleted file mode 100644 index 4f24a1fc8..000000000 --- a/tests/generics/tproctypecache_falsepositive.nim +++ /dev/null @@ -1,17 +0,0 @@ - -import asyncdispatch - -type - Callback = proc() {.closure, gcsafe.} - GameState = ref object - playerChangeHandlers: seq[Callback] - -#proc dummy() = -# var x = newSeq[proc() {.cdecl, gcsafe.}]() - -proc newGameState(): GameState = - result = GameState( - playerChangeHandlers: newSeq[Callback]() # this fails - ) - -#dummy() diff --git a/tests/generics/tptrinheritance.nim b/tests/generics/tptrinheritance.nim deleted file mode 100644 index 221b8777b..000000000 --- a/tests/generics/tptrinheritance.nim +++ /dev/null @@ -1,20 +0,0 @@ -type NSPasteboardItem* = ptr object -type NSPasteboard* = ptr object -type NSArrayAbstract = ptr object {.inheritable.} -type NSMutableArrayAbstract = ptr object of NSArrayAbstract -type NSArray*[T] = ptr object of NSArrayAbstract -type NSMutableArray*[T] = ptr object of NSArray[T] - -proc newMutableArrayAbstract*(): NSMutableArrayAbstract = discard - -template newMutableArray*(T: typedesc): NSMutableArray[T] = - cast[NSMutableArray[T]](newMutableArrayAbstract()) - -proc writeObjects*(p: NSPasteboard, o: NSArray[NSPasteboardItem]) = discard - -let a = newMutableArray NSPasteboardItem -var x: NSMutableArray[NSPasteboardItem] -var y: NSArray[NSPasteboardItem] = x - -writeObjects(nil, a) - diff --git a/tests/generics/tsigtypeop.nim b/tests/generics/tsigtypeop.nim deleted file mode 100644 index 4c863cba1..000000000 --- a/tests/generics/tsigtypeop.nim +++ /dev/null @@ -1,9 +0,0 @@ -type - Vec3[T] = array[3, T] - -proc foo(x: Vec3, y: Vec3.T, z: x.T): x.type.T = - return 10 - -var y: Vec3[int] = [1, 2, 3] -var z: int = foo(y, 3, 4) - diff --git a/tests/generics/tspecial_numeric_inference.nim b/tests/generics/tspecial_numeric_inference.nim deleted file mode 100644 index 41a84a5e9..000000000 --- a/tests/generics/tspecial_numeric_inference.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - output: '''false''' -""" - -when false: - import typetraits - - proc `@`[T: SomeInteger](x, y: T): T = x - - echo(type(5'i64 @ 6'i32)) - - echo(type(5'i32 @ 6'i64)) - -import sets -# bug #7247 -type - n8 = range[0'i8..127'i8] - -var tab = initSet[n8]() - -echo tab.contains(8) diff --git a/tests/generics/tspecialised_is_equivalent.nim b/tests/generics/tspecialised_is_equivalent.nim deleted file mode 100644 index 56fd72630..000000000 --- a/tests/generics/tspecialised_is_equivalent.nim +++ /dev/null @@ -1,14 +0,0 @@ -## -## specialised_is_equivalent Nim Module -## -## Created by Eric Doughty-Papassideris on 2011-02-16. - -type - TGen[T] = tuple[a: T] - TSpef = tuple[a: string] - -var - a: TGen[string] - b: TSpef -a = b - diff --git a/tests/generics/tspecialized_procvar.nim b/tests/generics/tspecialized_procvar.nim deleted file mode 100644 index 4bdc94a66..000000000 --- a/tests/generics/tspecialized_procvar.nim +++ /dev/null @@ -1,17 +0,0 @@ -discard """ - output: '''concrete 88''' -""" - -# Another regression triggered by changed closure computations: - -proc foo[T](x: proc(): T) = - echo "generic ", x() - -proc foo(x: proc(): int) = - echo "concrete ", x() - -# note the following 'proc' is not .closure! -foo(proc (): auto {.nimcall.} = 88) - -# bug #3499 last snippet fixed -# bug 705 last snippet fixed diff --git a/tests/generics/tstatictalias.nim b/tests/generics/tstatictalias.nim deleted file mode 100644 index 98751b8cb..000000000 --- a/tests/generics/tstatictalias.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - output: '''G:0,1:0.1 -G:0,1:0.1 -H:1:0.1''' -""" - -type - G[i,j:static[int]] = object - v:float - H[j:static[int]] = G[0,j] -proc p[i,j:static[int]](x:G[i,j]) = echo "G:",i,",",j,":",x.v -proc q[j:static[int]](x:H[j]) = echo "H:",j,":",x.v - -var - g0 = G[0,1](v: 0.1) - h0:H[1] = g0 -p(g0) -p(h0) -q(h0) -# bug #4863 diff --git a/tests/generics/tsubtypeconstraint.nim b/tests/generics/tsubtypeconstraint.nim deleted file mode 100644 index 2f0954522..000000000 --- a/tests/generics/tsubtypeconstraint.nim +++ /dev/null @@ -1,13 +0,0 @@ - -# bug #1684 -type - BaseType {.inheritable pure.} = object - idx: int - - DerivedType* {.final pure.} = object of BaseType - -proc index*[Toohoo: BaseType](h: Toohoo): int {.inline.} = h.idx -proc newDerived(idx: int): DerivedType {.inline.} = DerivedType(idx: idx) - -let d = newDerived(2) -assert(d.index == 2) diff --git a/tests/generics/ttable_alias.nim b/tests/generics/ttable_alias.nim deleted file mode 100644 index 992ca85e0..000000000 --- a/tests/generics/ttable_alias.nim +++ /dev/null @@ -1,7 +0,0 @@ -# bug #4589 - -import tables -type SimpleTable*[TKey, TVal] = TableRef[TKey, TVal] -template newSimpleTable*(TKey, TVal: typedesc): SimpleTable[TKey, TVal] = newTable[TKey, TVal]() -var fontCache : SimpleTable[string, SimpleTable[int32, int]] -fontCache = newSimpleTable(string, SimpleTable[int32, int]) diff --git a/tests/generics/ttempl_in_generic.nim b/tests/generics/ttempl_in_generic.nim deleted file mode 100644 index f04b9d216..000000000 --- a/tests/generics/ttempl_in_generic.nim +++ /dev/null @@ -1,8 +0,0 @@ - -# bug #4600 -template foo(x: untyped): untyped = echo 1 -template foo(x,y: untyped): untyped = echo 2 - -proc bar1[T](x: T) = foo(x) -proc bar2(x: float) = foo(x,x) -proc bar3[T](x: T) = foo(x,x) diff --git a/tests/generics/ttypeclass_to_typeclass.nim b/tests/generics/ttypeclass_to_typeclass.nim deleted file mode 100644 index a5f010450..000000000 --- a/tests/generics/ttypeclass_to_typeclass.nim +++ /dev/null @@ -1,12 +0,0 @@ -# bug #4672 -type - EnumContainer[T: enum] = object - v: T - SomeEnum {.pure.} = enum - A,B,C - -proc value[T: enum](this: EnumContainer[T]): T = - this.v - -var enumContainer: EnumContainer[SomeEnum] -discard enumContainer.value() diff --git a/tests/generics/tvarargs_vs_generic.nim b/tests/generics/tvarargs_vs_generic.nim deleted file mode 100644 index 122f3e453..000000000 --- a/tests/generics/tvarargs_vs_generic.nim +++ /dev/null @@ -1,26 +0,0 @@ -discard """ - output: "direct\ngeneric\ngeneric" -""" - -proc withDirectType(args: string) = - echo "direct" - -proc withDirectType[T](arg: T) = - echo "generic" - -proc withOpenArray(args: openarray[string]) = - echo "openarray" - -proc withOpenArray[T](arg: T) = - echo "generic" - -proc withVarargs(args: varargs[string]) = - echo "varargs" - -proc withVarargs[T](arg: T) = - echo "generic" - -withDirectType "string" -withOpenArray "string" -withVarargs "string" - diff --git a/tests/generics/tvarious.nim b/tests/generics/tvarious.nim new file mode 100644 index 000000000..5e18995f5 --- /dev/null +++ b/tests/generics/tvarious.nim @@ -0,0 +1,245 @@ +discard """ + output: ''' +we +direct +generic +generic +''' +""" + + +import algorithm, sugar, sequtils, typetraits, asyncdispatch + + +block tconfusing_arrow: + type Deck = object + value: int + + proc sort(h: var seq[Deck]) = + # works: + h.sort(proc (x, y: Deck): auto = + cmp(x.value, y.value)) + # fails: + h.sort((x, y: Deck) => cmp(ord(x.value), ord(y.value))) + + var player: seq[Deck] = @[] + player.sort() + + + +block tdictdestruct: + type + TDict[TK, TV] = object + k: TK + v: TV + PDict[TK, TV] = ref TDict[TK, TV] + + proc fakeNew[T](x: var ref T, destroy: proc (a: ref T) {.nimcall.}) = + discard + + proc destroyDict[TK, TV](a: PDict[TK, TV]) = + return + proc newDict[TK, TV](a: TK, b: TV): PDict[TK, TV] = + fakeNew(result, destroyDict[TK, TV]) + + # Problem: destroyDict is not instantiated when newDict is instantiated! + discard newDict("a", "b") + + + +block tgenericdefaults: + type + TFoo[T, U, R = int] = object + x: T + y: U + z: R + + TBar[T] = TFoo[T, array[4, T], T] + + var x1: TFoo[int, float] + + static: + assert type(x1.x) is int + assert type(x1.y) is float + assert type(x1.z) is int + + var x2: TFoo[string, R = float, U = seq[int]] + + static: + assert type(x2.x) is string + assert type(x2.y) is seq[int] + assert type(x2.z) is float + + var x3: TBar[float] + + static: + assert type(x3.x) is float + assert type(x3.y) is array[4, float] + assert type(x3.z) is float + + + +block tprop: + type + TProperty[T] = object of RootObj + getProc: proc(property: TProperty[T]): T {.nimcall.} + setProc: proc(property: TProperty[T], value: T) {.nimcall.} + value: T + + proc newProperty[T](value: RootObj): TProperty[T] = + result.getProc = proc (property: TProperty[T]) = + return property.value + + + +block trefs: + type + PA[T] = ref TA[T] + TA[T] = object + field: T + var a: PA[string] + new(a) + a.field = "some string" + + proc someOther[T](len: string): seq[T] = discard + proc someOther[T](len: int): seq[T] = echo "we" + + proc foo[T](x: T) = + var s = someOther[T](34) + #newSeq[T](34) + + foo 23 + + when false: + # Compiles unless you use var a: PA[string] + type + PA = ref TA + TA[T] = object + + # Cannot instantiate: + type + TA[T] = object + a: PA[T] + PA[T] = ref TA[T] + + type + PA[T] = ref TA[T] + TA[T] = object + + + +block tsharedcases: + proc typeNameLen(x: typedesc): int {.compileTime.} = + result = x.name.len + macro selectType(a, b: typedesc): typedesc = + result = a + + type + Foo[T] = object + data1: array[T.high, int] + data2: array[typeNameLen(T), float] + data3: array[0..T.typeNameLen, selectType(float, int)] + MyEnum = enum A, B, C, D + + var f1: Foo[MyEnum] + var f2: Foo[int8] + + doAssert high(f1.data1) == 2 # (D = 3) - 1 == 2 + doAssert high(f1.data2) == 5 # (MyEnum.len = 6) - 1 == 5 + + doAssert high(f2.data1) == 126 # 127 - 1 == 126 + doAssert high(f2.data2) == 3 # int8.len - 1 == 3 + + static: + assert high(f1.data1) == ord(C) + assert high(f1.data2) == 5 # length of MyEnum minus one, because we used T.high + + assert high(f2.data1) == 126 + assert high(f2.data2) == 3 + + assert high(f1.data3) == 6 # length of MyEnum + assert high(f2.data3) == 4 # length of int8 + + assert f2.data3[0] is float + + + +block tmap_auto: + let x = map(@[1, 2, 3], x => x+10) + assert x == @[11, 12, 13] + + let y = map(@[(1,"a"), (2,"b"), (3,"c")], x => $x[0] & x[1]) + assert y == @["1a", "2b", "3c"] + + proc eatsTwoArgProc[T,S,U](a: T, b: S, f: proc(t: T, s: S): U): U = + f(a,b) + + let z = eatsTwoArgProc(1, "a", (t,s) => $t & s) + assert z == "1a" + + + +block tproctypecache_falsepositive: + type + Callback = proc() {.closure, gcsafe.} + GameState = ref object + playerChangeHandlers: seq[Callback] + + proc newGameState(): GameState = + result = GameState( + playerChangeHandlers: newSeq[Callback]() # this fails + ) + + + +block tptrinheritance: + type NSPasteboardItem = ptr object + type NSPasteboard = ptr object + type NSArrayAbstract = ptr object {.inheritable.} + type NSMutableArrayAbstract = ptr object of NSArrayAbstract + type NSArray[T] = ptr object of NSArrayAbstract + type NSMutableArray[T] = ptr object of NSArray[T] + + proc newMutableArrayAbstract(): NSMutableArrayAbstract = discard + + template newMutableArray(T: typedesc): NSMutableArray[T] = + cast[NSMutableArray[T]](newMutableArrayAbstract()) + + proc writeObjects(p: NSPasteboard, o: NSArray[NSPasteboardItem]) = discard + + let a = newMutableArray NSPasteboardItem + var x: NSMutableArray[NSPasteboardItem] + var y: NSArray[NSPasteboardItem] = x + + writeObjects(nil, a) + + + +block tsigtypeop: + type Vec3[T] = array[3, T] + + proc foo(x: Vec3, y: Vec3.T, z: x.T): x.type.T = + return 10 + + var y: Vec3[int] = [1, 2, 3] + var z: int = foo(y, 3, 4) + + + +block tvarargs_vs_generics: + proc withDirectType(args: string) = + echo "direct" + proc withDirectType[T](arg: T) = + echo "generic" + proc withOpenArray(args: openarray[string]) = + echo "openarray" + proc withOpenArray[T](arg: T) = + echo "generic" + proc withVarargs(args: varargs[string]) = + echo "varargs" + proc withVarargs[T](arg: T) = + echo "generic" + + withDirectType "string" + withOpenArray "string" + withVarargs "string" |