summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
authorMichael Voronin <survivor.mail@gmail.com>2018-05-10 13:15:33 +0300
committerGitHub <noreply@github.com>2018-05-10 13:15:33 +0300
commit1051e8d69dbf71e93f653fecd8da3b8587e9b3d4 (patch)
treec9dde28d0d516ad5d0282766cc0ec44461abcef7 /tests
parent5ea967d97a30f0084883d4efa81b05bea3e5d148 (diff)
parent9048bcc54b5fe8d0ae8c24b9cf7454cfa897ce5a (diff)
downloadNim-1051e8d69dbf71e93f653fecd8da3b8587e9b3d4.tar.gz
Merge pull request #4 from nim-lang/devel
#4
Diffstat (limited to 'tests')
-rw-r--r--tests/async/tasyncawait.nim12
-rw-r--r--tests/collections/thashes.nim4
-rw-r--r--tests/collections/tsets.nim52
-rw-r--r--tests/exprs/tstmtexprs.nim2
-rw-r--r--tests/generics/module_with_generics.nim14
-rw-r--r--tests/generics/t5602_inheritence.nim8
-rw-r--r--tests/macros/tstructuredlogging.nim154
-rw-r--r--tests/macros/ttemplatesymbols.nim173
-rw-r--r--tests/misc/tsimplesort.nim10
-rw-r--r--tests/modules/definitions.nim4
-rw-r--r--tests/modules/proxy_module.nim3
-rw-r--r--tests/overload/tparam_forwarding.nim16
-rw-r--r--tests/parser/tbraces.nim432
-rw-r--r--tests/parser/tcommand_as_expr.nim13
-rw-r--r--tests/parser/twrongcmdsyntax.nim2
-rw-r--r--tests/stdlib/ttimes.nim6
-rw-r--r--tests/testament/tester.nim8
-rw-r--r--tests/threads/tthreadvars.nim78
-rw-r--r--tests/trmacros/thoist.nim2
-rw-r--r--tests/typerel/texplicitcmp.nim4
-rw-r--r--tests/vm/tref.nim12
21 files changed, 549 insertions, 460 deletions
diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim
index 9fe9507ad..74933f063 100644
--- a/tests/async/tasyncawait.nim
+++ b/tests/async/tasyncawait.nim
@@ -12,11 +12,11 @@ const
 
 var clientCount = 0
 
-proc sendMessages(client: TAsyncFD) {.async.} =
+proc sendMessages(client: AsyncFD) {.async.} =
   for i in 0 .. <messagesToSend:
     await send(client, "Message " & $i & "\c\L")
 
-proc launchSwarm(port: TPort) {.async.} =
+proc launchSwarm(port: Port) {.async.} =
   for i in 0 .. <swarmSize:
     var sock = newAsyncNativeSocket()
 
@@ -24,7 +24,7 @@ proc launchSwarm(port: TPort) {.async.} =
     await sendMessages(sock)
     closeSocket(sock)
 
-proc readMessages(client: TAsyncFD) {.async.} =
+proc readMessages(client: AsyncFD) {.async.} =
   while true:
     var line = await recvLine(client)
     if line == "":
@@ -37,7 +37,7 @@ proc readMessages(client: TAsyncFD) {.async.} =
       else:
         doAssert false
 
-proc createServer(port: TPort) {.async.} =
+proc createServer(port: Port) {.async.} =
   var server = newAsyncNativeSocket()
   block:
     var name: Sockaddr_in
@@ -55,8 +55,8 @@ proc createServer(port: TPort) {.async.} =
   while true:
     asyncCheck readMessages(await accept(server))
 
-asyncCheck createServer(TPort(10335))
-asyncCheck launchSwarm(TPort(10335))
+asyncCheck createServer(Port(10335))
+asyncCheck launchSwarm(Port(10335))
 while true:
   poll()
   if clientCount == swarmSize: break
diff --git a/tests/collections/thashes.nim b/tests/collections/thashes.nim
index 76b99313c..5cc3cc8bb 100644
--- a/tests/collections/thashes.nim
+++ b/tests/collections/thashes.nim
@@ -3,7 +3,7 @@ discard """
 """
 
 import tables
-from hashes import THash
+from hashes import Hash
 
 # Test with int
 block:
@@ -66,7 +66,7 @@ block:
 # The same test with a custom hash(s: string) does
 # work though.
 block:
-  proc hash(x: int): THash {.inline.} =
+  proc hash(x: int): Hash {.inline.} =
     echo "overloaded hash"
     result = x
   var t = initTable[int, int]()
diff --git a/tests/collections/tsets.nim b/tests/collections/tsets.nim
index 6139560bd..61e14260a 100644
--- a/tests/collections/tsets.nim
+++ b/tests/collections/tsets.nim
@@ -1,4 +1,6 @@
 import sets
+import hashes
+import algorithm
 
 block setEquality:
   var
@@ -35,7 +37,7 @@ block setWithSequences:
   doAssert( not s.contains(@[4, 5, 6]) )
 
 block setClearWorked:
-  var s = initSet[char]() 
+  var s = initSet[char]()
 
   for c in "this is a test":
     s.incl(c)
@@ -68,12 +70,54 @@ block orderedSetClearWorked:
   for c in "eat at joes":
     s.incl(c)
 
-  r = "" 
+  r = ""
   for c in items(s):
     add(r, c)
 
   doAssert r == "zeat jos"
 
+block hashForHashedSet:
+  let
+    seq1 = "This is the test."
+    seq2 = "the test is This."
+    s1 = seq1.toSet()
+    s2 = seq2.toSet()
+  var hashSeq: seq[Hash] = @[]
+  doAssert s1 == s2
+  doAssert hash(s1) == hash(s2)
+
+block hashForOrderdSet:
+  let
+    str = "This is the test."
+    rstr = str.reversed
 
-
-
+  var
+    s1 = initOrderedSet[char]()
+    s2 = initOrderedSet[char]()
+    r = initOrderedSet[char]()
+    expected: Hash
+    added: seq[char] = @[]
+    reversed: Hash
+    radded: seq[char] = @[]
+
+  expected = 0
+  for c in str:
+    if (not (c in added)):
+      expected = expected !& hash(c)
+      added.add(c)
+    s1.incl(c)
+    s2.incl(c)
+  expected = !$expected
+  doAssert hash(s1) == expected
+  doAssert hash(s1) == hash(s2)
+  doAssert hash(s1) != hash(r)
+
+  reversed = 0
+  for c in rstr:
+    if (not (c in radded)):
+      reversed = reversed !& hash(c)
+      radded.add(c)
+    r.incl(c)
+  reversed = !$reversed
+  doAssert hash(r) == reversed
+  doAssert hash(s1) != reversed
diff --git a/tests/exprs/tstmtexprs.nim b/tests/exprs/tstmtexprs.nim
index 2a0ec2821..577f314ec 100644
--- a/tests/exprs/tstmtexprs.nim
+++ b/tests/exprs/tstmtexprs.nim
@@ -81,7 +81,7 @@ semiProblem()
 # bug #844
 
 import json
-proc parseResponse(): PJsonNode =
+proc parseResponse(): JsonNode =
   result = % { "key1": % { "key2": % "value" } }
   for key, val in result["key1"]:
     var excMsg = key & "("
diff --git a/tests/generics/module_with_generics.nim b/tests/generics/module_with_generics.nim
new file mode 100644
index 000000000..e801a4790
--- /dev/null
+++ b/tests/generics/module_with_generics.nim
@@ -0,0 +1,14 @@
+type
+  Base[T] = ref object {.inheritable.}
+    value*: T
+
+  Derived[T] = ref object of Base[T]
+    derivedValue*: T
+
+proc makeDerived*[T](v: T): Derived[T] =
+  new result
+  result.value = v
+
+proc setBaseValue*[T](a: Base[T], value: T) =
+  a.value = value
+
diff --git a/tests/generics/t5602_inheritence.nim b/tests/generics/t5602_inheritence.nim
index 6d48c796e..ee5ba89d5 100644
--- a/tests/generics/t5602_inheritence.nim
+++ b/tests/generics/t5602_inheritence.nim
@@ -1,10 +1,11 @@
 discard """
   output: "seq[float]\n0"
+  targets: "c cpp"
 """
 
 # https://github.com/nim-lang/Nim/issues/5602
 
-import typetraits
+import typetraits, module_with_generics
 
 type
   Foo[T] = object of RootObj
@@ -16,3 +17,8 @@ proc p[T](f: Foo[T]): T =
 var s: Bar[float]
 echo p(s).len # the bug was: p(s) should return seq[float], but returns float instead
 
+# Test overloading and code generation when
+# downcasting is required for generic types:
+var d = makeDerived(10)
+setBaseValue(d, 20)
+
diff --git a/tests/macros/tstructuredlogging.nim b/tests/macros/tstructuredlogging.nim
new file mode 100644
index 000000000..05bb52a40
--- /dev/null
+++ b/tests/macros/tstructuredlogging.nim
@@ -0,0 +1,154 @@
+discard """
+output: '''
+main started: a=10, b=inner-b, c=10, d=some-d, x=16, z=20
+exiting: a=12, b=overriden-b, c=100, msg=bye bye, x=16
+'''
+"""
+
+import macros, tables
+
+template scopeHolder =
+  0 # scope revision number
+
+type
+  BindingsSet = Table[string, NimNode]
+
+proc actualBody(n: NimNode): NimNode =
+  # skip over the double StmtList node introduced in `mergeScopes`
+  result = n.body
+  if result.kind == nnkStmtList and result[0].kind == nnkStmtList:
+    result = result[0]
+
+iterator bindings(n: NimNode, skip = 0): (string, NimNode) =
+  for i in skip ..< n.len:
+    let child = n[i]
+    if child.kind in {nnkAsgn, nnkExprEqExpr}:
+      let name = $child[0]
+      let value = child[1]
+      yield (name, value)
+
+proc scopeRevision(scopeHolder: NimNode): int =
+  # get the revision number from a scopeHolder sym
+  assert scopeHolder.kind == nnkSym
+  var revisionNode = scopeHolder.getImpl.actualBody[0]
+  result = int(revisionNode.intVal)
+
+proc lastScopeHolder(scopeHolders: NimNode): NimNode =
+  # get the most recent scopeHolder from a symChoice node
+  if scopeHolders.kind in {nnkClosedSymChoice, nnkOpenSymChoice}:
+    var bestScopeRev = 0
+    assert scopeHolders.len > 0
+    for scope in scopeHolders:
+      let rev = scope.scopeRevision
+      if result == nil or rev > bestScopeRev:
+        result = scope
+        bestScopeRev = rev
+  else:
+    result = scopeHolders
+
+  assert result.kind == nnkSym
+
+macro mergeScopes(scopeHolders: typed, newBindings: untyped): untyped =
+  var
+    bestScope = scopeHolders.lastScopeHolder
+    bestScopeRev = bestScope.scopeRevision
+
+  var finalBindings = initTable[string, NimNode]()
+  for k, v in bindings(bestScope.getImpl.actualBody, skip = 1):
+    finalBindings[k] = v
+
+  for k, v in bindings(newBindings):
+    finalBindings[k] = v
+
+  var newScopeDefinition = newStmtList(newLit(bestScopeRev + 1))
+
+  for k, v in finalBindings:
+    newScopeDefinition.add newAssignment(newIdentNode(k), v)
+
+  result = quote:
+    template scopeHolder = `newScopeDefinition`
+
+template scope(newBindings: untyped) {.dirty.} =
+  mergeScopes(bindSym"scopeHolder", newBindings)
+
+type
+  TextLogRecord = object
+    line: string
+
+  StdoutLogRecord = object
+
+template setProperty(r: var TextLogRecord, key: string, val: string, isFirst: bool) =
+  if not first: r.line.add ", "
+  r.line.add key
+  r.line.add "="
+  r.line.add val
+
+template setEventName(r: var StdoutLogRecord, name: string) =
+  stdout.write(name & ": ")
+
+template setProperty(r: var StdoutLogRecord, key: string, val: auto, isFirst: bool) =
+  when not isFirst: stdout.write ", "
+  stdout.write key
+  stdout.write "="
+  stdout.write $val
+
+template flushRecord(r: var StdoutLogRecord) =
+  stdout.write "\n"
+  stdout.flushFile
+
+macro logImpl(scopeHolders: typed,
+              logStmtProps: varargs[untyped]): untyped =
+  let lexicalScope = scopeHolders.lastScopeHolder.getImpl.actualBody
+  var finalBindings = initOrderedTable[string, NimNode]()
+
+  for k, v in bindings(lexicalScope, skip = 1):
+    finalBindings[k] = v
+
+  for k, v in bindings(logStmtProps, skip = 1):
+    finalBindings[k] = v
+
+  finalBindings.sort(system.cmp)
+
+  let eventName = logStmtProps[0]
+  assert eventName.kind in {nnkStrLit}
+  let record = genSym(nskVar, "record")
+
+  result = quote:
+    var `record`: StdoutLogRecord
+    setEventName(`record`, `eventName`)
+
+  var isFirst = true
+  for k, v in finalBindings:
+    result.add newCall(newIdentNode"setProperty",
+                       record, newLit(k), v, newLit(isFirst))
+    isFirst = false
+
+  result.add newCall(newIdentNode"flushRecord", record)
+
+template log(props: varargs[untyped]) {.dirty.} =
+  logImpl(bindSym"scopeHolder", props)
+
+scope:
+  a = 12
+  b = "original-b"
+
+scope:
+  x = 16
+  b = "overriden-b"
+
+scope:
+  c = 100
+
+proc main =
+  scope:
+    c = 10
+
+  scope:
+    z = 20
+
+  log("main started", a = 10, b = "inner-b", d = "some-d")
+
+main()
+
+log("exiting", msg = "bye bye")
+
diff --git a/tests/macros/ttemplatesymbols.nim b/tests/macros/ttemplatesymbols.nim
new file mode 100644
index 000000000..8d9c9ec02
--- /dev/null
+++ b/tests/macros/ttemplatesymbols.nim
@@ -0,0 +1,173 @@
+import
+  macros, algorithm, strutils
+
+proc normalProc(x: int) =
+  echo x
+
+template templateWithtouParams =
+  echo 10
+
+proc overloadedProc(x: int) =
+  echo x
+
+proc overloadedProc(x: string) =
+  echo x
+
+proc overloadedProc[T](x: T) =
+  echo x
+
+template normalTemplate(x: int) =
+  echo x
+
+template overloadedTemplate(x: int) =
+  echo x
+
+template overloadedTemplate(x: string) =
+  echo x
+
+macro normalMacro(x: int): untyped =
+  discard
+
+macro macroWithoutParams: untyped =
+  discard
+
+macro inspectSymbol(sym: typed, expected: static[string]): untyped =
+  if sym.kind == nnkSym:
+    echo "Symbol node:"
+    let res = sym.getImpl.repr & "\n"
+    echo res
+    # echo "|", res, "|"
+    # echo "|", expected, "|"
+    if expected.len > 0: assert res == expected
+  elif sym.kind in {nnkClosedSymChoice, nnkOpenSymChoice}:
+    echo "Begin sym choice:"
+    var results = newSeq[string](0)
+    for innerSym in sym:
+      results.add innerSym.getImpl.repr
+    sort(results, cmp[string])
+    let res = results.join("\n") & "\n"
+    echo res
+    if expected.len > 0: assert res == expected
+    echo "End symchoice."
+  else:
+    echo "Non-symbol node: ", sym.kind
+    if expected.len > 0: assert $sym.kind == expected
+
+macro inspectUntyped(sym: untyped, expected: static[string]): untyped =
+  let res = sym.repr
+  echo "Untyped node: ", res
+  assert res == expected
+
+inspectSymbol templateWithtouParams, "nnkCommand"
+  # this template is expanded, because bindSym was not used
+  # the end result is the template body (nnkCommand)
+
+inspectSymbol bindSym("templateWithtouParams"), """
+template templateWithtouParams() =
+  echo 10
+
+"""
+
+inspectSymbol macroWithoutParams, "nnkEmpty"
+  # Just like the template above, the macro was expanded
+
+inspectSymbol bindSym("macroWithoutParams"), """
+macro macroWithoutParams(): untyped =
+  discard
+
+"""
+
+inspectSymbol normalMacro, """
+macro normalMacro(x: int): untyped =
+  discard
+
+"""
+  # Since the normalMacro has params, it's automatically
+  # treated as a symbol here (no need for `bindSym`)
+
+inspectSymbol bindSym("normalMacro"), """
+macro normalMacro(x: int): untyped =
+  discard
+
+"""
+
+inspectSymbol normalTemplate, """
+template normalTemplate(x: int) =
+  echo x
+
+"""
+
+inspectSymbol bindSym("normalTemplate"), """
+template normalTemplate(x: int) =
+  echo x
+
+"""
+
+inspectSymbol overloadedTemplate, """
+template overloadedTemplate(x: int) =
+  echo x
+
+template overloadedTemplate(x: string) =
+  echo x
+
+"""
+
+inspectSymbol bindSym("overloadedTemplate"), """
+template overloadedTemplate(x: int) =
+  echo x
+
+template overloadedTemplate(x: string) =
+  echo x
+
+"""
+
+inspectUntyped bindSym("overloadedTemplate"), """bindSym("overloadedTemplate")"""
+  # binSym is active only in the presense of `typed` params.
+  # `untyped` params still get the raw AST
+
+inspectSymbol normalProc, """
+proc normalProc(x: int) =
+  echo [x]
+
+"""
+
+inspectSymbol bindSym("normalProc"), """
+proc normalProc(x: int) =
+  echo [x]
+
+"""
+
+inspectSymbol overloadedProc, """
+proc overloadedProc(x: int) =
+  echo [x]
+
+proc overloadedProc(x: string) =
+  echo [x]
+
+proc overloadedProc[T](x: T) =
+  echo x
+
+"""
+  # XXX: There seems to be a repr rendering problem above.
+  # Notice that `echo [x]`
+
+inspectSymbol overloadedProc[float], """
+proc overloadedProc(x: T) =
+  echo [x]
+
+"""
+  # As expected, when we select a specific generic, the
+  # AST is no longer a symChoice
+
+inspectSymbol bindSym("overloadedProc"), """
+proc overloadedProc(x: int) =
+  echo [x]
+
+proc overloadedProc(x: string) =
+  echo [x]
+
+proc overloadedProc[T](x: T) =
+  echo x
+
+"""
+
diff --git a/tests/misc/tsimplesort.nim b/tests/misc/tsimplesort.nim
index 3115863d5..e4a8e0b37 100644
--- a/tests/misc/tsimplesort.nim
+++ b/tests/misc/tsimplesort.nim
@@ -40,11 +40,11 @@ proc mustRehash(length, counter: int): bool {.inline.} =
   assert(length > counter)
   result = (length * 2 < counter * 3) or (length - counter < 4)
 
-proc nextTry(h, maxHash: THash): THash {.inline.} =
+proc nextTry(h, maxHash: Hash): Hash {.inline.} =
   result = ((5 * h) + 1) and maxHash
 
 template rawGetImpl() =
-  var h: THash = hash(key) and high(t.data) # start with real hash value
+  var h: Hash = hash(key) and high(t.data) # start with real hash value
   while t.data[h].slot != seEmpty:
     if t.data[h].key == key and t.data[h].slot == seFilled:
       return h
@@ -52,7 +52,7 @@ template rawGetImpl() =
   result = -1
 
 template rawInsertImpl() =
-  var h: THash = hash(key) and high(data)
+  var h: Hash = hash(key) and high(data)
   while data[h].slot == seFilled:
     h = nextTry(h, high(data))
   data[h].key = key
@@ -162,7 +162,7 @@ iterator values*[A](t: TCountTable[A]): int =
     if t.data[h].val != 0: yield t.data[h].val
 
 proc RawGet[A](t: TCountTable[A], key: A): int =
-  var h: THash = hash(key) and high(t.data) # start with real hash value
+  var h: Hash = hash(key) and high(t.data) # start with real hash value
   while t.data[h].val != 0:
     if t.data[h].key == key: return h
     h = nextTry(h, high(t.data))
@@ -181,7 +181,7 @@ proc hasKey*[A](t: TCountTable[A], key: A): bool =
 
 proc rawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]],
                   key: A, val: int) =
-  var h: THash = hash(key) and high(data)
+  var h: Hash = hash(key) and high(data)
   while data[h].val != 0: h = nextTry(h, high(data))
   data[h].key = key
   data[h].val = val
diff --git a/tests/modules/definitions.nim b/tests/modules/definitions.nim
new file mode 100644
index 000000000..edc6eaa6d
--- /dev/null
+++ b/tests/modules/definitions.nim
@@ -0,0 +1,4 @@
+var v*: int
+proc p* = echo "proc p called"
+template t* = echo "template t expanded"
+
diff --git a/tests/modules/proxy_module.nim b/tests/modules/proxy_module.nim
new file mode 100644
index 000000000..c244688cd
--- /dev/null
+++ b/tests/modules/proxy_module.nim
@@ -0,0 +1,3 @@
+import definitions
+export definitions except p
+
diff --git a/tests/overload/tparam_forwarding.nim b/tests/overload/tparam_forwarding.nim
index c1b276bfc..b0eea42c7 100644
--- a/tests/overload/tparam_forwarding.nim
+++ b/tests/overload/tparam_forwarding.nim
@@ -6,6 +6,10 @@ output: '''baz
 a
 b
 c
+x: 1, y: test 1
+x: 2, y: test 2
+x: 10, y: test 3
+x: 4, y: test 4
 '''
 """
 
@@ -35,3 +39,15 @@ templateForwarding fooVarargs, "test".len > 3, Foo(x: 10), Foo(x: 100), Foo(x: 1
 
 procForwarding "a", "b", "c"
 
+proc hasKeywordArgs(x = 10, y = "y") =
+  echo "x: ", x, ", y: ", y
+
+proc hasRegularArgs(x: int, y: string) =
+  echo "x: ", x, ", y: ", y
+
+templateForwarding(hasRegularArgs, true, 1, "test 1")
+templateForwarding hasKeywordArgs, true, 2, "test 2"
+
+templateForwarding(hasKeywordArgs, true, y = "test 3")
+templateForwarding hasKeywordArgs, true, y = "test 4", x = 4
+
diff --git a/tests/parser/tbraces.nim b/tests/parser/tbraces.nim
deleted file mode 100644
index 86c854546..000000000
--- a/tests/parser/tbraces.nim
+++ /dev/null
@@ -1,432 +0,0 @@
-#? braces
-
-#
-#
-#            Nim's Runtime Library
-#        (c) Copyright 2015 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-## This module implements some common generic algorithms.
-
-type
-  SortOrder* = enum {  ## sort order
-    Descending, Ascending
-  }
-
-
-type(
-  DummyAlias = int
-  OtherAlias = distinct char
-
-  SomeObject = object of RootObj { ## declaration here
-    fieldA, fieldB: int
-    case order: SortOrder {
-      of Descending {a: string}
-      of Ascending {b: seq[char]}
-    }
-  }
-
-  MyConcept = concept x {
-     x is int
-  }
-)
-
-{.deprecated: [TSortOrder: SortOrder].}
-
-
-proc `*`*(x: int, order: SortOrder): int @inline {
-  ## flips `x` if ``order == Descending``;
-  ## if ``order == Ascending`` then `x` is returned.
-  ## `x` is supposed to be the result of a comparator, ie ``< 0`` for
-  ## *less than*, ``== 0`` for *equal*, ``> 0`` for *greater than*.
-  var y = order.ord - 1
-  result = (x xor y) - y
-}
-
-proc fill*[T](a: var openArray[T], first, last: Natural, value: T) {
-  ## fills the array ``a[first..last]`` with `value`.
-  var x = first
-  while x <= last {
-    a[x] = value
-    inc(x)
-  }
-}
-
-proc fill*[T](a: var openArray[T], value: T) {
-  ## fills the array `a` with `value`.
-  fill(a, 0, a.high, value)
-}
-
-proc reverse*[T](a: var openArray[T], first, last: Natural) {
-  ## reverses the array ``a[first..last]``.
-  var x = first
-  var y = last
-  while x < y {
-    swap(a[x], a[y])
-    dec(y)
-    inc(x)
-  }
-}
-
-proc reverse*[T](a: var openArray[T]) {
-  ## reverses the array `a`.
-  reverse(a, 0, a.high)
-}
-
-proc reversed*[T](a: openArray[T], first: Natural, last: int): seq[T] {
-  ## returns the reverse of the array `a[first..last]`.
-  assert last >= first-1
-  var i = last - first
-  var x = first.int
-  result = newSeq[T](i + 1)
-  while i >= 0 {
-    result[i] = a[x]
-    dec(i)
-    inc(x)
-  }
-}
-
-proc reversed*[T](a: openArray[T]): seq[T] {
-  ## returns the reverse of the array `a`.
-  reversed(a, 0, a.high)
-}
-
-proc binarySearch*[T](a: openArray[T], key: T): int {
-  ## binary search for `key` in `a`. Returns -1 if not found.
-  var b = len(a)
-  while result < b {
-    var mid = (result + b) div 2
-    if a[mid] < key { result = mid + 1 } else { b = mid }
-  }
-  if result >= len(a) or a[result] != key { result = -1 }
-}
-
-proc smartBinarySearch*[T](a: openArray[T], key: T): int {
-  ## ``a.len`` must be a power of 2 for this to work.
-  var step = a.len div 2
-  while step > 0 {
-    if a[result or step] <= key { result = result or step }
-    step = step shr 1
-  }
-  if a[result] != key { result = -1 }
-}
-
-const (
-  onlySafeCode = true
-)
-
-proc lowerBound*[T](a: openArray[T], key: T, cmp: proc(x,y: T): int @closure): int {
-  ## same as binarySearch except that if key is not in `a` then this
-  ## returns the location where `key` would be if it were. In other
-  ## words if you have a sorted sequence and you call
-  ## insert(thing, elm, lowerBound(thing, elm))
-  ## the sequence will still be sorted.
-  ##
-  ## `cmp` is the comparator function to use, the expected return values are
-  ## the same as that of system.cmp.
-  ##
-  ## example::
-  ##
-  ##   var arr = @[1,2,3,5,6,7,8,9]
-  ##   arr.insert(4, arr.lowerBound(4))
-  ##   # after running the above arr is `[1,2,3,4,5,6,7,8,9]`
-  result = a.low
-  var count = a.high - a.low + 1
-  var step, pos: int
-  while count != 0 {
-    step = count div 2
-    pos = result + step
-    if cmp(a[pos], key) < 0 {
-      result = pos + 1
-      count -= step + 1
-    } else {
-      count = step
-    }
-  }
-}
-
-proc lowerBound*[T](a: openArray[T], key: T): int { lowerBound(a, key, cmp[T]) }
-proc merge[T](a, b: var openArray[T], lo, m, hi: int,
-              cmp: proc (x, y: T): int @closure, order: SortOrder) {
-  template `<-` (a, b) {
-    when false {
-      a = b
-    } elif onlySafeCode {
-      shallowCopy(a, b)
-    } else {
-      copyMem(addr(a), addr(b), sizeof(T))
-    }
-  }
-  # optimization: If max(left) <= min(right) there is nothing to do!
-  # 1 2 3 4  ## 5 6 7 8
-  # -> O(n) for sorted arrays.
-  # On random data this safes up to 40% of merge calls
-  if cmp(a[m], a[m+1]) * order <= 0 { return }
-  var j = lo
-  # copy a[j..m] into b:
-  assert j <= m
-  when onlySafeCode {
-    var bb = 0
-    while j <= m {
-      b[bb] <- a[j]
-      inc(bb)
-      inc(j)
-    }
-  } else {
-    copyMem(addr(b[0]), addr(a[j]), sizeof(T)*(m-j+1))
-    j = m+1
-  }
-  var i = 0
-  var k = lo
-  # copy proper element back:
-  while k < j and j <= hi {
-    if cmp(b[i], a[j]) * order <= 0 {
-      a[k] <- b[i]
-      inc(i)
-    } else {
-      a[k] <- a[j]
-      inc(j)
-    }
-    inc(k)
-  }
-  # copy rest of b:
-  when onlySafeCode {
-    while k < j {
-      a[k] <- b[i]
-      inc(k)
-      inc(i)
-    }
-  } else {
-    if k < j { copyMem(addr(a[k]), addr(b[i]), sizeof(T)*(j-k)) }
-  }
-}
-
-proc sort*[T](a: var openArray[T],
-              cmp: proc (x, y: T): int @closure,
-              order = SortOrder.Ascending) {
-  ## Default Nim sort (an implementation of merge sort). The sorting
-  ## is guaranteed to be stable and the worst case is guaranteed to
-  ## be O(n log n).
-  ## The current implementation uses an iterative
-  ## mergesort to achieve this. It uses a temporary sequence of
-  ## length ``a.len div 2``. Currently Nim does not support a
-  ## sensible default argument for ``cmp``, so you have to provide one
-  ## of your own. However, the ``system.cmp`` procs can be used:
-  ##
-  ## .. code-block:: nim
-  ##
-  ##    sort(myIntArray, system.cmp[int])
-  ##
-  ##    # do not use cmp[string] here as we want to use the specialized
-  ##    # overload:
-  ##    sort(myStrArray, system.cmp)
-  ##
-  ## You can inline adhoc comparison procs with the `do notation
-  ## <manual.html#procedures-do-notation>`_. Example:
-  ##
-  ## .. code-block:: nim
-  ##
-  ##   people.sort do (x, y: Person) -> int:
-  ##     result = cmp(x.surname, y.surname)
-  ##     if result == 0:
-  ##       result = cmp(x.name, y.name)
-  var n = a.len
-  var b: seq[T]
-  newSeq(b, n div 2)
-  var s = 1
-  while s < n {
-    var m = n-1-s
-    while m >= 0 {
-      merge(a, b, max(m-s+1, 0), m, m+s, cmp, order)
-      dec(m, s*2)
-    }
-    s = s*2
-  }
-}
-
-proc sorted*[T](a: openArray[T], cmp: proc(x, y: T): int {.closure.},
-                order = SortOrder.Ascending): seq[T] {
-  ## returns `a` sorted by `cmp` in the specified `order`.
-  result = newSeq[T](a.len)
-  for i in 0 .. a.high { result[i] = a[i] }
-  sort(result, cmp, order)
-}
-
-template sortedByIt*(seq1, op: untyped): untyped {
-  ## Convenience template around the ``sorted`` proc to reduce typing.
-  ##
-  ## The template injects the ``it`` variable which you can use directly in an
-  ## expression. Example:
-  ##
-  ## .. code-block:: nim
-  ##
-  ##   type Person = tuple[name: string, age: int]
-  ##   var
-  ##     p1: Person = (name: "p1", age: 60)
-  ##     p2: Person = (name: "p2", age: 20)
-  ##     p3: Person = (name: "p3", age: 30)
-  ##     p4: Person = (name: "p4", age: 30)
-  ##     people = @[p1,p2,p4,p3]
-  ##
-  ##   echo people.sortedByIt(it.name)
-  ##
-  ## Because the underlying ``cmp()`` is defined for tuples you can do
-  ## a nested sort like in the following example:
-  ##
-  ## .. code-block:: nim
-  ##
-  ##   echo people.sortedByIt((it.age, it.name))
-  ##
-  var result = sorted(seq1, proc(x, y: type[seq1[0]]): int {
-    var it {.inject.} = x
-    let a = op
-    it = y
-    let b = op
-    result = cmp(a, b)
-  })
-  result
-}
-
-proc isSorted*[T](a: openarray[T],
-                 cmp: proc(x, y: T): int {.closure.},
-                 order = SortOrder.Ascending): bool {
-  ## Checks to see whether `a` is already sorted in `order`
-  ## using `cmp` for the comparison. Parameters identical
-  ## to `sort`
-  result = true
-  for i in 0..<len(a)-1 {
-    case cmp(a[i],a[i+1]) * order > 0 {
-      of true { return false }
-      of false {}
-    }
-  }
-}
-
-proc product*[T](x: openArray[seq[T]]): seq[seq[T]] {
-  ## produces the Cartesian product of the array. Warning: complexity
-  ## may explode.
-  result = newSeq[seq[T]]()
-  if x.len == 0 { return }
-  if x.len == 1 {
-    result = @x
-    return
-  }
-  var (
-    indexes = newSeq[int](x.len)
-    initial = newSeq[int](x.len)
-    index = 0
-  )
-  var next = newSeq[T]()
-  next.setLen(x.len)
-  for i in 0..(x.len-1) {
-    if len(x[i]) == 0 { return }
-    initial[i] = len(x[i])-1
-  }
-  indexes = initial
-  while true {
-    while indexes[index] == -1 {
-      indexes[index] = initial[index]
-      index += 1
-      if index == x.len { return }
-      indexes[index] -= 1
-    }
-    for ni, i in indexes {
-      next[ni] = x[ni][i]
-    }
-    var res: seq[T]
-    shallowCopy(res, next)
-    result.add(res)
-    index = 0
-    indexes[index] -= 1
-  }
-}
-
-proc nextPermutation*[T](x: var openarray[T]): bool {.discardable.} {
-  ## Calculates the next lexicographic permutation, directly modifying ``x``.
-  ## The result is whether a permutation happened, otherwise we have reached
-  ## the last-ordered permutation.
-  ##
-  ## .. code-block:: nim
-  ##
-  ##     var v = @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-  ##     v.nextPermutation()
-  ##     echo v # @[0, 1, 2, 3, 4, 5, 6, 7, 9, 8]
-  if x.len < 2 {
-    return false }
-
-  var i = x.high
-  while i > 0 and x[i-1] >= x[i] { dec i }
-  if i == 0 { return false }
-
-  var j = x.high
-  while j >= i and x[j] <= x[i-1] { dec j }
-
-  swap x[j], x[i-1]
-  x.reverse(i, x.high)
-
-  result = true
-}
-
-proc prevPermutation*[T](x: var openarray[T]): bool @discardable {
-  ## Calculates the previous lexicographic permutation, directly modifying
-  ## ``x``.  The result is whether a permutation happened, otherwise we have
-  ## reached the first-ordered permutation.
-  ##
-  ## .. code-block:: nim
-  ##
-  ##     var v = @[0, 1, 2, 3, 4, 5, 6, 7, 9, 8]
-  ##     v.prevPermutation()
-  ##     echo v # @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-  if x.len < 2 { return false }
-
-  var i = x.high
-  while i > 0 and x[i-1] <= x[i] {
-    dec i
-  }
-  if i == 0 { return false }
-
-  x.reverse(i, x.high)
-
-  var j = x.high
-  while j >= i and x[j-1] < x[i-1] {
-    dec j
-  }
-  swap x[i-1], x[j]
-
-  result = true
-}
-
-when isMainModule {
-  # Tests for lowerBound
-  var arr = @[1,2,3,5,6,7,8,9]
-  assert arr.lowerBound(0) == 0
-  assert arr.lowerBound(4) == 3
-  assert arr.lowerBound(5) == 3
-  assert arr.lowerBound(10) == 8
-  arr = @[1,5,10]
-  try {
-    assert arr.lowerBound(4) == 1
-    assert arr.lowerBound(5) == 1
-    assert arr.lowerBound(6) == 2
-  } except ValueError {}
-  # Tests for isSorted
-  var srt1 = [1,2,3,4,4,4,4,5]
-  var srt2 = ["iello","hello"]
-  var srt3 = [1.0,1.0,1.0]
-  var srt4: seq[int] = @[]
-  assert srt1.isSorted(cmp) == true
-  assert srt2.isSorted(cmp) == false
-  assert srt3.isSorted(cmp) == true
-  var srtseq = newSeq[int]()
-  assert srtseq.isSorted(cmp) == true
-  # Tests for reversed
-  var arr1 = @[0,1,2,3,4]
-  assert arr1.reversed() == @[4,3,2,1,0]
-  for i in 0 .. high(arr1) {
-    assert arr1.reversed(0, i) == arr1.reversed()[high(arr1) - i .. high(arr1)]
-    assert arr1.reversed(i, high(arr1)) == arr1.reversed()[0 .. high(arr1) - i]
-  }
-}
diff --git a/tests/parser/tcommand_as_expr.nim b/tests/parser/tcommand_as_expr.nim
index a244c8767..b25ec4bd8 100644
--- a/tests/parser/tcommand_as_expr.nim
+++ b/tests/parser/tcommand_as_expr.nim
@@ -2,7 +2,10 @@ discard """
   output: '''140
 5-120-120
 359
-77'''
+77
+-4
+-1
+-1'''
 """
 #import math
 import sequtils
@@ -25,3 +28,11 @@ let a = [2,4,8].map do (d:int) -> int: d + 1
 echo a[0], a[1], a[2]
 
 echo(foo 8, foo 8)
+
+# bug #7582
+proc f(x: int): int = x
+
+echo f -4
+
+echo int -1 # doesn't compile
+echo int `-` 1 # compiles
diff --git a/tests/parser/twrongcmdsyntax.nim b/tests/parser/twrongcmdsyntax.nim
index affe72c34..c2962bed4 100644
--- a/tests/parser/twrongcmdsyntax.nim
+++ b/tests/parser/twrongcmdsyntax.nim
@@ -1,5 +1,5 @@
 discard """
-  errormsg: '''identifier expected, but found 'echo 4'''
+  errormsg: '''in expression '4 2': identifier expected, but found '4'''
   line: 6
 """
 
diff --git a/tests/stdlib/ttimes.nim b/tests/stdlib/ttimes.nim
index 37e14c1e2..4ab3ba581 100644
--- a/tests/stdlib/ttimes.nim
+++ b/tests/stdlib/ttimes.nim
@@ -28,6 +28,12 @@ t.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" &
 
 t.checkFormat("yyyyMMddhhmmss", "20380119031407")
 
+# issue 7620
+let t7620_am = parse("4/15/2017 12:01:02 AM +0", "M/d/yyyy' 'h:mm:ss' 'tt' 'z", utc())
+t7620_am.checkFormat("M/d/yyyy' 'h:mm:ss' 'tt' 'z", "4/15/2017 12:01:02 AM +0")
+let t7620_pm = parse("4/15/2017 12:01:02 PM +0", "M/d/yyyy' 'h:mm:ss' 'tt' 'z", utc())
+t7620_pm.checkFormat("M/d/yyyy' 'h:mm:ss' 'tt' 'z", "4/15/2017 12:01:02 PM +0")
+
 let t2 = fromUnix(160070789).utc # Mon 27 Jan 16:06:29 GMT 1975
 t2.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" &
   " ss t tt y yy yyy yyyy yyyyy z zz zzz",
diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim
index f08c83079..0c6f376d3 100644
--- a/tests/testament/tester.nim
+++ b/tests/testament/tester.nim
@@ -212,18 +212,18 @@ proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest, target: TTarg
   elif expected.tfile == "" and extractFilename(expected.file) != extractFilename(given.file) and
       "internal error:" notin expected.msg:
     r.addResult(test, target, expected.file, given.file, reFilesDiffer)
-  elif expected.line   != given.line   and expected.line   != 0 or
+  elif expected.line != given.line and expected.line != 0 or
        expected.column != given.column and expected.column != 0:
     r.addResult(test, target, $expected.line & ':' & $expected.column,
-                      $given.line    & ':' & $given.column,
+                      $given.line & ':' & $given.column,
                       reLinesDiffer)
   elif expected.tfile != "" and extractFilename(expected.tfile) != extractFilename(given.tfile) and
       "internal error:" notin expected.msg:
     r.addResult(test, target, expected.tfile, given.tfile, reFilesDiffer)
-  elif expected.tline   != given.tline   and expected.tline   != 0 or
+  elif expected.tline != given.tline and expected.tline != 0 or
        expected.tcolumn != given.tcolumn and expected.tcolumn != 0:
     r.addResult(test, target, $expected.tline & ':' & $expected.tcolumn,
-                      $given.tline    & ':' & $given.tcolumn,
+                      $given.tline & ':' & $given.tcolumn,
                       reLinesDiffer)
   else:
     r.addResult(test, target, expected.msg, given.msg, reSuccess)
diff --git a/tests/threads/tthreadvars.nim b/tests/threads/tthreadvars.nim
new file mode 100644
index 000000000..81aa2e5ec
--- /dev/null
+++ b/tests/threads/tthreadvars.nim
@@ -0,0 +1,78 @@
+discard """
+output: '''
+10
+1111
+1222
+3030303
+3060606
+6060606
+6121212
+3030903
+3061206
+3031503
+3061806
+5050505
+5101010
+'''
+"""
+
+import typetraits
+
+var tls1 {.threadvar.}: int
+var g0: int
+var g1 {.global.}: int
+
+proc customInc(x: var int, delta: int) =
+  x += delta
+
+customInc(tls1, 10)
+echo tls1
+
+proc nonGenericProc: int =
+  var local: int
+  var nonGenericTls {.threadvar.}: int
+  var nonGenericGlobal {.global.}: int
+  var nonGenericMixedPragmas {.global, threadvar.}: int
+
+  customInc local, 1000
+  customInc nonGenericTls, 1
+  customInc nonGenericGlobal, 10
+  customInc nonGenericMixedPragmas, 100
+
+  return local + nonGenericTls + nonGenericGlobal + nonGenericMixedPragmas
+
+proc genericProc(T: typedesc): int =
+  var local: int
+  var genericTls {.threadvar.}: int
+  var genericGlobal {.global.}: int
+  var genericMixedPragmas {.global, threadvar.}: int
+
+  customInc local, T.name.len * 1000000
+  customInc genericTls, T.name.len * 1
+  customInc genericGlobal, T.name.len * 100
+  customInc genericMixedPragmas, T.name.len * 10000
+
+  return local + genericTls + genericGlobal + genericMixedPragmas
+
+echo nonGenericProc()
+echo nonGenericProc()
+
+echo genericProc(int)
+echo genericProc(int)
+
+echo genericProc(string)
+echo genericProc(string)
+
+proc echoInThread[T]() {.thread.} =
+  echo genericProc(T)
+  echo genericProc(T)
+
+proc newEchoThread(T: typedesc) =
+  var t: Thread[void]
+  createThread(t, echoInThread[T])
+  joinThreads(t)
+
+newEchoThread int
+newEchoThread int
+newEchoThread float
+
diff --git a/tests/trmacros/thoist.nim b/tests/trmacros/thoist.nim
index 7d14c0abf..657f210a1 100644
--- a/tests/trmacros/thoist.nim
+++ b/tests/trmacros/thoist.nim
@@ -5,7 +5,7 @@ true'''
 
 import pegs
 
-template optPeg{peg(pattern)}(pattern: string{lit}): TPeg =
+template optPeg{peg(pattern)}(pattern: string{lit}): Peg =
   var gl {.global, gensym.} = peg(pattern)
   gl
 
diff --git a/tests/typerel/texplicitcmp.nim b/tests/typerel/texplicitcmp.nim
index 8aec9885a..e91ac2ffe 100644
--- a/tests/typerel/texplicitcmp.nim
+++ b/tests/typerel/texplicitcmp.nim
@@ -18,7 +18,7 @@ proc works() =
   sort(f, system.cmp[int])
   outp(f)
 
-proc weird(json_params: TTable) =
+proc weird(json_params: Table) =
   var f = @[3, 2, 1]
   # The following line doesn't compile: type mismatch. Why?
   sort(f, system.cmp[int])
@@ -29,4 +29,4 @@ when isMainModule:
   sort(t, system.cmp[int])
   outp(t)
   works()
-  weird(initTable[string, TJsonNode]())
+  weird(initTable[string, JsonNode]())
diff --git a/tests/vm/tref.nim b/tests/vm/tref.nim
new file mode 100644
index 000000000..517a67fb0
--- /dev/null
+++ b/tests/vm/tref.nim
@@ -0,0 +1,12 @@
+static:
+  var
+    a: ref string
+    b: ref string
+  new a
+
+  a[] = "Hello world"
+  b = a
+
+  b[5] = 'c'
+  doAssert a[] == "Hellocworld"
+  doAssert b[] == "Hellocworld"
\ No newline at end of file