summary refs log tree commit diff stats
path: root/tests/generics
diff options
context:
space:
mode:
Diffstat (limited to 'tests/generics')
-rw-r--r--tests/generics/t1050.nim29
-rw-r--r--tests/generics/t1056.nim25
-rw-r--r--tests/generics/t1789.nim44
-rw-r--r--tests/generics/t3977.nim14
-rw-r--r--tests/generics/t4884.nim11
-rw-r--r--tests/generics/t5570.nim27
-rw-r--r--tests/generics/t5643.nim30
-rw-r--r--tests/generics/t5683.nim31
-rw-r--r--tests/generics/t7794.nim15
-rw-r--r--tests/generics/t8403.nim11
-rw-r--r--tests/generics/t8439.nim10
-rw-r--r--tests/generics/t8694.nim31
-rw-r--r--tests/generics/t88.nim33
-rw-r--r--tests/generics/t9130.nim33
-rw-r--r--tests/generics/tableref_is_nil.nim9
-rw-r--r--tests/generics/tarray_with_somenumber.nim11
-rw-r--r--tests/generics/tbind_bracket.nim20
-rw-r--r--tests/generics/tcan.nim46
-rw-r--r--tests/generics/tcan_alias_generic.nim10
-rw-r--r--tests/generics/tcan_alias_specialised_generic.nim16
-rw-r--r--tests/generics/tcan_inherit_generic.nim16
-rw-r--r--tests/generics/tcan_specialise_generic.nim10
-rw-r--r--tests/generics/tclosed_sym.nim11
-rw-r--r--tests/generics/tconfusing_arrow.nim15
-rw-r--r--tests/generics/tdictdestruct.nim20
-rw-r--r--tests/generics/tdont_use_inner_scope.nim27
-rw-r--r--tests/generics/tdotlookup.nim10
-rw-r--r--tests/generics/tfakedependenttypes.nim61
-rw-r--r--tests/generics/tforward_generic.nim28
-rw-r--r--tests/generics/tgeneric0.nim118
-rw-r--r--tests/generics/tgeneric1.nim53
-rw-r--r--tests/generics/tgeneric2.nim15
-rw-r--r--tests/generics/tgeneric4.nim10
-rw-r--r--tests/generics/tgeneric_closure.nim37
-rw-r--r--tests/generics/tgeneric_inheritance.nim19
-rw-r--r--tests/generics/tgenericconst.nim39
-rw-r--r--tests/generics/tgenericdefaults.nim29
-rw-r--r--tests/generics/tgenericmatcher.nim50
-rw-r--r--tests/generics/tgenericmatcher2.nim18
-rw-r--r--tests/generics/tgenericprop.nim12
-rw-r--r--tests/generics/tgenericrefs.nim38
-rw-r--r--tests/generics/tgenerics_and_inheritance.nim36
-rw-r--r--tests/generics/tgenericsdefaultvalues.nim14
-rw-r--r--tests/generics/tgenericshardcases.nim42
-rw-r--r--tests/generics/tgenerictmpl.nim21
-rw-r--r--tests/generics/timports.nim45
-rw-r--r--tests/generics/tinferredgenericprocs.nim21
-rw-r--r--tests/generics/tissues.nim765
-rw-r--r--tests/generics/tlamba_in_generic.nim13
-rw-r--r--tests/generics/tmap_auto.nim13
-rw-r--r--tests/generics/tmodule_same_as_proc.nim9
-rw-r--r--tests/generics/tobjecttyperel3.nim12
-rw-r--r--tests/generics/tproctypecache_falsepositive.nim17
-rw-r--r--tests/generics/tptrinheritance.nim20
-rw-r--r--tests/generics/tsigtypeop.nim9
-rw-r--r--tests/generics/tspecial_numeric_inference.nim21
-rw-r--r--tests/generics/tspecialised_is_equivalent.nim14
-rw-r--r--tests/generics/tspecialized_procvar.nim17
-rw-r--r--tests/generics/tstatictalias.nim20
-rw-r--r--tests/generics/tsubtypeconstraint.nim13
-rw-r--r--tests/generics/ttable_alias.nim7
-rw-r--r--tests/generics/ttempl_in_generic.nim8
-rw-r--r--tests/generics/ttypeclass_to_typeclass.nim12
-rw-r--r--tests/generics/tvarargs_vs_generic.nim26
-rw-r--r--tests/generics/tvarious.nim245
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"