summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/assert/tfailedassert.nim2
-rw-r--r--tests/assign/moverload_asgn2.nim10
-rw-r--r--tests/assign/toverload_asgn1.nim75
-rw-r--r--tests/assign/toverload_asgn2.nim22
-rw-r--r--tests/ccgbugs/tarray_equality.nim15
-rw-r--r--tests/cpp/tget_subsystem.nim23
-rw-r--r--tests/cpp/tvector_iterator.nim19
-rw-r--r--tests/destructor/tdestructor.nim16
-rw-r--r--tests/destructor/tdestructor2.nim8
-rw-r--r--tests/effects/tgcsafe.nim2
-rw-r--r--tests/exception/texceptions.nim6
-rw-r--r--tests/exception/treraise.nim4
-rw-r--r--tests/generics/twrong_generic_object.nim21
-rw-r--r--tests/js/test2.nim11
-rw-r--r--tests/js/tunittests.nim7
-rw-r--r--tests/macros/tlexerex.nim16
-rw-r--r--tests/macros/ttryparseexpr.nim1
-rw-r--r--tests/macros/typesapi2.nim4
-rw-r--r--tests/metatype/tautoproc.nim6
-rw-r--r--tests/misc/tunsignedinc.nim14
-rw-r--r--tests/objects/tillegal_recursion.nim7
-rw-r--r--tests/objects/tobjloop.nim15
-rw-r--r--tests/objects/trefobjsyntax2.nim19
-rw-r--r--tests/overload/tstmtoverload.nim38
-rw-r--r--tests/parallel/tgc_unsafe2.nim39
-rw-r--r--tests/parallel/twrong_refcounts.nim53
-rw-r--r--tests/parser/tstrongspaces.nim33
-rw-r--r--tests/stdlib/treloop.nim9
-rw-r--r--tests/template/ttempl2.nim8
-rw-r--r--tests/testament/specs.nim6
-rw-r--r--tests/testament/tester.nim15
-rw-r--r--tests/tuples/tuint_tuple.nim10
-rw-r--r--tests/types/tisopr.nim41
33 files changed, 538 insertions, 37 deletions
diff --git a/tests/assert/tfailedassert.nim b/tests/assert/tfailedassert.nim
index 729cdcac7..1e6764471 100644
--- a/tests/assert/tfailedassert.nim
+++ b/tests/assert/tfailedassert.nim
@@ -30,7 +30,7 @@ proc bar: int =
   # local overrides that are active only
   # in this proc
   onFailedAssert(msg): echo "WARNING: " & msg
-    
+
   assert(false, "first assertion from bar")
 
   onFailedAssert(msg):
diff --git a/tests/assign/moverload_asgn2.nim b/tests/assign/moverload_asgn2.nim
new file mode 100644
index 000000000..6620adbeb
--- /dev/null
+++ b/tests/assign/moverload_asgn2.nim
@@ -0,0 +1,10 @@
+type
+  Concrete* = object
+    a*, b*: string
+    rc*: int # refcount
+
+proc `=`(d: var Concrete; src: Concrete) =
+  shallowCopy(d.a, src.a)
+  shallowCopy(d.b, src.b)
+  dec d.rc
+  d.rc = src.rc + 1
diff --git a/tests/assign/toverload_asgn1.nim b/tests/assign/toverload_asgn1.nim
new file mode 100644
index 000000000..dbc3a71c4
--- /dev/null
+++ b/tests/assign/toverload_asgn1.nim
@@ -0,0 +1,75 @@
+discard """
+  output: '''Concrete '='
+Concrete '='
+Concrete '='
+Concrete '='
+Concrete '='
+GenericT[T] '=' int
+GenericT[T] '=' float
+GenericT[T] '=' float
+GenericT[T] '=' float
+GenericT[T] '=' string
+GenericT[T] '=' int8
+GenericT[T] '=' bool
+GenericT[T] '=' bool
+GenericT[T] '=' bool
+GenericT[T] '=' bool'''
+"""
+
+import typetraits
+
+type
+  Concrete = object
+    a, b: string
+
+proc `=`(d: var Concrete; src: Concrete) =
+  shallowCopy(d.a, src.a)
+  shallowCopy(d.b, src.b)
+  echo "Concrete '='"
+
+var x, y: array[0..2, Concrete]
+var cA, cB: Concrete
+
+var cATup, cBTup: tuple[x: int, ha: Concrete]
+
+x = y
+cA = cB
+cATup = cBTup
+
+type
+  GenericT[T] = object
+    a, b: T
+
+proc `=`[T](d: var GenericT[T]; src: GenericT[T]) =
+  shallowCopy(d.a, src.a)
+  shallowCopy(d.b, src.b)
+  echo "GenericT[T] '=' ", type(T).name
+
+var ag: GenericT[int]
+var bg: GenericT[int]
+
+ag = bg
+
+var xg, yg: array[0..2, GenericT[float]]
+var cAg, cBg: GenericT[string]
+
+var cATupg, cBTupg: tuple[x: int, ha: GenericT[int8]]
+
+xg = yg
+cAg = cBg
+cATupg = cBTupg
+
+var caSeqg, cbSeqg: seq[GenericT[bool]]
+newSeq(cbSeqg, 4)
+caSeqg = cbSeqg
+
+when false:
+  type
+    Foo = object
+      case b: bool
+      of false: xx: GenericT[int]
+      of true: yy: bool
+
+  var
+    a, b: Foo
+  a = b
diff --git a/tests/assign/toverload_asgn2.nim b/tests/assign/toverload_asgn2.nim
new file mode 100644
index 000000000..243c90494
--- /dev/null
+++ b/tests/assign/toverload_asgn2.nim
@@ -0,0 +1,22 @@
+discard """
+  output: '''i value 88
+2aa'''
+"""
+
+import moverload_asgn2
+
+proc passAround(i: int): Concrete =
+  echo "i value ", i
+  result = Concrete(a: "aa", b: "bb", rc: 0)
+
+proc main =
+  let
+    i = 88
+    v = passAround(i)
+    z = v.a
+  var
+    x: Concrete
+  x = v
+  echo x.rc, z # 2aa
+
+main()
diff --git a/tests/ccgbugs/tarray_equality.nim b/tests/ccgbugs/tarray_equality.nim
new file mode 100644
index 000000000..66a953439
--- /dev/null
+++ b/tests/ccgbugs/tarray_equality.nim
@@ -0,0 +1,15 @@
+discard """
+  output: '''true
+true'''
+"""
+
+# bug #2489
+
+let a = [1]
+let b = [1]
+echo a == b
+
+# bug #2498
+var x: array[0, int]
+var y: array[0, int]
+echo x == y
diff --git a/tests/cpp/tget_subsystem.nim b/tests/cpp/tget_subsystem.nim
new file mode 100644
index 000000000..461914739
--- /dev/null
+++ b/tests/cpp/tget_subsystem.nim
@@ -0,0 +1,23 @@
+discard """
+  cmd: "nim cpp $file"
+"""
+
+{.emit: """
+
+namespace System {
+  struct Input {};
+}
+
+struct SystemManager {
+  template <class T>
+  static T* getSubsystem() { return new T; }
+};
+
+""".}
+
+type Input {.importcpp: "System::Input".} = object
+proc getSubsystem*[T](): ptr T {.
+  importcpp: "SystemManager::getSubsystem<'*0>()", nodecl.}
+
+let input: ptr Input = getSubsystem[Input]()
+
diff --git a/tests/cpp/tvector_iterator.nim b/tests/cpp/tvector_iterator.nim
new file mode 100644
index 000000000..cb5ab33af
--- /dev/null
+++ b/tests/cpp/tvector_iterator.nim
@@ -0,0 +1,19 @@
+discard """
+  cmd: "nim cpp $file"
+"""
+
+{.emit: """
+
+template <class T>
+struct Vector {
+  struct Iterator {};
+};
+
+""".}
+
+type
+  Vector {.importcpp: "Vector".} [T] = object
+  VectorIterator {.importcpp: "Vector<'0>::Iterator".} [T] = object
+
+var x: VectorIterator[void]
+
diff --git a/tests/destructor/tdestructor.nim b/tests/destructor/tdestructor.nim
index cbaba3154..639dba941 100644
--- a/tests/destructor/tdestructor.nim
+++ b/tests/destructor/tdestructor.nim
@@ -40,7 +40,7 @@ type
     x: A
     y: B
     z: C
-  
+
   TObjKind = enum A, B, C, D
 
   TCaseObj = object
@@ -57,14 +57,14 @@ type
         q: TMyGeneric3[TMyObj, int, int]
       r: string
 
-proc destroy(o: var TMyObj) {.override.} =
+proc `=destroy`(o: var TMyObj) =
   if o.p != nil: dealloc o.p
   echo "myobj destroyed"
 
-proc destroy(o: var TMyGeneric1) {.override.} =
+proc `=destroy`(o: var TMyGeneric1) =
   echo "mygeneric1 destroyed"
 
-proc destroy[A, B](o: var TMyGeneric2[A, B]) {.override.} =
+proc `=destroy`[A, B](o: var TMyGeneric2[A, B]) =
   echo "mygeneric2 destroyed"
 
 proc open: TMyObj =
@@ -83,12 +83,12 @@ proc mygeneric1() =
 
 proc mygeneric2[T](val: T) =
   var a = open()
-  
+
   var b = TMyGeneric2[int, T](x: 10, y: val)
   echo "mygeneric2 constructed"
 
   var c = TMyGeneric3[int, int, string](x: 10, y: 20, z: "test")
-  
+
 proc mygeneric3 =
   var x = TMyGeneric3[int, string, TMyGeneric1[int]](
     x: 10, y: "test", z: TMyGeneric1[int](x: 10))
@@ -111,11 +111,11 @@ proc caseobj =
   block:
     echo "----"
     var o1 = TCaseObj(kind: A, x: TMyGeneric1[int](x: 10))
-  
+
   block:
     echo "----"
     var o2 = TCaseObj(kind: B, y: open())
-  
+
   block:
     echo "----"
     var o3 = TCaseObj(kind: D, innerKind: B, r: "test",
diff --git a/tests/destructor/tdestructor2.nim b/tests/destructor/tdestructor2.nim
index 6f966d861..34fa466af 100644
--- a/tests/destructor/tdestructor2.nim
+++ b/tests/destructor/tdestructor2.nim
@@ -5,14 +5,14 @@ discard """
 
 {.experimental.}
 
-type  
+type
   TMyObj = object
     x, y: int
     p: pointer
-    
-proc destroy(o: var TMyObj) {.override.} =
+
+proc `=destroy`(o: var TMyObj) =
   if o.p != nil: dealloc o.p
-  
+
 proc open: TMyObj =
   result = TMyObj(x: 1, y: 2, p: alloc(3))
 
diff --git a/tests/effects/tgcsafe.nim b/tests/effects/tgcsafe.nim
index 0d5109439..d146794b6 100644
--- a/tests/effects/tgcsafe.nim
+++ b/tests/effects/tgcsafe.nim
@@ -1,5 +1,5 @@
 discard """
-  line: 16
+  line: 17
   errormsg: "'mainUnsafe' is not GC-safe"
   cmd: "nim $target --hints:on --threads:on $options $file"
 """
diff --git a/tests/exception/texceptions.nim b/tests/exception/texceptions.nim
index 69b2d0f6a..bdf338599 100644
--- a/tests/exception/texceptions.nim
+++ b/tests/exception/texceptions.nim
@@ -35,9 +35,9 @@ echo ""
 proc reraise_in_except =
   try:
     echo "BEFORE"
-    raise newException(EIO, "")
+    raise newException(IOError, "")
 
-  except EIO:
+  except IOError:
     echo "EXCEPT"
     raise
 
@@ -52,7 +52,7 @@ echo ""
 proc return_in_except =
   try:
     echo "BEFORE"
-    raise newException(EIO, "")
+    raise newException(IOError, "")
 
   except:
     echo "EXCEPT"
diff --git a/tests/exception/treraise.nim b/tests/exception/treraise.nim
index cbd0b5f8a..b2a11d34f 100644
--- a/tests/exception/treraise.nim
+++ b/tests/exception/treraise.nim
@@ -4,8 +4,8 @@ discard """
   exitcode: "1"
 """
 type
-  ESomething = object of E_Base
-  ESomeOtherErr = object of E_Base
+  ESomething = object of Exception
+  ESomeOtherErr = object of Exception
 
 proc genErrors(s: string) =
   if s == "error!":
diff --git a/tests/generics/twrong_generic_object.nim b/tests/generics/twrong_generic_object.nim
new file mode 100644
index 000000000..00d90c55e
--- /dev/null
+++ b/tests/generics/twrong_generic_object.nim
@@ -0,0 +1,21 @@
+discard """
+  errormsg: "cannot instantiate: 'GenericNodeObj'"
+  line: 21
+"""
+# bug #2509
+type
+  GenericNodeObj[T] = ref object
+    obj: T
+
+  Node* = ref object
+    children*: seq[Node]
+    parent*: Node
+
+    nodeObj*: GenericNodeObj # [int]
+
+proc newNode*(nodeObj: GenericNodeObj): Node =
+  result = Node(nodeObj: nodeObj)
+  newSeq(result.children, 10)
+
+var genericObj = GenericNodeObj[int]()
+var myNode = newNode(genericObj)
diff --git a/tests/js/test2.nim b/tests/js/test2.nim
index 5a734358c..1a42fbfda 100644
--- a/tests/js/test2.nim
+++ b/tests/js/test2.nim
@@ -1,6 +1,7 @@
 discard """
   output: '''foo
-js 3.14'''
+js 3.14
+7'''
 """
 
 # This file tests the JavaScript generator
@@ -20,3 +21,11 @@ else:
   proc foo(val: float): string = "js " & $val
 
 echo foo(3.14)
+
+# #2495
+type C = concept x
+
+proc test(x: C, T: typedesc): T =
+  cast[T](x)
+
+echo 7.test(int8)
diff --git a/tests/js/tunittests.nim b/tests/js/tunittests.nim
index af38cd9b9..8a264a5e0 100644
--- a/tests/js/tunittests.nim
+++ b/tests/js/tunittests.nim
@@ -1,3 +1,10 @@
+discard """
+  disabled: "true"
+"""
+
+# Unittest uses lambdalifting at compile-time which we disable for the JS
+# codegen! So this cannot and will not work for quite some time.
+
 import unittest
 
 suite "Bacon":
diff --git a/tests/macros/tlexerex.nim b/tests/macros/tlexerex.nim
new file mode 100644
index 000000000..d348a4bcc
--- /dev/null
+++ b/tests/macros/tlexerex.nim
@@ -0,0 +1,16 @@
+
+import macros
+
+macro match*(s: cstring|string; pos: int; sections: untyped): untyped =
+  for sec in sections.children:
+    expectKind sec, nnkOfBranch
+    expectLen sec, 2
+  result = newStmtList()
+
+when isMainModule:
+  var input = "the input"
+  var pos = 0
+  match input, pos:
+  of r"[a-zA-Z_]\w+": echo "an identifier"
+  of r"\d+": echo "an integer"
+  of r".": echo "something else"
diff --git a/tests/macros/ttryparseexpr.nim b/tests/macros/ttryparseexpr.nim
index af932eb7d..c7bbc8e5b 100644
--- a/tests/macros/ttryparseexpr.nim
+++ b/tests/macros/ttryparseexpr.nim
@@ -15,5 +15,6 @@ const
   valid = 45
   a = test("foo&&")
   b = test("valid")
+  c = test("\"") # bug #2504
 
 echo a, " ", b
diff --git a/tests/macros/typesapi2.nim b/tests/macros/typesapi2.nim
index 016295ba4..2e59d2154 100644
--- a/tests/macros/typesapi2.nim
+++ b/tests/macros/typesapi2.nim
@@ -1,4 +1,4 @@
-# tests to see if a symbol returned from macros.getType() can 
+# tests to see if a symbol returned from macros.getType() can
 # be used as a type
 import macros
 
@@ -20,7 +20,7 @@ static: assert iii is TestFN
 
 proc foo11 : testTypesym(void) =
     echo "HI!"
-static: assert foo11 is proc():void
+static: assert foo11 is (proc():void {.nimcall.})
 
 var sss: testTypesym(seq[int])
 static: assert sss is seq[int]
diff --git a/tests/metatype/tautoproc.nim b/tests/metatype/tautoproc.nim
index 562f508fc..ef5377096 100644
--- a/tests/metatype/tautoproc.nim
+++ b/tests/metatype/tautoproc.nim
@@ -1,11 +1,13 @@
 discard """
-  errormsg: "expression 'generate(builder)' has no type (or is ambiguous)"
+  output: "empty"
 """
 
 # bug #898
 
+import typetraits
+
 proc measureTime(e: auto) =
-  discard
+  echo e.type.name
 
 proc generate(a: int): void =
   discard
diff --git a/tests/misc/tunsignedinc.nim b/tests/misc/tunsignedinc.nim
new file mode 100644
index 000000000..95622156f
--- /dev/null
+++ b/tests/misc/tunsignedinc.nim
@@ -0,0 +1,14 @@
+discard """
+  output: '''253'''
+"""
+
+# bug #2427
+
+import unsigned
+
+var x = 0'u8
+dec x # OverflowError
+x -= 1 # OverflowError
+x = x - 1 # No error
+
+echo x
diff --git a/tests/objects/tillegal_recursion.nim b/tests/objects/tillegal_recursion.nim
new file mode 100644
index 000000000..171a04f87
--- /dev/null
+++ b/tests/objects/tillegal_recursion.nim
@@ -0,0 +1,7 @@
+discard """
+  errormsg: "illegal recursion in type 'object'"
+  line: 7
+"""
+# bug #1691
+type
+  Foo = ref object of Foo
diff --git a/tests/objects/tobjloop.nim b/tests/objects/tobjloop.nim
new file mode 100644
index 000000000..9fea1e2fb
--- /dev/null
+++ b/tests/objects/tobjloop.nim
@@ -0,0 +1,15 @@
+discard """
+  output: "is Nil false"
+"""
+# bug #1658
+
+type
+  Loop* = ref object
+    onBeforeSelect*: proc (L: Loop)
+
+var L: Loop
+new L
+L.onBeforeSelect = proc (bar: Loop) =
+  echo "is Nil ", bar.isNil
+
+L.onBeforeSelect(L)
diff --git a/tests/objects/trefobjsyntax2.nim b/tests/objects/trefobjsyntax2.nim
new file mode 100644
index 000000000..8ee209cc7
--- /dev/null
+++ b/tests/objects/trefobjsyntax2.nim
@@ -0,0 +1,19 @@
+# bug #2508
+
+type
+  GenericNodeObj[T] = ref object
+    obj: T
+
+  Node* = ref object
+    children*: seq[Node]
+    parent*: Node
+
+    nodeObj*: GenericNodeObj[int]
+
+proc newNode*(nodeObj: GenericNodeObj): Node =
+    result = Node(nodeObj: nodeObj)
+    newSeq(result.children, 10)
+
+var genericObj = GenericNodeObj[int]()
+
+var myNode = newNode(genericObj)
diff --git a/tests/overload/tstmtoverload.nim b/tests/overload/tstmtoverload.nim
new file mode 100644
index 000000000..f1944b637
--- /dev/null
+++ b/tests/overload/tstmtoverload.nim
@@ -0,0 +1,38 @@
+
+# bug #2481
+import math
+
+template test(loopCount: int, extraI: int, testBody: stmt): stmt =
+  block:
+    for i in 0..loopCount-1:
+      testBody
+    echo "done extraI=", extraI
+
+template test(loopCount: int, extraF: float, testBody: stmt): stmt =
+  block:
+    test(loopCount, round(extraF), testBody)
+
+template test(loopCount: int, testBody: stmt): stmt =
+  block:
+    test(loopCount, 0, testBody)
+    echo "done extraI passed 0"
+
+when isMainModule:
+  var
+    loops = 0
+
+  test 0, 0:
+    loops += 1
+  echo "test 0 complete, loops=", loops
+
+  test 1, 1.0:
+    loops += 1
+  echo "test 1.0 complete, loops=", loops
+
+  when true:
+    # when true we get the following compile time error:
+    #   b.nim(35, 6) Error: expression 'loops += 1' has no type (or is ambiguous)
+    loops = 0
+    test 2:
+      loops += 1
+    echo "test no extra complete, loops=", loops
diff --git a/tests/parallel/tgc_unsafe2.nim b/tests/parallel/tgc_unsafe2.nim
new file mode 100644
index 000000000..ec4605fe9
--- /dev/null
+++ b/tests/parallel/tgc_unsafe2.nim
@@ -0,0 +1,39 @@
+discard """
+  line: 28
+  nimout: '''tgc_unsafe2.nim(22, 5) Warning: 'trick' is not GC-safe as it accesses 'global' which is a global using GC'ed memory
+tgc_unsafe2.nim(26, 5) Warning: 'track' is not GC-safe as it calls 'trick'
+tgc_unsafe2.nim(28, 5) Error: 'consumer' is not GC-safe as it calls 'track'
+'''
+  errormsg: "'consumer' is not GC-safe as it calls 'track'"
+"""
+
+import threadpool
+
+type StringChannel = TChannel[string]
+var channels: array[1..3, StringChannel]
+
+type
+  MyObject[T] = object
+    x: T
+
+var global: MyObject[string]
+var globalB: MyObject[float]
+
+proc trick(ix: int) =
+  echo global.x
+  echo channels[ix].recv()
+
+proc track(ix: int) = trick(ix)
+
+proc consumer(ix: int) {.thread.} =
+  track(ix)
+
+proc main =
+  for ix in 1..3: channels[ix].open()
+  for ix in 1..3: spawn consumer(ix)
+  for ix in 1..3: channels[ix].send("test")
+  sync()
+  for ix in 1..3: channels[ix].close()
+
+when isMainModule:
+  main()
diff --git a/tests/parallel/twrong_refcounts.nim b/tests/parallel/twrong_refcounts.nim
new file mode 100644
index 000000000..db32a96d8
--- /dev/null
+++ b/tests/parallel/twrong_refcounts.nim
@@ -0,0 +1,53 @@
+discard """
+  output: "Success"
+"""
+
+import math, threadPool
+
+# ---
+
+type
+  Person = object
+    age: int
+    friend: ref Person
+
+var
+  people: seq[ref Person] = @[]
+
+proc newPerson(age:int): ref Person =
+  result.new()
+  result.age = age
+
+proc greet(p:Person) =
+  #echo p.age, ", ", p.friend.age
+  p.friend.age += 1
+
+# ---
+
+proc setup =
+  for i in 0 .. <20:
+    people.add newPerson(i + 1)
+  for i in 0 .. <20:
+    people[i].friend = people[random(20)]
+
+proc update =
+  var countA: array[20, int]
+  var countB: array[20, int]
+
+  for i, p in people:
+    countA[i] = getRefCount(p)
+  parallel:
+    for i in 0 .. people.high:
+      spawn greet(people[i][])
+  for i, p in people:
+    countB[i] = getRefCount(p)
+
+  for i in 0 .. <20:
+    doAssert countA[i] == countB[i]
+  echo "Success"
+
+# ---
+
+when isMainModule:
+  setup()
+  update()
diff --git a/tests/parser/tstrongspaces.nim b/tests/parser/tstrongspaces.nim
index 91506daf0..e70b91988 100644
--- a/tests/parser/tstrongspaces.nim
+++ b/tests/parser/tstrongspaces.nim
@@ -2,6 +2,12 @@
 
 discard """
   output: '''35
+true
+true
+4
+true
+1
+false
 77
 (Field0: 1, Field1: 2, Field2: 2)
 ha
@@ -9,11 +15,26 @@ true
 tester args
 all
 all args
+19
+-3
+false
+-2
 '''
 """
 
 echo 2+5 * 5
 
+# Keyword operators
+echo 1 + 16 shl 1 == 1 + (16 shl 1)
+echo 2 and 1  in  {0, 30}
+echo 2+2 * 2 shr 1
+echo false  or  2 and 1  in  {0, 30}
+
+proc `^`(a, b: int): int = a + b div 2
+echo 19 mod 16 ^ 4  +  2 and 1
+echo 18 mod 16 ^ 4 > 0
+
+# echo $foo gotcha
 let foo = 77
 echo $foo
 
@@ -27,7 +48,7 @@ when true:
   let b = 66
   let c = 90
   let bar = 8000
-  if foo+4 * 4 == 8 and b&c | 9  ++
+  if foo+4 * 4 == 8  and  b&c | 9  ++
       bar:
     echo "ho"
   else:
@@ -50,3 +71,13 @@ const
 echo tester & " " & args|"all"
 echo "all"  |  tester & " " & args
 echo "all"|tester & " " & args
+
+# Test arrow like operators. See also tests/macros/tclosuremacro.nim
+proc `+->`(a, b: int): int = a + b*4
+template `===>`(a, b: int): expr = a - b shr 1
+
+echo 3 +-> 2 + 2 and 4
+var arrowed = 3+->2 + 2 and 4  # arrowed = 4
+echo arrowed ===> 15
+echo (2 * 3+->2) == (2*3 +-> 2)
+echo arrowed ===> 2 + 3+->2
diff --git a/tests/stdlib/treloop.nim b/tests/stdlib/treloop.nim
new file mode 100644
index 000000000..35236708c
--- /dev/null
+++ b/tests/stdlib/treloop.nim
@@ -0,0 +1,9 @@
+discard """
+  output: "@[(, +,  1,  2, )]"
+"""
+
+import re
+
+let str = "(+ 1 2)"
+var tokenRE = re"""[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)"""
+echo str.findAll(tokenRE)
diff --git a/tests/template/ttempl2.nim b/tests/template/ttempl2.nim
index 142bbb8c7..aaa2f1344 100644
--- a/tests/template/ttempl2.nim
+++ b/tests/template/ttempl2.nim
@@ -3,12 +3,12 @@ discard """
   line: 18
   errormsg: "undeclared identifier: \'b\'"
 """
-template declareInScope(x: expr, t: typeDesc): stmt {.immediate.} =
+template declareInScope(x: untyped, t: typeDesc): untyped {.immediate.} =
   var x: t
-  
-template declareInNewScope(x: expr, t: typeDesc): stmt {.immediate.} =
+
+template declareInNewScope(x: untyped, t: typeDesc): untyped {.immediate.} =
   # open a new scope:
-  block: 
+  block:
     var x: t
 
 declareInScope(a, int)
diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim
index 2a8a4ea24..8bf1a4ad7 100644
--- a/tests/testament/specs.nim
+++ b/tests/testament/specs.nim
@@ -42,7 +42,8 @@ type
     action*: TTestAction
     file*, cmd*: string
     outp*: string
-    line*, exitCode*: int
+    line*, column*: int
+    exitCode*: int
     msg*: string
     ccodeCheck*: string
     err*: TResultEnum
@@ -98,6 +99,8 @@ proc parseSpec*(filename: string): TSpec =
   result.nimout = ""
   result.ccodeCheck = ""
   result.cmd = cmdTemplate
+  result.line = 0
+  result.column = 0
   parseSpecAux:
     case normalize(e.key)
     of "action":
@@ -108,6 +111,7 @@ proc parseSpec*(filename: string): TSpec =
       else: echo ignoreMsg(p, e)
     of "file": result.file = e.value
     of "line": discard parseInt(e.value, result.line)
+    of "column": discard parseInt(e.value, result.column)
     of "output": 
       result.action = actionRun
       result.outp = e.value
diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim
index 7391b105e..ed39109ad 100644
--- a/tests/testament/tester.nim
+++ b/tests/testament/tester.nim
@@ -50,7 +50,7 @@ type
 
 let
   pegLineError =
-    peg"{[^(]*} '(' {\d+} ', ' \d+ ') ' ('Error') ':' \s* {.*}"
+    peg"{[^(]*} '(' {\d+} ', ' {\d+} ') ' ('Error') ':' \s* {.*}"
   pegOtherError = peg"'Error:' \s* {.*}"
   pegSuccess = peg"'Hint: operation successful'.*"
   pegOfInterest = pegLineError / pegOtherError
@@ -77,11 +77,13 @@ proc callCompiler(cmdTemplate, filename, options: string,
   result.msg = ""
   result.file = ""
   result.outp = ""
-  result.line = -1
+  result.line = 0
+  result.column = 0
   if err =~ pegLineError:
     result.file = extractFilename(matches[0])
     result.line = parseInt(matches[1])
-    result.msg = matches[2]
+    result.column = parseInt(matches[2])
+    result.msg = matches[3]
   elif err =~ pegOtherError:
     result.msg = matches[0]
   elif suc =~ pegSuccess:
@@ -130,8 +132,11 @@ proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest) =
   elif extractFilename(expected.file) != extractFilename(given.file) and
       "internal error:" notin expected.msg:
     r.addResult(test, expected.file, given.file, reFilesDiffer)
-  elif expected.line != given.line and expected.line != 0:
-    r.addResult(test, $expected.line, $given.line, reLinesDiffer)
+  elif expected.line   != given.line   and expected.line   != 0 or
+       expected.column != given.column and expected.column != 0:
+    r.addResult(test, $expected.line & ':' & $expected.column,
+                      $given.line    & ':' & $given.column,
+                      reLinesDiffer)
   else:
     r.addResult(test, expected.msg, given.msg, reSuccess)
     inc(r.passed)
diff --git a/tests/tuples/tuint_tuple.nim b/tests/tuples/tuint_tuple.nim
new file mode 100644
index 000000000..24bcead5e
--- /dev/null
+++ b/tests/tuples/tuint_tuple.nim
@@ -0,0 +1,10 @@
+# bug #1986 found by gdmoore
+
+proc test(): int64 =
+  return 0xdeadbeef.int64
+
+const items = [
+  (var1: test(), var2: 100'u32),
+  (var1: test(), var2: 192'u32)
+]
+
diff --git a/tests/types/tisopr.nim b/tests/types/tisopr.nim
index 8b7fe4e46..b9acfa5fb 100644
--- a/tests/types/tisopr.nim
+++ b/tests/types/tisopr.nim
@@ -1,5 +1,11 @@
 discard """
-  output: '''true true false yes'''
+  output: '''true true false yes
+false
+false
+false
+true
+true
+no'''
 """
 
 proc IsVoid[T](): string =
@@ -28,7 +34,7 @@ no  s.items is iterator: float
 yes s.items is iterator: TNumber
 no  s.items is iterator: object
 
-type 
+type
   Iter[T] = iterator: T
 
 yes s.items is Iter[TNumber]
@@ -51,3 +57,34 @@ yes Foo[4, int] is Bar[int]
 no Foo[4, int] is Baz[4]
 yes Foo[4, float] is Baz[4]
 
+
+# bug #2505
+
+echo(8'i8 is int32)
+
+# bug #1853
+type SeqOrSet[E] = seq[E] or set[E]
+type SeqOfInt = seq[int]
+type SeqOrSetOfInt = SeqOrSet[int]
+
+# This prints "false", which seems less correct that (1) printing "true" or (2)
+# raising a compiler error.
+echo seq is SeqOrSet
+
+# This prints "false", as expected.
+echo seq is SeqOrSetOfInt
+
+# This prints "true", as expected.
+echo SeqOfInt is SeqOrSet
+
+# This causes an internal error (filename: compiler/semtypes.nim, line: 685).
+echo SeqOfInt is SeqOrSetOfInt
+
+# bug #2522
+proc test[T](x: T) =
+  when T is typedesc:
+    echo "yes"
+  else:
+    echo "no"
+
+test(7)