summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/sempass2.nim3
-rw-r--r--lib/core/macros.nim20
-rw-r--r--lib/pure/collections/tables.nim2
-rw-r--r--lib/pure/math.nim8
-rw-r--r--lib/pure/net.nim9
-rw-r--r--lib/pure/os.nim6
-rw-r--r--lib/pure/times.nim102
-rw-r--r--lib/system.nim38
-rw-r--r--lib/system/repr.nim6
-rw-r--r--tests/collections/tindexby.nim22
-rw-r--r--tests/collections/ttableconstr.nim (renamed from tests/table/ttableconstr.nim)0
-rw-r--r--tests/collections/ttables.nim148
-rw-r--r--tests/collections/ttables2.nim (renamed from tests/table/ttables2.nim)0
-rw-r--r--tests/collections/ttablesref.nim (renamed from tests/table/ptables.nim)2
-rw-r--r--tests/collections/ttablesref2.nim (renamed from tests/table/ptables2.nim)0
-rw-r--r--tests/stdlib/tircbot.nim453
-rw-r--r--tests/stdlib/tmitems.nim2
-rw-r--r--tests/table/ttables.nim128
-rw-r--r--todo.txt1
19 files changed, 246 insertions, 704 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index ede556a70..6fa7c756e 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -859,7 +859,8 @@ proc trackProc*(s: PSym, body: PNode) =
     if s.typ.lockLevel == UnspecifiedLockLevel:
       s.typ.lockLevel = t.maxLockLevel
     elif t.maxLockLevel > s.typ.lockLevel:
-      localError(s.info,
+      #localError(s.info,
+      message(s.info, warnLockLevel,
         "declared lock level is $1, but real lock level is $2" %
           [$s.typ.lockLevel, $t.maxLockLevel])
 
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 22b9c4907..4c561df70 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -136,12 +136,12 @@ proc len*(n: PNimrodNode): int {.magic: "NLen", noSideEffect.}
   ## returns the number of children of `n`.
 
 proc add*(father, child: PNimrodNode): PNimrodNode {.magic: "NAdd", discardable,
-  noSideEffect.}
+  noSideEffect, locks: 0.}
   ## Adds the `child` to the `father` node. Returns the
   ## father node so that calls can be nested.
 
 proc add*(father: PNimrodNode, children: varargs[PNimrodNode]): PNimrodNode {.
-  magic: "NAddMultiple", discardable, noSideEffect.}
+  magic: "NAddMultiple", discardable, noSideEffect, locks: 0.}
   ## Adds each child of `children` to the `father` node.
   ## Returns the `father` node so that calls can be nested.
 
@@ -177,13 +177,13 @@ proc newNimNode*(kind: TNimrodNodeKind,
 proc copyNimNode*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimNode", noSideEffect.}
 proc copyNimTree*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimTree", noSideEffect.}
 
-proc error*(msg: string) {.magic: "NError", gcsafe.}
+proc error*(msg: string) {.magic: "NError", benign.}
   ## writes an error message at compile time
 
-proc warning*(msg: string) {.magic: "NWarning", gcsafe.}
+proc warning*(msg: string) {.magic: "NWarning", benign.}
   ## writes a warning message at compile time
 
-proc hint*(msg: string) {.magic: "NHint", gcsafe.}
+proc hint*(msg: string) {.magic: "NHint", benign.}
   ## writes a hint message at compile time
 
 proc newStrLitNode*(s: string): PNimrodNode {.compileTime, noSideEffect.} =
@@ -237,7 +237,7 @@ proc genSym*(kind: TNimrodSymKind = nskLet; ident = ""): PNimrodNode {.
   ## generates a fresh symbol that is guaranteed to be unique. The symbol
   ## needs to occur in a declaration context.
 
-proc callsite*(): PNimrodNode {.magic: "NCallSite", gcsafe.}
+proc callsite*(): PNimrodNode {.magic: "NCallSite", benign.}
   ## returns the AST of the invocation expression that invoked this macro.
 
 proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
@@ -387,11 +387,11 @@ proc nestList*(theProc: TNimrodIdent,
     # This could easily user code and so should be fixed in evals.nim somehow.
     result = newCall(theProc, x[i], copyNimTree(result))
 
-proc treeRepr*(n: PNimrodNode): string {.compileTime.} =
+proc treeRepr*(n: PNimrodNode): string {.compileTime, benign.} =
   ## Convert the AST `n` to a human-readable tree-like string.
   ##
   ## See also `repr` and `lispRepr`.
-  proc traverse(res: var string, level: int, n: PNimrodNode) =
+  proc traverse(res: var string, level: int, n: PNimrodNode) {.benign.} =
     for i in 0..level-1: res.add "  "
     res.add(($n.kind).substr(3))
 
@@ -412,7 +412,7 @@ proc treeRepr*(n: PNimrodNode): string {.compileTime.} =
   result = ""
   traverse(result, 0, n)
 
-proc lispRepr*(n: PNimrodNode): string {.compileTime.} =
+proc lispRepr*(n: PNimrodNode): string {.compileTime, benign.} =
   ## Convert the AST `n` to a human-readable lisp-like string,
   ##
   ## See also `repr` and `treeRepr`.
@@ -651,7 +651,7 @@ proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} =
   else:
     badNodeKind someProc.kind, "body="
 
-proc basename*(a: PNimrodNode): PNimrodNode {.compiletime.}
+proc basename*(a: PNimrodNode): PNimrodNode {.compiletime, benign.}
 
 
 proc `$`*(node: PNimrodNode): string {.compileTime.} =
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 9dcc97148..671f767cf 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -347,7 +347,7 @@ proc `$`*[A, B](t: TableRef[A, B]): string =
 proc `==`*[A, B](s, t: TableRef[A, B]): bool =
   if isNil(s): result = isNil(t)
   elif isNil(t): result = false
-  else: result = equalsImpl()
+  else: equalsImpl()
 
 proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): TableRef[C, B] =
   ## Index the collection with the proc provided.
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index b9e057e78..1690377ff 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -129,25 +129,25 @@ proc variance*(x: openArray[float]): float {.noSideEffect.} =
     result = result + diff*diff
   result = result / toFloat(len(x))
 
-proc random*(max: int): int {.gcsafe.}
+proc random*(max: int): int {.benign.}
   ## returns a random number in the range 0..max-1. The sequence of
   ## random number is always the same, unless `randomize` is called
   ## which initializes the random number generator with a "random"
   ## number, i.e. a tickcount.
 
-proc random*(max: float): float {.gcsafe.}
+proc random*(max: float): float {.benign.}
   ## returns a random number in the range 0..<max. The sequence of
   ## random number is always the same, unless `randomize` is called
   ## which initializes the random number generator with a "random"
   ## number, i.e. a tickcount. This has a 16-bit resolution on windows
   ## and a 48-bit resolution on other platforms.
 
-proc randomize*() {.gcsafe.}
+proc randomize*() {.benign.}
   ## initializes the random number generator with a "random"
   ## number, i.e. a tickcount. Note: Does nothing for the JavaScript target,
   ## as JavaScript does not support this.
   
-proc randomize*(seed: int) {.gcsafe.}
+proc randomize*(seed: int) {.benign.}
   ## initializes the random number generator with a specific seed.
   ## Note: Does nothing for the JavaScript target,
   ## as JavaScript does not support this.
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 4eacfea78..2b81b6fb0 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -321,7 +321,8 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
     dealloc(aiList)
 
 proc acceptAddr*(server: Socket, client: var Socket, address: var string,
-                 flags = {SocketFlag.SafeDisconn}) {.tags: [ReadIOEffect].} =
+                 flags = {SocketFlag.SafeDisconn}) {.
+                 tags: [ReadIOEffect], gcsafe, locks: 0.} =
   ## Blocks until a connection is being made from a client. When a connection
   ## is made sets ``client`` to the client socket and ``address`` to the address
   ## of the connecting client.
@@ -938,8 +939,12 @@ proc connect*(socket: Socket, address: string, port = Port(0), timeout: int,
         doAssert socket.handshake()
   socket.fd.setBlocking(true)
 
-proc isSsl*(socket: Socket): bool = return socket.isSSL
+proc isSsl*(socket: Socket): bool = 
   ## Determines whether ``socket`` is a SSL socket.
+  when defined(ssl):
+    result = socket.isSSL
+  else:
+    result = false
 
 proc getFd*(socket: Socket): SocketHandle = return socket.fd
   ## Returns the socket's file descriptor
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index f01343673..14cbe07bb 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1339,7 +1339,7 @@ proc rawRemoveDir(dir: string) =
     if rmdir(dir) != 0'i32 and errno != ENOENT: raiseOSError(osLastError())
 
 proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [
-  WriteDirEffect, ReadDirEffect].} =
+  WriteDirEffect, ReadDirEffect], benign.} =
   ## Removes the directory `dir` including all subdirectories and files
   ## in `dir` (recursively).
   ##
@@ -1385,7 +1385,7 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].} =
   rawCreateDir(dir)
 
 proc copyDir*(source, dest: string) {.rtl, extern: "nos$1",
-  tags: [WriteIOEffect, ReadIOEffect].} =
+  tags: [WriteIOEffect, ReadIOEffect], benign.} =
   ## Copies a directory from `source` to `dest`.
   ##
   ## If this fails, `OSError` is raised. On the Windows platform this proc will
@@ -1558,7 +1558,7 @@ proc copyFileWithPermissions*(source, dest: string,
 
 proc copyDirWithPermissions*(source, dest: string,
     ignorePermissionErrors = true) {.rtl, extern: "nos$1",
-    tags: [WriteIOEffect, ReadIOEffect].} =
+    tags: [WriteIOEffect, ReadIOEffect], benign.} =
   ## Copies a directory from `source` to `dest` preserving file permissions.
   ##
   ## If this fails, `OSError` is raised. This is a wrapper proc around `copyDir()
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index 1cabd381b..0925e3471 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -63,44 +63,44 @@ elif defined(windows):
 elif defined(JS):
   type
     Time* {.importc.} = object
-      getDay: proc (): int {.tags: [], raises: [], gcsafe.}
-      getFullYear: proc (): int {.tags: [], raises: [], gcsafe.}
-      getHours: proc (): int {.tags: [], raises: [], gcsafe.}
-      getMilliseconds: proc (): int {.tags: [], raises: [], gcsafe.}
-      getMinutes: proc (): int {.tags: [], raises: [], gcsafe.}
-      getMonth: proc (): int {.tags: [], raises: [], gcsafe.}
-      getSeconds: proc (): int {.tags: [], raises: [], gcsafe.}
-      getTime: proc (): int {.tags: [], raises: [], gcsafe.}
-      getTimezoneOffset: proc (): int {.tags: [], raises: [], gcsafe.}
-      getDate: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCDate: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCFullYear: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCHours: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCMilliseconds: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCMinutes: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCMonth: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCSeconds: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCDay: proc (): int {.tags: [], raises: [], gcsafe.}
-      getYear: proc (): int {.tags: [], raises: [], gcsafe.}
-      parse: proc (s: cstring): Time {.tags: [], raises: [], gcsafe.}
-      setDate: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setHours: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setMilliseconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setMinutes: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setMonth: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setSeconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setTime: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCDate: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCHours: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCMilliseconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCMinutes: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCMonth: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCSeconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setYear: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      toGMTString: proc (): cstring {.tags: [], raises: [], gcsafe.}
-      toLocaleString: proc (): cstring {.tags: [], raises: [], gcsafe.}
+      getDay: proc (): int {.tags: [], raises: [], benign.}
+      getFullYear: proc (): int {.tags: [], raises: [], benign.}
+      getHours: proc (): int {.tags: [], raises: [], benign.}
+      getMilliseconds: proc (): int {.tags: [], raises: [], benign.}
+      getMinutes: proc (): int {.tags: [], raises: [], benign.}
+      getMonth: proc (): int {.tags: [], raises: [], benign.}
+      getSeconds: proc (): int {.tags: [], raises: [], benign.}
+      getTime: proc (): int {.tags: [], raises: [], benign.}
+      getTimezoneOffset: proc (): int {.tags: [], raises: [], benign.}
+      getDate: proc (): int {.tags: [], raises: [], benign.}
+      getUTCDate: proc (): int {.tags: [], raises: [], benign.}
+      getUTCFullYear: proc (): int {.tags: [], raises: [], benign.}
+      getUTCHours: proc (): int {.tags: [], raises: [], benign.}
+      getUTCMilliseconds: proc (): int {.tags: [], raises: [], benign.}
+      getUTCMinutes: proc (): int {.tags: [], raises: [], benign.}
+      getUTCMonth: proc (): int {.tags: [], raises: [], benign.}
+      getUTCSeconds: proc (): int {.tags: [], raises: [], benign.}
+      getUTCDay: proc (): int {.tags: [], raises: [], benign.}
+      getYear: proc (): int {.tags: [], raises: [], benign.}
+      parse: proc (s: cstring): Time {.tags: [], raises: [], benign.}
+      setDate: proc (x: int) {.tags: [], raises: [], benign.}
+      setFullYear: proc (x: int) {.tags: [], raises: [], benign.}
+      setHours: proc (x: int) {.tags: [], raises: [], benign.}
+      setMilliseconds: proc (x: int) {.tags: [], raises: [], benign.}
+      setMinutes: proc (x: int) {.tags: [], raises: [], benign.}
+      setMonth: proc (x: int) {.tags: [], raises: [], benign.}
+      setSeconds: proc (x: int) {.tags: [], raises: [], benign.}
+      setTime: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCDate: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCFullYear: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCHours: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCMilliseconds: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCMinutes: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCMonth: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCSeconds: proc (x: int) {.tags: [], raises: [], benign.}
+      setYear: proc (x: int) {.tags: [], raises: [], benign.}
+      toGMTString: proc (): cstring {.tags: [], raises: [], benign.}
+      toLocaleString: proc (): cstring {.tags: [], raises: [], benign.}
 
 type
   TimeInfo* = object of RootObj ## represents a time in different parts
@@ -139,42 +139,42 @@ type
 {.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time,
     TTimeInterval: TimeInterval, TTimeInfo: TimeInfo].}
 
-proc getTime*(): Time {.tags: [TimeEffect], gcsafe.}
+proc getTime*(): Time {.tags: [TimeEffect], benign.}
   ## gets the current calendar time as a UNIX epoch value (number of seconds
   ## elapsed since 1970) with integer precission. Use epochTime for higher
   ## resolution.
-proc getLocalTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.}
+proc getLocalTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], benign.}
   ## converts the calendar time `t` to broken-time representation,
   ## expressed relative to the user's specified time zone.
-proc getGMTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.}
+proc getGMTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], benign.}
   ## converts the calendar time `t` to broken-down time representation,
   ## expressed in Coordinated Universal Time (UTC).
 
-proc timeInfoToTime*(timeInfo: TimeInfo): Time {.tags: [], gcsafe.}
+proc timeInfoToTime*(timeInfo: TimeInfo): Time {.tags: [], benign.}
   ## converts a broken-down time structure to
   ## calendar time representation. The function ignores the specified
   ## contents of the structure members `weekday` and `yearday` and recomputes
   ## them from the other information in the broken-down time structure.
 
-proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], gcsafe.}
+proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], benign.}
   ## Takes a float which contains the number of seconds since the unix epoch and
   ## returns a time object.
 
-proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], gcsafe.} = 
+proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], benign.} = 
   ## Takes an int which contains the number of seconds since the unix epoch and
   ## returns a time object.
   fromSeconds(float(since1970))
 
-proc toSeconds*(time: Time): float {.tags: [], raises: [], gcsafe.}
+proc toSeconds*(time: Time): float {.tags: [], raises: [], benign.}
   ## Returns the time in seconds since the unix epoch.
 
-proc `$` *(timeInfo: TimeInfo): string {.tags: [], raises: [], gcsafe.}
+proc `$` *(timeInfo: TimeInfo): string {.tags: [], raises: [], benign.}
   ## converts a `TimeInfo` object to a string representation.
-proc `$` *(time: Time): string {.tags: [], raises: [], gcsafe.}
+proc `$` *(time: Time): string {.tags: [], raises: [], benign.}
   ## converts a calendar time to a string representation.
 
 proc `-`*(a, b: Time): int64 {.
-  rtl, extern: "ntDiffTime", tags: [], raises: [].}
+  rtl, extern: "ntDiffTime", tags: [], raises: [], benign.}
   ## computes the difference of two calendar times. Result is in seconds.
 
 proc `<`*(a, b: Time): bool {.
@@ -194,14 +194,14 @@ proc `==`*(a, b: Time): bool {.
 
 when not defined(JS):
   proc getTzname*(): tuple[nonDST, DST: string] {.tags: [TimeEffect], raises: [],
-    gcsafe.}
+    benign.}
     ## returns the local timezone; ``nonDST`` is the name of the local non-DST
     ## timezone, ``DST`` is the name of the local DST timezone.
 
-proc getTimezone*(): int {.tags: [TimeEffect], raises: [], gcsafe.}
+proc getTimezone*(): int {.tags: [TimeEffect], raises: [], benign.}
   ## returns the offset of the local (non-DST) timezone in seconds west of UTC.
 
-proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], gcsafe.}
+proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.}
   ## get the miliseconds from the start of the program. **Deprecated since
   ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead.
 
diff --git a/lib/system.nim b/lib/system.nim
index ef70a2672..9dc233cb7 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -2098,17 +2098,16 @@ when not defined(nimrodVM) and hostOS != "standalone":
     ## returns an informative string about the GC's activity. This may be useful
     ## for tweaking.
     
-  # XXX mark these as 'locks: 0' once 0.10.0 has been released
-  proc GC_ref*[T](x: ref T) {.magic: "GCref", gcsafe.}
-  proc GC_ref*[T](x: seq[T]) {.magic: "GCref", gcsafe.}
-  proc GC_ref*(x: string) {.magic: "GCref", gcsafe.}
+  proc GC_ref*[T](x: ref T) {.magic: "GCref", benign.}
+  proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign.}
+  proc GC_ref*(x: string) {.magic: "GCref", benign.}
     ## marks the object `x` as referenced, so that it will not be freed until
     ## it is unmarked via `GC_unref`. If called n-times for the same object `x`,
     ## n calls to `GC_unref` are needed to unmark `x`. 
     
-  proc GC_unref*[T](x: ref T) {.magic: "GCunref", gcsafe.}
-  proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", gcsafe.}
-  proc GC_unref*(x: string) {.magic: "GCunref", gcsafe.}
+  proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign.}
+  proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign.}
+  proc GC_unref*(x: string) {.magic: "GCunref", benign.}
     ## see the documentation of `GC_ref`.
 
 template accumulateResult*(iter: expr) =
@@ -2248,14 +2247,9 @@ when not declared(sysFatal):
       e.msg = message & arg
       raise e
 
-when defined(nimlocks):
-  proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe, locks: 0.}
-    ## get type information for `x`. Ordinary code should not use this, but
-    ## the `typeinfo` module instead.
-else:
-  proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe.}
-    ## get type information for `x`. Ordinary code should not use this, but
-    ## the `typeinfo` module instead.
+proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", benign.}
+  ## get type information for `x`. Ordinary code should not use this, but
+  ## the `typeinfo` module instead.
 
 {.push stackTrace: off.}
 proc abs*(x: int): int {.magic: "AbsI", noSideEffect.} =
@@ -2455,14 +2449,10 @@ when not defined(JS): #and not defined(NimrodVM):
       ## Returns ``false`` if the end of the file has been reached, ``true``
       ## otherwise. If ``false`` is returned `line` contains no new data.
 
-    when not defined(booting):
-      proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, 
-                               tags: [WriteIOEffect], gcsafe, locks: 0.}
-        ## writes the values `x` to `f` and then writes "\n".
-        ## May throw an IO exception.
-    else:
-      proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, 
-                               tags: [WriteIOEffect].}
+    proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, 
+                             tags: [WriteIOEffect], benign.}
+      ## writes the values `x` to `f` and then writes "\n".
+      ## May throw an IO exception.
 
     proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], benign.}
       ## retrieves the file size (in bytes) of `f`.
@@ -2576,7 +2566,7 @@ when not defined(JS): #and not defined(NimrodVM):
     initAllocator()
   when hasThreadSupport:
     include "system/syslocks"
-    include "system/threads"
+    when hostOS != "standalone": include "system/threads"
   elif not defined(nogc) and not defined(NimrodVM) and hostOS != "standalone":
     when not defined(useNimRtl) and not defined(createNimRtl): initStackBottom()
     initGC()
diff --git a/lib/system/repr.nim b/lib/system/repr.nim
index 2de603cea..5a243cb44 100644
--- a/lib/system/repr.nim
+++ b/lib/system/repr.nim
@@ -78,7 +78,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
 type
   PByteArray = ptr array[0.. 0xffff, int8]
 
-proc addSetElem(result: var string, elem: int, typ: PNimType) {.gcsafe.} =
+proc addSetElem(result: var string, elem: int, typ: PNimType) {.benign.} =
   case typ.kind
   of tyEnum: add result, reprEnum(elem, typ)
   of tyBool: add result, reprBool(bool(elem))
@@ -147,7 +147,7 @@ when not defined(useNimRtl):
     for i in 0..cl.indent-1: add result, ' '
 
   proc reprAux(result: var string, p: pointer, typ: PNimType,
-               cl: var TReprClosure) {.gcsafe.}
+               cl: var TReprClosure) {.benign.}
 
   proc reprArray(result: var string, p: pointer, typ: PNimType,
                  cl: var TReprClosure) =
@@ -172,7 +172,7 @@ when not defined(useNimRtl):
     add result, "]"
 
   proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode,
-                     cl: var TReprClosure) {.gcsafe.} =
+                     cl: var TReprClosure) {.benign.} =
     case n.kind
     of nkNone: sysAssert(false, "reprRecordAux")
     of nkSlot:
diff --git a/tests/collections/tindexby.nim b/tests/collections/tindexby.nim
new file mode 100644
index 000000000..f374d5504
--- /dev/null
+++ b/tests/collections/tindexby.nim
@@ -0,0 +1,22 @@
+import tables
+
+doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table"
+
+var tbl1 = initTable[int, int]()
+tbl1.add(1,1)
+tbl1.add(2,2)
+doAssert indexBy(@[1,2], proc(x: int):int = x) == tbl1, "int table"
+
+type
+  TElem = object
+    foo: int
+    bar: string
+    
+let
+  elem1 = TElem(foo: 1, bar: "bar")
+  elem2 = TElem(foo: 2, bar: "baz")
+  
+var tbl2 = initTable[string, TElem]()
+tbl2.add("bar", elem1)
+tbl2.add("baz", elem2)
+doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table"
diff --git a/tests/table/ttableconstr.nim b/tests/collections/ttableconstr.nim
index 1a21a18d1..1a21a18d1 100644
--- a/tests/table/ttableconstr.nim
+++ b/tests/collections/ttableconstr.nim
diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim
index f374d5504..de4aaed5e 100644
--- a/tests/collections/ttables.nim
+++ b/tests/collections/ttables.nim
@@ -1,22 +1,128 @@
-import tables
-
-doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table"
-
-var tbl1 = initTable[int, int]()
-tbl1.add(1,1)
-tbl1.add(2,2)
-doAssert indexBy(@[1,2], proc(x: int):int = x) == tbl1, "int table"
-
-type
-  TElem = object
-    foo: int
-    bar: string
-    
-let
-  elem1 = TElem(foo: 1, bar: "bar")
-  elem2 = TElem(foo: 2, bar: "baz")
+discard """
+  output: '''true'''
+"""
+
+import hashes, tables
+
+const
+  data = {
+    "34": 123456, "12": 789,
+    "90": 343, "0": 34404,
+    "1": 344004, "2": 344774,
+    "3": 342244, "4": 3412344,
+    "5": 341232144, "6": 34214544,
+    "7": 3434544, "8": 344544,
+    "9": 34435644, "---00": 346677844,
+    "10": 34484, "11": 34474, "19": 34464,
+    "20": 34454, "30": 34141244, "40": 344114,
+    "50": 344490, "60": 344491, "70": 344492,
+    "80": 344497}
+
+  sorteddata = {
+    "---00": 346677844,
+    "0": 34404,
+    "1": 344004,
+    "10": 34484, 
+    "11": 34474,
+    "12": 789,
+    "19": 34464,
+    "2": 344774, "20": 34454, 
+    "3": 342244, "30": 34141244,
+    "34": 123456,
+    "4": 3412344, "40": 344114,
+    "5": 341232144, "50": 344490, 
+    "6": 34214544, "60": 344491,
+    "7": 3434544, "70": 344492,
+    "8": 344544, "80": 344497,
+    "9": 34435644,
+    "90": 343}
+
+block tableTest1:
+  var t = initTable[tuple[x, y: int], string]()
+  t[(0,0)] = "00"
+  t[(1,0)] = "10"
+  t[(0,1)] = "01"
+  t[(1,1)] = "11"
+  for x in 0..1:
+    for y in 0..1:
+      assert t[(x,y)] == $x & $y
+  assert($t == 
+    "{(x: 0, y: 0): 00, (x: 0, y: 1): 01, (x: 1, y: 0): 10, (x: 1, y: 1): 11}")
+
+block tableTest2:
+  var t = initTable[string, float]()
+  t["test"] = 1.2345
+  t["111"] = 1.000043
+  t["123"] = 1.23
+  t.del("111")
   
-var tbl2 = initTable[string, TElem]()
-tbl2.add("bar", elem1)
-tbl2.add("baz", elem2)
-doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table"
+  t["012"] = 67.9
+  t["123"] = 1.5 # test overwriting
+  
+  assert t["123"] == 1.5
+  assert t["111"] == 0.0 # deleted
+  assert(not hasKey(t, "111"))
+  
+  for key, val in items(data): t[key] = val.toFloat
+  for key, val in items(data): assert t[key] == val.toFloat
+  
+
+block orderedTableTest1:
+  var t = initOrderedTable[string, int](2)
+  for key, val in items(data): t[key] = val
+  for key, val in items(data): assert t[key] == val
+  var i = 0
+  # `pairs` needs to yield in insertion order:
+  for key, val in pairs(t):
+    assert key == data[i][0]
+    assert val == data[i][1]
+    inc(i)
+
+  for key, val in mpairs(t): val = 99
+  for val in mvalues(t): assert val == 99
+
+block countTableTest1:
+  var s = data.toTable
+  var t = initCountTable[string]()
+  for k in s.keys: t.inc(k)
+  for k in t.keys: assert t[k] == 1
+  t.inc("90", 3)
+  t.inc("12", 2)
+  t.inc("34", 1)
+  assert t.largest()[0] == "90"
+
+  t.sort()
+  var i = 0
+  for k, v in t.pairs:
+    case i
+    of 0: assert k == "90" and v == 4
+    of 1: assert k == "12" and v == 3
+    of 2: assert k == "34" and v == 2
+    else: break
+    inc i
+
+block SyntaxTest:
+  var x = toTable[int, string]({:})
+
+proc orderedTableSortTest() =
+  var t = initOrderedTable[string, int](2)
+  for key, val in items(data): t[key] = val
+  for key, val in items(data): assert t[key] == val
+  t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key))
+  var i = 0
+  # `pairs` needs to yield in sorted order:
+  for key, val in pairs(t):
+    doAssert key == sorteddata[i][0]
+    doAssert val == sorteddata[i][1]
+    inc(i)
+
+  # check that lookup still works:
+  for key, val in pairs(t):
+    doAssert val == t[key]
+  # check that insert still works:
+  t["newKeyHere"] = 80
+
+
+orderedTableSortTest()
+echo "true"
+
diff --git a/tests/table/ttables2.nim b/tests/collections/ttables2.nim
index 611f3f8ec..611f3f8ec 100644
--- a/tests/table/ttables2.nim
+++ b/tests/collections/ttables2.nim
diff --git a/tests/table/ptables.nim b/tests/collections/ttablesref.nim
index 79a9aab17..e666c7852 100644
--- a/tests/table/ptables.nim
+++ b/tests/collections/ttablesref.nim
@@ -84,7 +84,7 @@ block orderedTableTest1:
 block countTableTest1:
   var s = data.toTable
   var t = newCountTable[string]()
-  for k in s.Keys: t.inc(k)
+  for k in s.keys: t.inc(k)
   for k in t.keys: assert t[k] == 1
   t.inc("90", 3)
   t.inc("12", 2)
diff --git a/tests/table/ptables2.nim b/tests/collections/ttablesref2.nim
index 939de2b84..939de2b84 100644
--- a/tests/table/ptables2.nim
+++ b/tests/collections/ttablesref2.nim
diff --git a/tests/stdlib/tircbot.nim b/tests/stdlib/tircbot.nim
deleted file mode 100644
index 6b209dce3..000000000
--- a/tests/stdlib/tircbot.nim
+++ /dev/null
@@ -1,453 +0,0 @@
-import irc, sockets, asyncio, json, os, strutils, times, redis
-
-type
-  TDb* = object
-    r*: Redis
-    lastPing: float
-
-  TBuildResult* = enum
-    bUnknown, bFail, bSuccess
-
-  TTestResult* = enum
-    tUnknown, tFail, tSuccess
-
-  TEntry* = tuple[c: TCommit, p: seq[TPlatform]]
-  
-  TCommit* = object
-    commitMsg*, username*, hash*: string
-    date*: Time
-
-  TPlatform* = object
-    buildResult*: TBuildResult
-    testResult*: TTestResult
-    failReason*, platform*: string
-    total*, passed*, skipped*, failed*: BiggestInt
-    csources*: bool
-
-const
-  listName = "commits"
-  failOnExisting = false
-
-proc open*(host = "localhost", port: Port): TDb =
-  result.r = redis.open(host, port)
-  result.lastPing = epochTime()
-
-discard """proc customHSet(database: TDb, name, field, value: string) =
-  if database.r.hSet(name, field, value).int == 0:
-    if failOnExisting:
-      assert(false)
-    else:
-      echo("[Warning:REDIS] ", field, " already exists in ", name)"""
-
-proc updateProperty*(database: TDb, commitHash, platform, property,
-                    value: string) =
-  var name = platform & ":" & commitHash
-  if database.r.hSet(name, property, value).int == 0:
-    echo("[INFO:REDIS] '$1' field updated in hash" % [property])
-  else:
-    echo("[INFO:REDIS] '$1' new field added to hash" % [property])
-
-proc globalProperty*(database: TDb, commitHash, property, value: string) =
-  if database.r.hSet(commitHash, property, value).int == 0:
-    echo("[INFO:REDIS] '$1' field updated in hash" % [property])
-  else:
-    echo("[INFO:REDIS] '$1' new field added to hash" % [property])
-
-proc addCommit*(database: TDb, commitHash, commitMsg, user: string) =
-  # Add the commit hash to the `commits` list.
-  discard database.r.lPush(listName, commitHash)
-  # Add the commit message, current date and username as a property
-  globalProperty(database, commitHash, "commitMsg", commitMsg)
-  globalProperty(database, commitHash, "date", $int(getTime()))
-  globalProperty(database, commitHash, "username", user)
-
-proc keepAlive*(database: var TDb) =
-  ## Keep the connection alive. Ping redis in this case. This functions does
-  ## not guarantee that redis will be pinged.
-  var t = epochTime()
-  if t - database.lastPing >= 60.0:
-    echo("PING -> redis")
-    assert(database.r.ping() == "PONG")
-    database.lastPing = t
-    
-proc getCommits*(database: TDb,
-                 plStr: var seq[string]): seq[TEntry] =
-  result = @[]
-  var commitsRaw = database.r.lrange("commits", 0, -1)
-  for c in items(commitsRaw):
-    var commit: TCommit
-    commit.hash = c
-    for key, value in database.r.hPairs(c):
-      case normalize(key)
-      of "commitmsg": commit.commitMsg = value
-      of "date": commit.date = Time(parseInt(value))
-      of "username": commit.username = value
-      else:
-        echo(key)
-        assert(false)
-
-    var platformsRaw = database.r.lrange(c & ":platforms", 0, -1)
-    var platforms: seq[TPlatform] = @[]
-    for p in items(platformsRaw):
-      var platform: TPlatform
-      for key, value in database.r.hPairs(p & ":" & c):
-        case normalize(key)
-        of "buildresult":
-          platform.buildResult = parseInt(value).TBuildResult
-        of "testresult":
-          platform.testResult = parseInt(value).TTestResult
-        of "failreason":
-          platform.failReason = value
-        of "total":
-          platform.total = parseBiggestInt(value)
-        of "passed":
-          platform.passed = parseBiggestInt(value)
-        of "skipped":
-          platform.skipped = parseBiggestInt(value)
-        of "failed":
-          platform.failed = parseBiggestInt(value)
-        of "csources":
-          platform.csources = if value == "t": true else: false
-        else:
-          echo(normalize(key))
-          assert(false)
-      
-      platform.platform = p
-      
-      platforms.add(platform)
-      if p notin plStr:
-        plStr.add(p)
-    result.add((commit, platforms))
-
-proc commitExists*(database: TDb, commit: string, starts = false): bool =
-  # TODO: Consider making the 'commits' list a set.
-  for c in items(database.r.lrange("commits", 0, -1)):
-    if starts:
-      if c.startsWith(commit): return true
-    else:
-      if c == commit: return true
-  return false
-
-proc platformExists*(database: TDb, commit: string, platform: string): bool =
-  for p in items(database.r.lrange(commit & ":" & "platforms", 0, -1)):
-    if p == platform: return true
-
-proc expandHash*(database: TDb, commit: string): string =
-  for c in items(database.r.lrange("commits", 0, -1)):
-    if c.startsWith(commit): return c
-  assert false
-
-proc isNewest*(database: TDb, commit: string): bool =
-  return database.r.lIndex("commits", 0) == commit
-
-proc getNewest*(database: TDb): string =
-  return database.r.lIndex("commits", 0)
-
-proc addPlatform*(database: TDb, commit: string, platform: string) =
-  assert database.commitExists(commit)
-  assert (not database.platformExists(commit, platform))
-  var name = platform & ":" & commit
-  if database.r.exists(name):
-    if failOnExisting: quit("[FAIL] " & name & " already exists!", 1)
-    else: echo("[Warning] " & name & " already exists!")
-
-  discard database.r.lPush(commit & ":" & "platforms", platform)
-
-proc `[]`*(p: seq[TPlatform], name: string): TPlatform =
-  for platform in items(p):
-    if platform.platform == name:
-      return platform
-  raise newException(ValueError, name & " platforms not found in commits.")
-  
-proc contains*(p: seq[TPlatform], s: string): bool =
-  for i in items(p):
-    if i.platform == s:
-      return true
-    
-
-type
-  PState = ref TState
-  TState = object of RootObj
-    dispatcher: Dispatcher
-    sock: AsyncSocket
-    ircClient: PAsyncIRC
-    hubPort: Port
-    database: TDb
-    dbConnected: bool
-
-  TSeenType = enum
-    PSeenJoin, PSeenPart, PSeenMsg, PSeenNick, PSeenQuit
-  
-  TSeen = object
-    nick: string
-    channel: string
-    timestamp: Time
-    case kind*: TSeenType
-    of PSeenJoin: nil
-    of PSeenPart, PSeenQuit, PSeenMsg:
-      msg: string
-    of PSeenNick:
-      newNick: string
-
-const
-  ircServer = "irc.freenode.net"
-  joinChans = @["#nim"]
-  botNickname = "NimBot"
-
-proc setSeen(d: TDb, s: TSeen) =
-  discard d.r.del("seen:" & s.nick)
-
-  var hashToSet = @[("type", $s.kind.int), ("channel", s.channel),
-                    ("timestamp", $s.timestamp.int)]
-  case s.kind
-  of PSeenJoin: discard
-  of PSeenPart, PSeenMsg, PSeenQuit:
-    hashToSet.add(("msg", s.msg))
-  of PSeenNick:
-    hashToSet.add(("newnick", s.newNick))
-  
-  d.r.hMSet("seen:" & s.nick, hashToSet)
-
-proc getSeen(d: TDb, nick: string, s: var TSeen): bool =
-  if d.r.exists("seen:" & nick):
-    result = true
-    s.nick = nick
-    # Get the type first
-    s.kind = d.r.hGet("seen:" & nick, "type").parseInt.TSeenType
-    
-    for key, value in d.r.hPairs("seen:" & nick):
-      case normalize(key)
-      of "type":
-        discard
-        #s.kind = value.parseInt.TSeenType
-      of "channel":
-        s.channel = value
-      of "timestamp":
-        s.timestamp = Time(value.parseInt)
-      of "msg":
-        s.msg = value
-      of "newnick":
-        s.newNick = value
-
-template createSeen(typ: TSeenType, n, c: string): stmt {.immediate, dirty.} =
-  var seenNick: TSeen
-  seenNick.kind = typ
-  seenNick.nick = n
-  seenNick.channel = c
-  seenNick.timestamp = getTime()
-
-proc parseReply(line: string, expect: string): bool =
-  var jsonDoc = parseJson(line)
-  return jsonDoc["reply"].str == expect
-
-proc limitCommitMsg(m: string): string =
-  ## Limits the message to 300 chars and adds ellipsis.
-  var m1 = m
-  if NewLines in m1:
-    m1 = m1.splitLines()[0]
-  
-  if m1.len >= 300:
-    m1 = m1[0..300]
-
-  if m1.len >= 300 or NewLines in m: m1.add("... ")
-
-  if NewLines in m: m1.add($m.splitLines().len & " more lines")
-
-  return m1
-
-proc handleWebMessage(state: PState, line: string) =
-  echo("Got message from hub: " & line)
-  var json = parseJson(line)
-  if json.hasKey("payload"):
-    for i in 0..min(4, json["payload"]["commits"].len-1):
-      var commit = json["payload"]["commits"][i]
-      # Create the message
-      var message = ""
-      message.add(json["payload"]["repository"]["owner"]["name"].str & "/" &
-                  json["payload"]["repository"]["name"].str & " ")
-      message.add(commit["id"].str[0..6] & " ")
-      message.add(commit["author"]["name"].str & " ")
-      message.add("[+" & $commit["added"].len & " ")
-      message.add("±" & $commit["modified"].len & " ")
-      message.add("-" & $commit["removed"].len & "]: ")
-      message.add(limitCommitMsg(commit["message"].str))
-
-      # Send message to #nim.
-      discard state.ircClient.privmsg(joinChans[0], message)
-  elif json.hasKey("redisinfo"):
-    assert json["redisinfo"].hasKey("port")
-    #let redisPort = json["redisinfo"]["port"].num
-    state.dbConnected = true
-
-proc hubConnect(state: PState)
-proc handleConnect(s: AsyncSocket, state: PState) =
-  try:
-    # Send greeting
-    var obj = newJObject()
-    obj["name"] = newJString("irc")
-    obj["platform"] = newJString("?")
-    state.sock.send($obj & "\c\L")
-
-    # Wait for reply.
-    var line = ""
-    sleep(1500)
-    if state.sock.recvLine(line):
-      assert(line != "")
-      doAssert parseReply(line, "OK")
-      echo("The hub accepted me!")
-    else:
-      raise newException(ValueError,
-                         "Hub didn't accept me. Waited 1.5 seconds.")
-    
-    # ask for the redis info
-    var riobj = newJObject()
-    riobj["do"] = newJString("redisinfo")
-    state.sock.send($riobj & "\c\L")
-    
-  except OsError:
-    echo(getCurrentExceptionMsg())
-    s.close()
-    echo("Waiting 5 seconds...")
-    sleep(5000)
-    state.hubConnect()
-
-proc handleRead(s: AsyncSocket, state: PState) =
-  var line = ""
-  if state.sock.recvLine(line):
-    if line != "":
-      # Handle the message
-      state.handleWebMessage(line)
-    else:
-      echo("Disconnected from hub: ", osErrorMsg())
-      s.close()
-      echo("Reconnecting...")
-      state.hubConnect()
-  else:
-    echo(osErrorMsg())
-
-proc hubConnect(state: PState) =
-  state.sock = asyncSocket()
-  state.sock.connect("127.0.0.1", state.hubPort)
-  state.sock.handleConnect =
-    proc (s: AsyncSocket) =
-      handleConnect(s, state)
-  state.sock.handleRead =
-    proc (s: AsyncSocket) =
-      handleRead(s, state)
-
-  state.dispatcher.register(state.sock)
-
-proc handleIrc(irc: PAsyncIRC, event: TIRCEvent, state: PState) =
-  case event.typ
-  of EvConnected: discard
-  of EvDisconnected:
-    while not state.ircClient.isConnected:
-      try:
-        state.ircClient.connect()
-      except:
-        echo("Error reconnecting: ", getCurrentExceptionMsg())
-      
-      echo("Waiting 5 seconds...")
-      sleep(5000)
-    echo("Reconnected successfully!")
-  of EvMsg:
-    echo("< ", event.raw)
-    case event.cmd
-    of MPrivMsg:
-      let msg = event.params[event.params.len-1]
-      let words = msg.split(' ')
-      template pm(msg: string): stmt =
-        state.ircClient.privmsg(event.origin, msg)
-      case words[0]
-      of "!ping": pm("pong")
-      of "!lag":
-        if state.ircClient.getLag != -1.0:
-          var lag = state.ircClient.getLag
-          lag = lag * 1000.0
-          pm($int(lag) & "ms between me and the server.")
-        else:
-          pm("Unknown.")
-      of "!seen":
-        if words.len > 1:
-          let nick = words[1]
-          if nick == botNickname:
-            pm("Yes, I see myself.")
-          echo(nick)
-          var seenInfo: TSeen
-          if state.database.getSeen(nick, seenInfo):
-            #var mSend = ""
-            case seenInfo.kind
-            of PSeenMsg:
-              pm("$1 was last seen on $2 in $3 saying: $4" %
-                    [seenInfo.nick, $seenInfo.timestamp,
-                     seenInfo.channel, seenInfo.msg])
-            of PSeenJoin:
-              pm("$1 was last seen on $2 joining $3" %
-                        [seenInfo.nick, $seenInfo.timestamp, seenInfo.channel])
-            of PSeenPart:
-              pm("$1 was last seen on $2 leaving $3 with message: $4" %
-                        [seenInfo.nick, $seenInfo.timestamp, seenInfo.channel,
-                         seenInfo.msg])
-            of PSeenQuit:
-              pm("$1 was last seen on $2 quitting with message: $3" %
-                        [seenInfo.nick, $seenInfo.timestamp, seenInfo.msg])
-            of PSeenNick:
-              pm("$1 was last seen on $2 changing nick to $3" %
-                        [seenInfo.nick, $seenInfo.timestamp, seenInfo.newNick])
-            
-          else:
-            pm("I have not seen " & nick)
-        else:
-          pm("Syntax: !seen <nick>")
-
-      # TODO: ... commands
-
-      # -- Seen
-      # Log this as activity.
-      createSeen(PSeenMsg, event.nick, event.origin)
-      seenNick.msg = msg
-      state.database.setSeen(seenNick)
-    of MJoin:
-      createSeen(PSeenJoin, event.nick, event.origin)
-      state.database.setSeen(seenNick)
-    of MPart:
-      createSeen(PSeenPart, event.nick, event.origin)
-      let msg = event.params[event.params.high]
-      seenNick.msg = msg
-      state.database.setSeen(seenNick)
-    of MQuit:
-      createSeen(PSeenQuit, event.nick, event.origin)
-      let msg = event.params[event.params.high]
-      seenNick.msg = msg
-      state.database.setSeen(seenNick)
-    of MNick:
-      createSeen(PSeenNick, event.nick, "#nim")
-      seenNick.newNick = event.params[0]
-      state.database.setSeen(seenNick)
-    else:
-      discard # TODO: ?
-
-proc open(port: Port = Port(5123)): PState =
-  var res: PState
-  new(res)
-  res.dispatcher = newDispatcher()
-  
-  res.hubPort = port
-  res.hubConnect()
-  let hirc =
-    proc (a: PAsyncIRC, ev: TIRCEvent) =
-      handleIrc(a, ev, res)
-  # Connect to the irc server.
-  res.ircClient = AsyncIrc(ircServer, nick = botNickname, user = botNickname,
-                 joinChans = joinChans, ircEvent = hirc)
-  res.ircClient.connect()
-  res.dispatcher.register(res.ircClient)
-
-  res.dbConnected = false
-  result = res
-
-var state = tircbot.open() # Connect to the website and the IRC server.
-
-while state.dispatcher.poll():
-  if state.dbConnected:
-    state.database.keepAlive()
diff --git a/tests/stdlib/tmitems.nim b/tests/stdlib/tmitems.nim
index bf67d2b7b..2c0a0392a 100644
--- a/tests/stdlib/tmitems.nim
+++ b/tests/stdlib/tmitems.nim
@@ -11,7 +11,7 @@ fpqeew
 [11, 12, 13]
 [11, 12, 13]
 [11, 12, 13]
-{ "key1": 11,  "key2": 12,  "key3": 13}
+{"key1": 11, "key2": 12, "key3": 13}
 [11, 12, 13]
 <Students>
   <Student Name="Aprilfoo" />
diff --git a/tests/table/ttables.nim b/tests/table/ttables.nim
deleted file mode 100644
index de4aaed5e..000000000
--- a/tests/table/ttables.nim
+++ /dev/null
@@ -1,128 +0,0 @@
-discard """
-  output: '''true'''
-"""
-
-import hashes, tables
-
-const
-  data = {
-    "34": 123456, "12": 789,
-    "90": 343, "0": 34404,
-    "1": 344004, "2": 344774,
-    "3": 342244, "4": 3412344,
-    "5": 341232144, "6": 34214544,
-    "7": 3434544, "8": 344544,
-    "9": 34435644, "---00": 346677844,
-    "10": 34484, "11": 34474, "19": 34464,
-    "20": 34454, "30": 34141244, "40": 344114,
-    "50": 344490, "60": 344491, "70": 344492,
-    "80": 344497}
-
-  sorteddata = {
-    "---00": 346677844,
-    "0": 34404,
-    "1": 344004,
-    "10": 34484, 
-    "11": 34474,
-    "12": 789,
-    "19": 34464,
-    "2": 344774, "20": 34454, 
-    "3": 342244, "30": 34141244,
-    "34": 123456,
-    "4": 3412344, "40": 344114,
-    "5": 341232144, "50": 344490, 
-    "6": 34214544, "60": 344491,
-    "7": 3434544, "70": 344492,
-    "8": 344544, "80": 344497,
-    "9": 34435644,
-    "90": 343}
-
-block tableTest1:
-  var t = initTable[tuple[x, y: int], string]()
-  t[(0,0)] = "00"
-  t[(1,0)] = "10"
-  t[(0,1)] = "01"
-  t[(1,1)] = "11"
-  for x in 0..1:
-    for y in 0..1:
-      assert t[(x,y)] == $x & $y
-  assert($t == 
-    "{(x: 0, y: 0): 00, (x: 0, y: 1): 01, (x: 1, y: 0): 10, (x: 1, y: 1): 11}")
-
-block tableTest2:
-  var t = initTable[string, float]()
-  t["test"] = 1.2345
-  t["111"] = 1.000043
-  t["123"] = 1.23
-  t.del("111")
-  
-  t["012"] = 67.9
-  t["123"] = 1.5 # test overwriting
-  
-  assert t["123"] == 1.5
-  assert t["111"] == 0.0 # deleted
-  assert(not hasKey(t, "111"))
-  
-  for key, val in items(data): t[key] = val.toFloat
-  for key, val in items(data): assert t[key] == val.toFloat
-  
-
-block orderedTableTest1:
-  var t = initOrderedTable[string, int](2)
-  for key, val in items(data): t[key] = val
-  for key, val in items(data): assert t[key] == val
-  var i = 0
-  # `pairs` needs to yield in insertion order:
-  for key, val in pairs(t):
-    assert key == data[i][0]
-    assert val == data[i][1]
-    inc(i)
-
-  for key, val in mpairs(t): val = 99
-  for val in mvalues(t): assert val == 99
-
-block countTableTest1:
-  var s = data.toTable
-  var t = initCountTable[string]()
-  for k in s.keys: t.inc(k)
-  for k in t.keys: assert t[k] == 1
-  t.inc("90", 3)
-  t.inc("12", 2)
-  t.inc("34", 1)
-  assert t.largest()[0] == "90"
-
-  t.sort()
-  var i = 0
-  for k, v in t.pairs:
-    case i
-    of 0: assert k == "90" and v == 4
-    of 1: assert k == "12" and v == 3
-    of 2: assert k == "34" and v == 2
-    else: break
-    inc i
-
-block SyntaxTest:
-  var x = toTable[int, string]({:})
-
-proc orderedTableSortTest() =
-  var t = initOrderedTable[string, int](2)
-  for key, val in items(data): t[key] = val
-  for key, val in items(data): assert t[key] == val
-  t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key))
-  var i = 0
-  # `pairs` needs to yield in sorted order:
-  for key, val in pairs(t):
-    doAssert key == sorteddata[i][0]
-    doAssert val == sorteddata[i][1]
-    inc(i)
-
-  # check that lookup still works:
-  for key, val in pairs(t):
-    doAssert val == t[key]
-  # check that insert still works:
-  t["newKeyHere"] = 80
-
-
-orderedTableSortTest()
-echo "true"
-
diff --git a/todo.txt b/todo.txt
index 706954f65..57cfea017 100644
--- a/todo.txt
+++ b/todo.txt
@@ -41,7 +41,6 @@ Misc
 - make tuple unpacking work in a non-var/let context
 - built-in 'getImpl'
 - prevent 'alloc(TypeWithGCedMemory)'
-- some table related tests are wrong (memory usage checks)
 
 
 Bugs