summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/clearmsg/tmacroerrorproc.nim6
-rw-r--r--tests/closure/tdonotation.nim45
-rw-r--r--tests/concepts/t5642.nim25
-rw-r--r--tests/concepts/tconceptinclosure.nim53
-rw-r--r--tests/concepts/tmisc_issues.nim2
-rw-r--r--tests/concepts/trandom_vars.nim42
-rw-r--r--tests/generics/t5570.nim27
-rw-r--r--tests/generics/t5602_inheritence.nim18
-rw-r--r--tests/generics/t5643.nim30
-rw-r--r--tests/generics/t5683.nim31
-rw-r--r--tests/generics/tbindoncevsbindmany.nim68
-rw-r--r--tests/generics/tmapping_generic_alias.nim28
-rw-r--r--tests/generics/tparam_binding.nim28
-rw-r--r--tests/generics/tptrinheritance.nim20
-rw-r--r--tests/js/tjsffi.nim62
-rw-r--r--tests/macros/tlexerex.nim5
-rw-r--r--tests/parser/tpostexprblocks.nim513
-rw-r--r--tests/template/tgensymregression.nim3
-rw-r--r--tests/types/t5640.nim6
-rw-r--r--tests/types/t5648.nim21
-rwxr-xr-xtests/types/thard_tyforward.nim22
21 files changed, 1041 insertions, 14 deletions
diff --git a/tests/clearmsg/tmacroerrorproc.nim b/tests/clearmsg/tmacroerrorproc.nim
index 9a6ff6a06..cd9b15e25 100644
--- a/tests/clearmsg/tmacroerrorproc.nim
+++ b/tests/clearmsg/tmacroerrorproc.nim
@@ -7,7 +7,7 @@ discard """
 import macros
 
 macro mixer(n: typed): untyped =
-  expectKind(n, nnkCharLit)
-  
+  expectKind(n[0], nnkCharLit)
+
 mixer:
-  echo "owh"
\ No newline at end of file
+  echo "owh"
diff --git a/tests/closure/tdonotation.nim b/tests/closure/tdonotation.nim
new file mode 100644
index 000000000..94eba8ddb
--- /dev/null
+++ b/tests/closure/tdonotation.nim
@@ -0,0 +1,45 @@
+discard """
+output: '''
+click at 10,20
+lost focus 1
+lost focus 2
+registered handler for UserEvent 1
+registered handler for UserEvent 2
+registered handler for UserEvent 3'''
+"""
+
+import future
+
+type
+  Button = object
+  Event = object
+    x, y: int
+
+proc onClick(x: Button, handler: proc(x: Event)) =
+  handler(Event(x: 10, y: 20))
+
+proc onFocusLost(x: Button, handler: proc()) =
+  handler()
+
+proc onUserEvent(x: Button, eventName: string, handler: proc) =
+  echo "registered handler for ", eventName
+
+var b = Button()
+
+b.onClick do (e: Event):
+  echo "click at ", e.x, ",", e.y
+
+b.onFocusLost:
+  echo "lost focus 1"
+
+b.onFocusLost do:
+  echo "lost focus 2"
+
+b.onUserEvent "UserEvent 1" do:
+  discard
+
+b.onUserEvent "UserEvent 2":
+  discard
+
+b.onUserEvent("UserEvent 3", () => echo "event 3")
+
diff --git a/tests/concepts/t5642.nim b/tests/concepts/t5642.nim
new file mode 100644
index 000000000..d1e7bd1dd
--- /dev/null
+++ b/tests/concepts/t5642.nim
@@ -0,0 +1,25 @@
+discard """
+  output: 9
+"""
+
+type DataTable = concept x
+  x is object
+  for f in fields(x):
+    f is seq
+
+type Students = object
+   id : seq[int]
+   name : seq[string]
+   age: seq[int]
+
+proc nrow*(dt: DataTable) : Natural =
+  var totalLen = 0
+  for f in fields(dt):
+    totalLen += f.len
+  return totalLen
+
+let
+ stud = Students (id : @[1,2,3], name : @["Vas", "Pas", "NafNaf"], age : @[10,16,32])
+
+echo nrow(stud)
+
diff --git a/tests/concepts/tconceptinclosure.nim b/tests/concepts/tconceptinclosure.nim
new file mode 100644
index 000000000..23c1bf293
--- /dev/null
+++ b/tests/concepts/tconceptinclosure.nim
@@ -0,0 +1,53 @@
+discard """
+  output: '''
+10
+20
+int
+20
+3
+'''
+"""
+
+import typetraits
+
+type
+  FonConcept = concept x
+    x.x is int
+
+  GenericConcept[T] = concept x
+    x.x is T
+    const L = T.name.len
+
+  Implementation = object
+    x: int
+
+  Closure = object
+    f: proc()
+
+proc f1(x: FonConcept): Closure =
+  result.f = proc () =
+    echo x.x
+
+proc f2(x: GenericConcept): Closure =
+  result.f = proc () =
+    echo x.x
+    echo GenericConcept.T.name
+
+proc f3[T](x: GenericConcept[T]): Closure =
+  result.f = proc () =
+    echo x.x
+    echo x.L
+
+let x = Implementation(x: 10)
+let y = Implementation(x: 20)
+
+let a = x.f1
+let b = x.f2
+let c = x.f1
+let d = y.f2
+let e = y.f3
+
+a.f()
+d.f()
+e.f()
+
diff --git a/tests/concepts/tmisc_issues.nim b/tests/concepts/tmisc_issues.nim
index 10e072521..d9bb84a2f 100644
--- a/tests/concepts/tmisc_issues.nim
+++ b/tests/concepts/tmisc_issues.nim
@@ -42,7 +42,7 @@ echo p2 is AbstractPointOfFloat      # true
 echo p2.x is float and p2.y is float # true
 
 # https://github.com/nim-lang/Nim/issues/2018
-type ProtocolFollower = generic
+type ProtocolFollower = concept
   true # not a particularly involved protocol
 
 type ImplementorA = object
diff --git a/tests/concepts/trandom_vars.nim b/tests/concepts/trandom_vars.nim
new file mode 100644
index 000000000..a236cebad
--- /dev/null
+++ b/tests/concepts/trandom_vars.nim
@@ -0,0 +1,42 @@
+discard """
+output: "11.0"
+"""
+
+type
+  # A random number generator
+  Random = object
+    random: proc(): float
+  # A generic typeclass for a random var
+  RandomVar[A] = concept x
+    var rng: Random
+    rng.sample(x) is A
+  # A few concrete instances
+  Uniform = object
+    a, b: float
+  ClosureVar[A] = object
+    f: proc(rng: var Random): A
+
+# How to sample from various concrete instances
+proc sample(rng: var Random, u: Uniform): float = u.a + (u.b - u.a) * rng.random()
+
+proc sample[A](rng: var Random, c: ClosureVar[A]): A = c.f(rng)
+
+proc uniform(a, b: float): Uniform = Uniform(a: a, b: b)
+
+# How to lift a function on values to a function on random variables
+proc map[A, B](x: RandomVar[A], f: proc(a: A): B): ClosureVar[B] =
+  proc inner(rng: var Random): B =
+    f(rng.sample(x))
+
+  result.f = inner
+
+import future
+
+proc fakeRandom(): Random =
+  result.random = () => 0.5
+
+let x = uniform(1, 10).map((x: float) => 2 * x)
+
+var rng = fakeRandom()
+
+echo rng.sample(x)
diff --git a/tests/generics/t5570.nim b/tests/generics/t5570.nim
new file mode 100644
index 000000000..e3f9ff415
--- /dev/null
+++ b/tests/generics/t5570.nim
@@ -0,0 +1,27 @@
+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/t5602_inheritence.nim b/tests/generics/t5602_inheritence.nim
new file mode 100644
index 000000000..6d48c796e
--- /dev/null
+++ b/tests/generics/t5602_inheritence.nim
@@ -0,0 +1,18 @@
+discard """
+  output: "seq[float]\n0"
+"""
+
+# https://github.com/nim-lang/Nim/issues/5602
+
+import typetraits
+
+type
+  Foo[T] = object of RootObj
+  Bar[T] = object of Foo[seq[T]]
+
+proc p[T](f: Foo[T]): T =
+  echo T.name
+
+var s: Bar[float]
+echo p(s).len # the bug was: p(s) should return seq[float], but returns float instead
+
diff --git a/tests/generics/t5643.nim b/tests/generics/t5643.nim
new file mode 100644
index 000000000..962d5cef5
--- /dev/null
+++ b/tests/generics/t5643.nim
@@ -0,0 +1,30 @@
+type
+  Matrix*[M, N: static[int], T: SomeReal] = 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
new file mode 100644
index 000000000..38da52ec2
--- /dev/null
+++ b/tests/generics/t5683.nim
@@ -0,0 +1,31 @@
+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/tbindoncevsbindmany.nim b/tests/generics/tbindoncevsbindmany.nim
new file mode 100644
index 000000000..01e801f0e
--- /dev/null
+++ b/tests/generics/tbindoncevsbindmany.nim
@@ -0,0 +1,68 @@
+template accept(x) =
+  static: assert(compiles(x))
+
+template reject(x) =
+  static: assert(not compiles(x))
+
+type
+  ObjectWithNumber = concept obj
+    obj.number is int
+
+  Foo[T] = object
+    x: T
+
+type A = object
+  anumber: int
+
+type B = object
+  bnumber: int
+
+proc number(a: A): int = a.anumber
+proc number(b: B): int = b.bnumber
+
+proc notDistincConcept1(a: ObjectWithNumber, b: ObjectWithNumber) = discard
+proc notDistincConcept2(a, b: ObjectWithNumber) = discard
+proc distinctConcept1(a, b: distinct ObjectWithNumber) = discard
+proc distinctConcept2(a: ObjectWithNumber, b: distinct ObjectWithNumber) = discard
+proc distinctConcept3(a: distinct ObjectWithNumber, b: ObjectWithNumber) = discard
+proc distinctConcept4(a: distinct ObjectWithNumber, b: distinct ObjectWithNumber) = discard
+
+var a = A(anumber: 5)
+var b = B(bnumber: 6)
+
+accept notDistincConcept1(a, a)
+accept notDistincConcept1(b, b)
+reject notDistincConcept2(a, b)
+
+accept notDistincConcept2(a, a)
+accept notDistincConcept2(b, b)
+reject notDistincConcept2(a, b)
+
+accept distinctConcept1(a, b)
+accept distinctConcept2(a, b)
+accept distinctConcept3(a, b)
+accept distinctConcept4(a, b)
+
+proc nonDistincGeneric1(a: Foo, b: Foo) = discard
+proc nonDistincGeneric2(a, b: Foo) = discard
+proc distinctGeneric1(a, b: distinct Foo) = discard
+proc distinctGeneric2(a: distinct Foo, b: Foo) = discard
+proc distinctGeneric3(a: Foo, b: distinct Foo) = discard
+proc distinctGeneric4(a: distinct Foo, b: distinct Foo) = discard
+
+var f1 = Foo[int](x: 10)
+var f2 = Foo[string](x: "x")
+
+accept nonDistincGeneric1(f1, f1)
+accept nonDistincGeneric1(f2, f2)
+reject nonDistincGeneric1(f1, f2)
+
+accept nonDistincGeneric2(f1, f1)
+accept nonDistincGeneric2(f2, f2)
+reject nonDistincGeneric2(f1, f2)
+
+accept distinctGeneric1(f1, f1)
+accept distinctGeneric2(f1, f1)
+accept distinctGeneric3(f1, f1)
+accept distinctGeneric4(f1, f1)
+
diff --git a/tests/generics/tmapping_generic_alias.nim b/tests/generics/tmapping_generic_alias.nim
new file mode 100644
index 000000000..efdf32ead
--- /dev/null
+++ b/tests/generics/tmapping_generic_alias.nim
@@ -0,0 +1,28 @@
+discard """
+output: '''type(c) = GenAlias[system.int]
+T = int
+seq[int]
+'''
+"""
+
+import typetraits
+
+type
+  Gen[T] = object
+    x: T
+
+  GenAlias[T] = Gen[seq[T]]
+
+proc f1[T](x: Gen[T]) =
+  echo T.name
+
+proc f2[T](x: GenAlias[T]) =
+  echo "type(c) = ", type(x).name
+  echo "T = ", T.name
+  f1 x
+
+let
+  y = Gen[seq[int]](x: @[10])
+
+f2 y
+
diff --git a/tests/generics/tparam_binding.nim b/tests/generics/tparam_binding.nim
new file mode 100644
index 000000000..643e9b226
--- /dev/null
+++ b/tests/generics/tparam_binding.nim
@@ -0,0 +1,28 @@
+discard """
+  errormsg: "got (ref Matrix[2, 2, system.float], ref Matrix[2, 1, system.float])"
+  line: 27
+"""
+
+type
+  Matrix[M,N: static[int]; T: SomeReal] = distinct array[0..(M*N - 1), T]
+
+let a = new Matrix[2,2,float]
+let b = new Matrix[2,1,float]
+
+proc foo[M,N: static[int],T](a: ref Matrix[M, N, T], b: ref Matrix[M, N, T])=
+  discard
+
+foo(a, a)
+
+proc bar[M,N: static[int],T](a: ref Matrix[M, M, T], b: ref Matrix[M, N, T])=
+  discard
+
+bar(a, b)
+bar(a, a)
+
+proc baz[M,N: static[int],T](a: ref Matrix[N, N, T], b: ref Matrix[M, N, T])=
+  discard
+
+baz(a, a)
+baz(a, b)
+
diff --git a/tests/generics/tptrinheritance.nim b/tests/generics/tptrinheritance.nim
new file mode 100644
index 000000000..1e1115fa5
--- /dev/null
+++ b/tests/generics/tptrinheritance.nim
@@ -0,0 +1,20 @@
+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: ptr NSArray[NSPasteboardItem]) = discard
+
+let a = newMutableArray NSPasteboardItem
+var x: NSMutableArray[NSPasteboardItem]
+var y: NSArray[NSPasteboardItem] = x
+
+writeObjects(nil, a)
+
diff --git a/tests/js/tjsffi.nim b/tests/js/tjsffi.nim
index 71eb211e3..e4aad4b99 100644
--- a/tests/js/tjsffi.nim
+++ b/tests/js/tjsffi.nim
@@ -1,5 +1,5 @@
 discard """
-  output: '''true
+output: '''
 true
 true
 true
@@ -14,10 +14,18 @@ true
 true
 true
 true
-true'''
+true
+true
+3
+2
+12
+Event { name: 'click: test' }
+Event { name: 'reloaded: test' }
+Event { name: 'updates: test' }
+'''
 """
 
-import macros, jsffi
+import macros, jsffi, jsconsole
 
 # Tests for JsObject
 # Test JsObject []= and []
@@ -55,8 +63,8 @@ block:
 block:
   proc test(): bool =
     let obj = newJsObject()
-    obj.`?!$` = proc(x, y, z: int, t: string): string = t & $(x + y + z)
-    obj.`?!$`(1, 2, 3, "Result is: ").to(string) == "Result is: 6"
+    obj.`?!$` = proc(x, y, z: int, t: cstring): cstring = t & $(x + y + z)
+    obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == "Result is: 6"
   echo test()
 
 # Test JsObject []()
@@ -265,3 +273,47 @@ block:
     let obj = TestObject(a: 9, onWhatever: bindMethod(handleWhatever))
     obj.onWhatever(1) == 10
   echo test()
+
+block:
+  {.emit: "function jsProc(n) { return n; }" .}
+  proc jsProc(x: int32): JsObject {.importc: "jsProc".}
+
+  proc test() =
+    var x = jsProc(1)
+    var y = jsProc(2)
+    console.log x + y
+    console.log ++x
+
+    x += jsProc(10)
+    console.log x
+
+  test()
+
+import macros
+
+block:
+  {.emit:
+  """
+  function Event(name) { this.name = name; }
+  function on(eventName, eventHandler) { eventHandler(new Event(eventName + ": test")); }
+  var jslib = { "on": on, "subscribe": on };
+  """
+  .}
+
+  type Event = object
+    name: cstring
+
+  proc on(event: cstring, handler: proc) {.importc: "on".}
+  var jslib {.importc: "jslib", nodecl.}: JsObject
+
+  on("click") do (e: Event):
+    console.log e
+
+  jslib.on "reloaded" do:
+    console.log jsarguments[0]
+
+  # this test case is different from the above, because
+  # `subscribe` is not overloaded in the current scope
+  jslib.subscribe "updates":
+    console.log jsarguments[0]
+
diff --git a/tests/macros/tlexerex.nim b/tests/macros/tlexerex.nim
index d348a4bcc..db2c38ef6 100644
--- a/tests/macros/tlexerex.nim
+++ b/tests/macros/tlexerex.nim
@@ -1,8 +1,7 @@
-
 import macros
 
-macro match*(s: cstring|string; pos: int; sections: untyped): untyped =
-  for sec in sections.children:
+macro match*(s: cstring|string; pos: int; sections: varargs[untyped]): untyped =
+  for sec in sections:
     expectKind sec, nnkOfBranch
     expectLen sec, 2
   result = newStmtList()
diff --git a/tests/parser/tpostexprblocks.nim b/tests/parser/tpostexprblocks.nim
new file mode 100644
index 000000000..85f2628bf
--- /dev/null
+++ b/tests/parser/tpostexprblocks.nim
@@ -0,0 +1,513 @@
+discard """
+nimout: '''
+StmtList
+  Ident !"foo"
+  Call
+    Ident !"foo"
+  Call
+    Ident !"foo"
+    Ident !"x"
+  Command
+    Ident !"foo"
+    Ident !"x"
+  Call
+    Ident !"foo"
+    StmtList
+      DiscardStmt
+        Empty
+  Call
+    Ident !"foo"
+    StmtList
+      DiscardStmt
+        Empty
+  Call
+    Ident !"foo"
+    StrLit test
+    StmtList
+      DiscardStmt
+        Empty
+  Call
+    Ident !"foo"
+    StrLit test
+    StmtList
+      DiscardStmt
+        Empty
+  Command
+    Ident !"foo"
+    StrLit test
+    StmtList
+      DiscardStmt
+        Empty
+  Command
+    Ident !"foo"
+    StrLit test
+    StmtList
+      DiscardStmt
+        Empty
+  Command
+    Ident !"foo"
+    IntLit 1
+    Par
+      Infix
+        Ident !"+"
+        IntLit 2
+        IntLit 3
+    StmtList
+      DiscardStmt
+        Empty
+  Command
+    Ident !"foo"
+    IntLit 1
+    Par
+      Infix
+        Ident !"+"
+        IntLit 2
+        IntLit 3
+    StmtList
+      DiscardStmt
+        Empty
+  Call
+    Ident !"foo"
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Empty
+        IdentDefs
+          Ident !"x"
+          Empty
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    Ident !"foo"
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Empty
+        IdentDefs
+          Ident !"x"
+          Ident !"int"
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    Ident !"foo"
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Ident !"int"
+        IdentDefs
+          Ident !"x"
+          Ident !"int"
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+  Command
+    Ident !"foo"
+    Ident !"x"
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Empty
+        IdentDefs
+          Ident !"y"
+          Empty
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    Ident !"foo"
+    StmtList
+      DiscardStmt
+        Empty
+    Else
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    Ident !"foo"
+    StmtList
+      DiscardStmt
+        Empty
+    StmtList
+      DiscardStmt
+        Empty
+    Else
+      StmtList
+        DiscardStmt
+          Empty
+  Command
+    Ident !"foo"
+    Ident !"x"
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Empty
+        IdentDefs
+          Ident !"y"
+          Empty
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Ident !"int"
+        IdentDefs
+          Ident !"z"
+          Empty
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Ident !"int"
+        IdentDefs
+          Ident !"w"
+          Ident !"int"
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+    StmtList
+      DiscardStmt
+        Empty
+    Else
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    Ident !"foo"
+    Ident !"x"
+    Call
+      Ident !"bar"
+      StmtList
+        DiscardStmt
+          Empty
+      Else
+        StmtList
+          DiscardStmt
+            Empty
+  VarSection
+    IdentDefs
+      Ident !"a"
+      Empty
+      Ident !"foo"
+  VarSection
+    IdentDefs
+      Ident !"a"
+      Empty
+      Call
+        Ident !"foo"
+  VarSection
+    IdentDefs
+      Ident !"a"
+      Empty
+      Call
+        Ident !"foo"
+        Ident !"x"
+  VarSection
+    IdentDefs
+      Ident !"a"
+      Empty
+      Command
+        Ident !"foo"
+        Ident !"x"
+  VarSection
+    IdentDefs
+      Ident !"a"
+      Empty
+      Call
+        Ident !"foo"
+        StmtList
+          DiscardStmt
+            Empty
+  VarSection
+    IdentDefs
+      Ident !"a"
+      Empty
+      Call
+        Ident !"foo"
+        StmtList
+          DiscardStmt
+            Empty
+  VarSection
+    IdentDefs
+      Ident !"a"
+      Empty
+      Call
+        Ident !"foo"
+        StmtList
+          DiscardStmt
+            Empty
+        Else
+          StmtList
+            DiscardStmt
+              Empty
+  VarSection
+    IdentDefs
+      Ident !"a"
+      Empty
+      Command
+        Ident !"foo"
+        Ident !"x"
+        Do
+          Empty
+          Empty
+          Empty
+          FormalParams
+            Empty
+            IdentDefs
+              Ident !"y"
+              Empty
+              Empty
+          Empty
+          Empty
+          StmtList
+            DiscardStmt
+              Empty
+        Else
+          StmtList
+            DiscardStmt
+              Empty
+  Asgn
+    Ident !"a"
+    Ident !"foo"
+  Asgn
+    Ident !"a"
+    Call
+      Ident !"foo"
+  Asgn
+    Ident !"a"
+    Call
+      Ident !"foo"
+      Ident !"x"
+  Asgn
+    Ident !"a"
+    Command
+      Ident !"foo"
+      Ident !"x"
+  Asgn
+    Ident !"a"
+    Call
+      Ident !"foo"
+      StmtList
+        DiscardStmt
+          Empty
+  Asgn
+    Ident !"a"
+    Call
+      Ident !"foo"
+      StmtList
+        DiscardStmt
+          Empty
+  Asgn
+    Ident !"a"
+    Call
+      Ident !"foo"
+      StmtList
+        DiscardStmt
+          Empty
+      Else
+        StmtList
+          DiscardStmt
+            Empty
+  Asgn
+    Ident !"a"
+    Command
+      Ident !"foo"
+      Ident !"x"
+      Do
+        Empty
+        Empty
+        Empty
+        FormalParams
+          Empty
+          IdentDefs
+            Ident !"y"
+            Empty
+            Empty
+        Empty
+        Empty
+        StmtList
+          DiscardStmt
+            Empty
+      Else
+        StmtList
+          DiscardStmt
+            Empty
+  Call
+    DotExpr
+      Ident !"result"
+      Ident !"add"
+    BracketExpr
+      Call
+        Ident !"quote"
+        StmtList
+          DiscardStmt
+            Empty
+      IntLit 0
+'''
+"""
+
+import macros
+
+dumpTree:
+  # simple calls
+  foo
+  foo()
+  foo(x)
+  foo x
+
+  foo:
+    discard
+
+  foo do:
+    discard
+
+  foo("test"):
+    discard
+
+  foo("test") do:
+    discard
+
+  foo "test":
+    discard
+
+  foo "test" do:
+    discard
+
+  # more complicated calls
+  foo 1, (2+3):
+    discard
+
+  foo 1, (2+3) do:
+    discard
+
+  foo do (x):
+    discard
+
+  foo do (x: int):
+    discard
+
+  foo do (x: int) -> int:
+    discard
+
+  foo x do (y):
+    discard
+
+  # extra blocks
+  foo:
+    discard
+  else:
+    discard
+
+  foo do:
+    discard
+  do:
+    discard
+  else:
+    discard
+
+  foo x do (y):
+    discard
+  do (z) -> int:
+    discard
+  do (w: int) -> int:
+    discard
+  do:
+    discard
+  else:
+    discard
+
+  # call with blocks as a param
+  foo(x, bar do:
+    discard
+  else:
+    discard
+  )
+
+  # introduce a variable
+  var a = foo
+  var a = foo()
+  var a = foo(x)
+  var a = foo x
+
+  var a = foo:
+    discard
+
+  var a = foo do:
+    discard
+
+  var a = foo do:
+    discard
+  else:
+    discard
+
+  var a = foo x do (y):
+    discard
+  else:
+    discard
+
+  # assignments
+  a = foo
+  a = foo()
+  a = foo(x)
+  a = foo x
+
+  a = foo:
+    discard
+
+  a = foo do:
+    discard
+
+  a = foo do:
+    discard
+  else:
+    discard
+
+  a = foo x do (y):
+    discard
+  else:
+    discard
+
+  # some edge cases
+  result.add((quote do:
+    discard
+  )[0])
+
diff --git a/tests/template/tgensymregression.nim b/tests/template/tgensymregression.nim
index 0fadbde41..4cc64a831 100644
--- a/tests/template/tgensymregression.nim
+++ b/tests/template/tgensymregression.nim
@@ -59,14 +59,13 @@ template wrap(body: typed): untyped =
 
 macro makeProc(): typed =
   # Make a template tree
-  result = (quote do:
+  result = quote do:
     proc someProc* =
       wrap do:
         let x = 123
         # Implicit conversion here
         let s: string = x
         echo s
-  )
 
 makeProc()
 
diff --git a/tests/types/t5640.nim b/tests/types/t5640.nim
new file mode 100644
index 000000000..5e1c99c4d
--- /dev/null
+++ b/tests/types/t5640.nim
@@ -0,0 +1,6 @@
+type
+  vecBase[I: static[int]] = distinct array[I, float32]
+  vec2* = vecBase[2]
+
+var v = vec2([0.0'f32, 0.0'f32])
+
diff --git a/tests/types/t5648.nim b/tests/types/t5648.nim
new file mode 100644
index 000000000..c230cc12c
--- /dev/null
+++ b/tests/types/t5648.nim
@@ -0,0 +1,21 @@
+discard """
+output: "ptr Foo"
+"""
+
+import typetraits
+
+type Foo = object
+  bar*: int
+
+proc main() =
+  var f = create(Foo)
+  f.bar = 3
+  echo f.type.name
+
+  discard realloc(f, 0)
+
+  var g = Foo()
+  g.bar = 3
+
+main()
+
diff --git a/tests/types/thard_tyforward.nim b/tests/types/thard_tyforward.nim
new file mode 100755
index 000000000..7131cd64b
--- /dev/null
+++ b/tests/types/thard_tyforward.nim
@@ -0,0 +1,22 @@
+type
+  Bar[T] = Foo[T, T]
+  Baz[T] = proc (x: Foo[T, T])
+  
+  GenericAlias[T] = Foo[T]
+  GenericAlias2[T] = Foo[Baz[T]]
+  
+  Concrete1 = Foo[int, float]
+  Concrete2 = proc(x: proc(a: Foo[int, float]))
+  
+  Foo[T, U] = object
+    x: T
+    y: U
+
+var
+  x1: Bar[float]
+  x2: Baz[int]
+  x3: Concrete1
+  x4: Concrete2
+  x5: GenericAlias[int]
+  x6: GenericAlias2[string]
+