summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--[-rwxr-xr-x]build.sh0
-rw-r--r--compiler/ast.nim18
-rw-r--r--compiler/ccgcalls.nim3
-rw-r--r--compiler/ccgstmts.nim245
-rw-r--r--compiler/cgen.nim336
-rw-r--r--compiler/guards.nim23
-rw-r--r--compiler/lookups.nim74
-rw-r--r--compiler/parampatterns.nim8
-rw-r--r--compiler/pragmas.nim265
-rw-r--r--compiler/sem.nim1
-rw-r--r--compiler/sempass2.nim61
-rw-r--r--compiler/semtypes.nim10
-rw-r--r--compiler/semtypinst.nim53
-rw-r--r--compiler/sigmatch.nim8
-rw-r--r--compiler/transf.nim3
-rw-r--r--compiler/vmdeps.nim9
-rw-r--r--compiler/vmgen.nim88
-rw-r--r--compiler/wordrecg.nim114
-rw-r--r--doc/nimc.txt16
-rw-r--r--lib/core/macros.nim226
-rw-r--r--lib/impure/db_mysql.nim6
-rw-r--r--lib/impure/db_postgres.nim6
-rw-r--r--lib/impure/db_sqlite.nim14
-rw-r--r--lib/pure/asyncdispatch.nim28
-rw-r--r--lib/pure/collections/tables.nim45
-rw-r--r--lib/pure/future.nim10
-rw-r--r--lib/pure/htmlgen.nim178
-rw-r--r--lib/pure/json.nim208
-rw-r--r--lib/pure/unittest.nim6
-rw-r--r--lib/pure/xmltree.nim90
-rw-r--r--lib/system.nim14
-rw-r--r--tests/caas/idetools_api.nim2
-rw-r--r--tests/collections/ttablesref.nim9
-rw-r--r--tests/concepts/tmanual.nim (renamed from tests/metatype/udtcmanual.nim)1
-rw-r--r--tests/concepts/tswizzle.nim (renamed from tests/metatype/swizzle.nim)49
-rw-r--r--tests/concepts/tusertypeclasses.nim (renamed from tests/metatype/tusertypeclasses.nim)0
-rw-r--r--tests/concepts/tusertypeclasses2.nim (renamed from tests/metatype/tusertypeclasses2.nim)0
-rw-r--r--tests/converter/ttypeconverter1.nim2
-rw-r--r--tests/generics/tarray_with_somenumber.nim11
-rw-r--r--tests/generics/tunique_type.nim6
-rw-r--r--tests/let/tlet2.nim2
-rw-r--r--tests/macros/tbugs.nim6
-rw-r--r--tests/macros/tdumpast.nim8
-rw-r--r--tests/macros/tdumpast2.nim14
-rw-r--r--tests/macros/tgensym.nim12
-rw-r--r--tests/macros/tgentemplates.nim4
-rw-r--r--tests/macros/tmacro1.nim6
-rw-r--r--tests/macros/tmacro3.nim4
-rw-r--r--tests/macros/tmacro4.nim2
-rw-r--r--tests/macros/tmacro5.nim8
-rw-r--r--tests/macros/tmacros1.nim4
-rw-r--r--tests/macros/tnimnode_for_runtime.nim2
-rw-r--r--tests/macros/tstringinterp.nim12
-rw-r--r--tests/macros/tvarnimnode.nim2
-rw-r--r--tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim50
-rw-r--r--tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim50
-rw-r--r--tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim26
-rw-r--r--tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim3
-rw-r--r--tests/manyloc/named_argument_bug/tri_engine/gfx/gl/gl.nim2
-rw-r--r--tests/manyloc/named_argument_bug/tri_engine/gfx/gl/primitive.nim8
-rw-r--r--tests/manyloc/named_argument_bug/tri_engine/gfx/gl/shader.nim10
-rw-r--r--tests/misc/tinc.nim2
-rw-r--r--tests/misc/tinout.nim2
-rw-r--r--tests/notnil/tnotnil4.nim8
-rw-r--r--tests/objvariant/tadrdisc.nim13
-rw-r--r--tests/overload/tspec.nim81
-rw-r--r--tests/parallel/tarray_of_channels.nim26
-rw-r--r--tests/parallel/tdont_be_stupid.nim15
-rw-r--r--tests/parallel/tgc_unsafe.nim32
-rw-r--r--tests/showoff/tdrdobbs_examples.nim12
-rw-r--r--tests/template/t_otemplates.nim10
-rw-r--r--tests/testament/categories.nim2
-rw-r--r--tests/testament/tester.nim1
-rw-r--r--tests/usingstmt/tusingstatement.nim22
-rw-r--r--tests/vm/tstringnil.nim6
-rw-r--r--todo.txt1
-rw-r--r--web/news.txt17
77 files changed, 1497 insertions, 1234 deletions
diff --git a/build.sh b/build.sh
index 139c28359..139c28359 100755..100644
--- a/build.sh
+++ b/build.sh
diff --git a/compiler/ast.nim b/compiler/ast.nim
index ab315877a..660f3e45e 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -257,7 +257,7 @@ type
     sfThread,         # proc will run as a thread
                       # variable is a thread variable
     sfCompileTime,    # proc can be evaluated at compile time
-    sfMerge,          # proc can be merged with itself
+    sfConstructor,    # proc is a C++ constructor
     sfDeadCodeElim,   # dead code elimination for the module is turned on
     sfBorrow,         # proc is borrowed
     sfInfixCall,      # symbol needs infix call syntax in target language;
@@ -663,7 +663,9 @@ type
     locOther                  # location is something other
   TLocFlag* = enum
     lfIndirect,               # backend introduced a pointer
-    lfParamCopy,              # backend introduced a parameter copy (LLVM)
+    lfFullExternalName, # only used when 'gCmd == cmdPretty': Indicates
+      # that the symbol has been imported via 'importc: "fullname"' and
+      # no format string.
     lfNoDeepCopy,             # no need for a deep copy
     lfNoDecl,                 # do not declare it in C
     lfDynamicLib,             # link symbol to dynamic library
@@ -915,9 +917,7 @@ const
 
   skIterators* = {skIterator, skClosureIterator}
 
-  lfFullExternalName* = lfParamCopy # \
-    # only used when 'gCmd == cmdPretty': Indicates that the symbol has been
-    # imported via 'importc: "fullname"' and no format string.
+var ggDebug* {.deprecated.}: bool ## convenience switch for trying out things
 
 proc isCallExpr*(n: PNode): bool =
   result = n.kind in nkCallKinds
@@ -1333,8 +1333,12 @@ proc propagateToOwner*(owner, elem: PType) =
   if elem.isMetaType:
     owner.flags.incl tfHasMeta
 
-  if owner.kind != tyProc:
-    if elem.isGCedMem or tfHasGCedMem in elem.flags:
+  if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
+                       tyGenericInvocation}:
+    let elemB = elem.skipTypes({tyGenericInst})
+    if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
+      # for simplicity, we propagate this flag even to generics. We then
+      # ensure this doesn't bite us in sempass2.
       owner.flags.incl tfHasGCedMem
 
 proc rawAddSon*(father, son: PType) =
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim
index 86f300aa0..91dcaef42 100644
--- a/compiler/ccgcalls.nim
+++ b/compiler/ccgcalls.nim
@@ -412,7 +412,8 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
   else:
     var pl: PRope = nil
     #var param = typ.n.sons[1].sym
-    app(pl, genThisArg(p, ri, 1, typ))
+    if 1 < ri.len:
+      app(pl, genThisArg(p, ri, 1, typ))
     app(pl, op.r)
     var params: PRope
     for i in countup(2, length - 1):
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index a4938c9ac..441ceb22a 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -33,7 +33,7 @@ proc isAssignedImmediately(n: PNode): bool {.inline.} =
     return false
   result = true
 
-proc genVarTuple(p: BProc, n: PNode) = 
+proc genVarTuple(p: BProc, n: PNode) =
   var tup, field: TLoc
   if n.kind != nkVarTuple: internalError(n.info, "genVarTuple")
   var L = sonsLen(n)
@@ -49,7 +49,7 @@ proc genVarTuple(p: BProc, n: PNode) =
   genLineDir(p, n)
   initLocExpr(p, n.sons[L-1], tup)
   var t = tup.t.getUniqueType
-  for i in countup(0, L-3): 
+  for i in countup(0, L-3):
     var v = n.sons[i].sym
     if sfCompileTime in v.flags: continue
     if sfGlobal in v.flags:
@@ -60,11 +60,11 @@ proc genVarTuple(p: BProc, n: PNode) =
       assignLocalVar(p, v)
       initLocalVar(p, v, immediateAsgn=isAssignedImmediately(n[L-1]))
     initLoc(field, locExpr, t.sons[i], tup.s)
-    if t.kind == tyTuple: 
+    if t.kind == tyTuple:
       field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)])
-    else: 
+    else:
       if t.n.sons[i].kind != nkSym: internalError(n.info, "genVarTuple")
-      field.r = ropef("$1.$2", 
+      field.r = ropef("$1.$2",
                       [rdLoc(tup), mangleRecFieldName(t.n.sons[i].sym, t)])
     putLocIntoDest(p, v.loc, field)
 
@@ -117,7 +117,7 @@ proc endBlock(p: BProc, blockEnd: PRope) =
   line(p, cpsStmts, blockEnd)
 
 proc endBlock(p: BProc) =
-  let topBlock = p.blocks.len - 1  
+  let topBlock = p.blocks.len - 1
   var blockEnd = if p.blocks[topBlock].label != nil:
       rfmt(nil, "} $1: ;$n", p.blocks[topBlock].label)
     else:
@@ -190,10 +190,10 @@ proc genSingleVar(p: BProc, a: PNode) =
       targetProc = p.module.preInitProc
     assignGlobalVar(targetProc, v)
     # XXX: be careful here.
-    # Global variables should not be zeromem-ed within loops 
+    # Global variables should not be zeromem-ed within loops
     # (see bug #20).
     # That's why we are doing the construction inside the preInitProc.
-    # genObjectInit relies on the C runtime's guarantees that 
+    # genObjectInit relies on the C runtime's guarantees that
     # global variables will be initialized to zero.
     genObjectInit(p.module.preInitProc, cpsInit, v.typ, v.loc, true)
     # Alternative construction using default constructor (which may zeromem):
@@ -202,7 +202,8 @@ proc genSingleVar(p: BProc, a: PNode) =
       genVarPrototypeAux(generatedHeader, v)
     registerGcRoot(p, v)
   else:
-    let imm = isAssignedImmediately(a.sons[2])
+    let value = a.sons[2]
+    let imm = isAssignedImmediately(value)
     if imm and p.module.compileToCpp and p.splitDecls == 0 and
         not containsHiddenPointer(v.typ):
       # C++ really doesn't like things like 'Foo f; f = x' as that invokes a
@@ -211,8 +212,19 @@ proc genSingleVar(p: BProc, a: PNode) =
       genLineDir(p, a)
       let decl = localVarDecl(p, v)
       var tmp: TLoc
-      initLocExprSingleUse(p, a.sons[2], tmp)
-      lineF(p, cpsStmts, "$# = $#;$n", decl, tmp.rdLoc)
+      if value.kind in nkCallKinds and value[0].kind == nkSym and
+           sfConstructor in value[0].sym.flags:
+        var params: PRope
+        let typ = skipTypes(value.sons[0].typ, abstractInst)
+        assert(typ.kind == tyProc)
+        for i in 1.. <value.len:
+          if params != nil: params.app(~", ")
+          assert(sonsLen(typ) == sonsLen(typ.n))
+          app(params, genOtherArg(p, value, i, typ))
+        lineF(p, cpsStmts, "$#($#);$n", decl, params)
+      else:
+        initLocExprSingleUse(p, value, tmp)
+        lineF(p, cpsStmts, "$# = $#;$n", decl, tmp.rdLoc)
       return
     assignLocalVar(p, v)
     initLocalVar(p, v, imm)
@@ -229,10 +241,10 @@ proc genClosureVar(p: BProc, a: PNode) =
     genLineDir(p, a)
     loadInto(p, a.sons[0], a.sons[2], v)
 
-proc genVarStmt(p: BProc, n: PNode) = 
-  for i in countup(0, sonsLen(n) - 1): 
+proc genVarStmt(p: BProc, n: PNode) =
+  for i in countup(0, sonsLen(n) - 1):
     var a = n.sons[i]
-    if a.kind == nkCommentStmt: continue 
+    if a.kind == nkCommentStmt: continue
     if a.kind == nkIdentDefs:
       # can be a lifted var nowadays ...
       if a.sons[0].kind == nkSym:
@@ -242,12 +254,12 @@ proc genVarStmt(p: BProc, n: PNode) =
     else:
       genVarTuple(p, a)
 
-proc genConstStmt(p: BProc, t: PNode) = 
-  for i in countup(0, sonsLen(t) - 1): 
+proc genConstStmt(p: BProc, t: PNode) =
+  for i in countup(0, sonsLen(t) - 1):
     var it = t.sons[i]
-    if it.kind == nkCommentStmt: continue 
+    if it.kind == nkCommentStmt: continue
     if it.kind != nkConstDef: internalError(t.info, "genConstStmt")
-    var c = it.sons[0].sym 
+    var c = it.sons[0].sym
     if c.typ.containsCompileTimeOnly: continue
     if sfFakeConst in c.flags:
       genSingleVar(p, it)
@@ -274,9 +286,9 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
     getTemp(p, n.typ, d)
   genLineDir(p, n)
   let lend = getLabel(p)
-  for i in countup(0, sonsLen(n) - 1): 
+  for i in countup(0, sonsLen(n) - 1):
     let it = n.sons[i]
-    if it.len == 2: 
+    if it.len == 2:
       when newScopeForIf: startBlock(p)
       initLocExprSingleUse(p, it.sons[0], a)
       lelse = getLabel(p)
@@ -303,13 +315,13 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
   if sonsLen(n) > 1: fixLabel(p, lend)
 
 
-proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) = 
+proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
   # Called by return and break stmts.
   # Deals with issues faced when jumping out of try/except/finally stmts,
 
   var stack: seq[PNode]
   newSeq(stack, 0)
-  
+
   var alreadyPoppedCnt = p.inExceptBlock
   for i in countup(1, howManyTrys):
     if not p.module.compileToCpp:
@@ -327,11 +339,11 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
     # Find finally-stmt for this try-stmt
     # and generate a copy of its sons
     var finallyStmt = lastSon(tryStmt)
-    if finallyStmt.kind == nkFinally: 
+    if finallyStmt.kind == nkFinally:
       genStmts(p, finallyStmt.sons[0])
 
   # push old elements again:
-  for i in countdown(howManyTrys-1, 0): 
+  for i in countdown(howManyTrys-1, 0):
     p.nestedTryStmts.add(stack[i])
 
   if not p.module.compileToCpp:
@@ -344,14 +356,14 @@ proc genReturnStmt(p: BProc, t: PNode) =
   p.beforeRetNeeded = true
   genLineDir(p, t)
   if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
-  blockLeaveActions(p, 
+  blockLeaveActions(p,
     howManyTrys    = p.nestedTryStmts.len,
     howManyExcepts = p.inExceptBlock)
   if (p.finallySafePoints.len > 0):
     # If we're in a finally block, and we came here by exception
     # consume it before we return.
     var safePoint = p.finallySafePoints[p.finallySafePoints.len-1]
-    linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", safePoint)    
+    linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", safePoint)
   lineF(p, cpsStmts, "goto BeforeRet;$n", [])
 
 proc genComputedGoto(p: BProc; n: PNode) =
@@ -387,7 +399,7 @@ proc genComputedGoto(p: BProc; n: PNode) =
   let topBlock = p.blocks.len-1
   let oldBody = p.blocks[topBlock].sections[cpsStmts]
   p.blocks[topBlock].sections[cpsStmts] = nil
-  
+
   for j in casePos+1 .. <n.len: genStmts(p, n.sons[j])
   let tailB = p.blocks[topBlock].sections[cpsStmts]
 
@@ -402,7 +414,7 @@ proc genComputedGoto(p: BProc; n: PNode) =
   initLocExpr(p, caseStmt.sons[0], a)
   # first goto:
   lineF(p, cpsStmts, "goto *$#[$#];$n", tmp, a.rdLoc)
-  
+
   for i in 1 .. <caseStmt.len:
     startBlock(p)
     let it = caseStmt.sons[i]
@@ -426,7 +438,7 @@ proc genComputedGoto(p: BProc; n: PNode) =
 proc genWhileStmt(p: BProc, t: PNode) =
   # we don't generate labels here as for example GCC would produce
   # significantly worse code
-  var 
+  var
     a: TLoc
     labl: TLabel
   assert(sonsLen(t) == 2)
@@ -437,7 +449,7 @@ proc genWhileStmt(p: BProc, t: PNode) =
     p.breakIdx = startBlock(p, "while (1) {$n")
     p.blocks[p.breakIdx].isLoop = true
     initLocExpr(p, t.sons[0], a)
-    if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0): 
+    if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
       let label = assignLabel(p.blocks[p.breakIdx])
       lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
     var loopBody = t.sons[1]
@@ -483,23 +495,23 @@ proc genParForStmt(p: BProc, t: PNode) =
     let call = t.sons[1]
     initLocExpr(p, call.sons[1], rangeA)
     initLocExpr(p, call.sons[2], rangeB)
-    
+
     lineF(p, cpsStmts, "#pragma omp parallel for $4$n" &
-                        "for ($1 = $2; $1 <= $3; ++$1)", 
+                        "for ($1 = $2; $1 <= $3; ++$1)",
                         forLoopVar.loc.rdLoc,
                         rangeA.rdLoc, rangeB.rdLoc,
                         call.sons[3].getStr.toRope)
-    
+
     p.breakIdx = startBlock(p)
     p.blocks[p.breakIdx].isLoop = true
     genStmts(p, t.sons[2])
     endBlock(p)
 
   dec(p.withinLoop)
-  
-proc genBreakStmt(p: BProc, t: PNode) = 
+
+proc genBreakStmt(p: BProc, t: PNode) =
   var idx = p.breakIdx
-  if t.sons[0].kind != nkEmpty: 
+  if t.sons[0].kind != nkEmpty:
     # named break?
     assert(t.sons[0].kind == nkSym)
     var sym = t.sons[0].sym
@@ -511,13 +523,13 @@ proc genBreakStmt(p: BProc, t: PNode) =
     if idx < 0 or not p.blocks[idx].isLoop:
       internalError(t.info, "no loop to break")
   let label = assignLabel(p.blocks[idx])
-  blockLeaveActions(p, 
+  blockLeaveActions(p,
     p.nestedTryStmts.len - p.blocks[idx].nestedTryStmts,
     p.inExceptBlock - p.blocks[idx].nestedExceptStmts)
   genLineDir(p, t)
   lineF(p, cpsStmts, "goto $1;$n", [label])
 
-proc getRaiseFrmt(p: BProc): string = 
+proc getRaiseFrmt(p: BProc): string =
   if p.module.compileToCpp:
     result = "throw NimException($1, $2);$n"
   elif getCompilerProc("Exception") != nil:
@@ -532,7 +544,7 @@ proc genRaiseStmt(p: BProc, t: PNode) =
     var finallyBlock = p.nestedTryStmts[p.nestedTryStmts.len - 1].lastSon
     if finallyBlock.kind == nkFinally:
       genSimpleBlock(p, finallyBlock.sons[0])
-  if t.sons[0].kind != nkEmpty: 
+  if t.sons[0].kind != nkEmpty:
     var a: TLoc
     initLocExpr(p, t.sons[0], a)
     var e = rdLoc(a)
@@ -547,23 +559,23 @@ proc genRaiseStmt(p: BProc, t: PNode) =
     else:
       linefmt(p, cpsStmts, "#reraiseException();$n")
 
-proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc, 
-                          rangeFormat, eqFormat: TFormatStr, labl: TLabel) = 
-  var 
+proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
+                          rangeFormat, eqFormat: TFormatStr, labl: TLabel) =
+  var
     x, y: TLoc
   var length = sonsLen(b)
-  for i in countup(0, length - 2): 
-    if b.sons[i].kind == nkRange: 
+  for i in countup(0, length - 2):
+    if b.sons[i].kind == nkRange:
       initLocExpr(p, b.sons[i].sons[0], x)
       initLocExpr(p, b.sons[i].sons[1], y)
-      lineCg(p, cpsStmts, rangeFormat, 
+      lineCg(p, cpsStmts, rangeFormat,
            [rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl])
-    else: 
+    else:
       initLocExpr(p, b.sons[i], x)
       lineCg(p, cpsStmts, eqFormat, [rdCharLoc(e), rdCharLoc(x), labl])
 
-proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc, 
-                       labId, until: int): TLabel = 
+proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
+                       labId, until: int): TLabel =
   var lend = getLabel(p)
   for i in 1..until:
     lineF(p, cpsStmts, "LA$1: ;$n", [toRope(labId + i)])
@@ -596,23 +608,23 @@ proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
   else:
     result = genCaseSecondPass(p, t, d, labId, until)
 
-proc genCaseGeneric(p: BProc, t: PNode, d: var TLoc, 
-                    rangeFormat, eqFormat: TFormatStr) = 
+proc genCaseGeneric(p: BProc, t: PNode, d: var TLoc,
+                    rangeFormat, eqFormat: TFormatStr) =
   var a: TLoc
   initLocExpr(p, t.sons[0], a)
   var lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, sonsLen(t)-1, a)
   fixLabel(p, lend)
 
-proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel, 
-                         branches: var openArray[PRope]) = 
+proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel,
+                         branches: var openArray[PRope]) =
   var x: TLoc
   var length = sonsLen(b)
-  for i in countup(0, length - 2): 
+  for i in countup(0, length - 2):
     assert(b.sons[i].kind != nkRange)
     initLocExpr(p, b.sons[i], x)
     assert(b.sons[i].kind in {nkStrLit..nkTripleStrLit})
     var j = int(hashString(b.sons[i].strVal) and high(branches))
-    appcg(p.module, branches[j], "if (#eqStrings($1, $2)) goto $3;$n", 
+    appcg(p.module, branches[j], "if (#eqStrings($1, $2)) goto $3;$n",
          [rdLoc(e), rdLoc(x), labl])
 
 proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
@@ -627,35 +639,35 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
     var a: TLoc
     initLocExpr(p, t.sons[0], a) # fist pass: gnerate ifs+goto:
     var labId = p.labels
-    for i in countup(1, sonsLen(t) - 1): 
+    for i in countup(1, sonsLen(t) - 1):
       inc(p.labels)
-      if t.sons[i].kind == nkOfBranch: 
-        genCaseStringBranch(p, t.sons[i], a, con("LA", toRope(p.labels)), 
+      if t.sons[i].kind == nkOfBranch:
+        genCaseStringBranch(p, t.sons[i], a, con("LA", toRope(p.labels)),
                             branches)
-      else: 
+      else:
         # else statement: nothing to do yet
         # but we reserved a label, which we use later
         discard
-    linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n", 
+    linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
             rdLoc(a), toRope(bitMask))
     for j in countup(0, high(branches)):
       if branches[j] != nil:
-        lineF(p, cpsStmts, "case $1: $n$2break;$n", 
+        lineF(p, cpsStmts, "case $1: $n$2break;$n",
              [intLiteral(j), branches[j]])
     lineF(p, cpsStmts, "}$n") # else statement:
-    if t.sons[sonsLen(t)-1].kind != nkOfBranch: 
-      lineF(p, cpsStmts, "goto LA$1;$n", [toRope(p.labels)]) 
+    if t.sons[sonsLen(t)-1].kind != nkOfBranch:
+      lineF(p, cpsStmts, "goto LA$1;$n", [toRope(p.labels)])
     # third pass: generate statements
     var lend = genCaseSecondPass(p, t, d, labId, sonsLen(t)-1)
     fixLabel(p, lend)
   else:
     genCaseGeneric(p, t, d, "", "if (#eqStrings($1, $2)) goto $3;$n")
-  
-proc branchHasTooBigRange(b: PNode): bool = 
-  for i in countup(0, sonsLen(b)-2): 
+
+proc branchHasTooBigRange(b: PNode): bool =
+  for i in countup(0, sonsLen(b)-2):
     # last son is block
     if (b.sons[i].kind == nkRange) and
-        b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit: 
+        b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit:
       return true
 
 proc ifSwitchSplitPoint(p: BProc, n: PNode): int =
@@ -664,21 +676,21 @@ proc ifSwitchSplitPoint(p: BProc, n: PNode): int =
     var stmtBlock = lastSon(branch)
     if stmtBlock.stmtsContainPragma(wLinearScanEnd):
       result = i
-    elif hasSwitchRange notin CC[cCompiler].props: 
-      if branch.kind == nkOfBranch and branchHasTooBigRange(branch): 
+    elif hasSwitchRange notin CC[cCompiler].props:
+      if branch.kind == nkOfBranch and branchHasTooBigRange(branch):
         result = i
 
 proc genCaseRange(p: BProc, branch: PNode) =
   var length = branch.len
-  for j in 0 .. length-2: 
-    if branch[j].kind == nkRange: 
-      if hasSwitchRange in CC[cCompiler].props: 
+  for j in 0 .. length-2:
+    if branch[j].kind == nkRange:
+      if hasSwitchRange in CC[cCompiler].props:
         lineF(p, cpsStmts, "case $1 ... $2:$n", [
-            genLiteral(p, branch[j][0]), 
+            genLiteral(p, branch[j][0]),
             genLiteral(p, branch[j][1])])
-      else: 
+      else:
         var v = copyNode(branch[j][0])
-        while v.intVal <= branch[j][1].intVal: 
+        while v.intVal <= branch[j][1].intVal:
           lineF(p, cpsStmts, "case $1:$n", [genLiteral(p, v)])
           inc(v.intVal)
     else:
@@ -687,53 +699,53 @@ proc genCaseRange(p: BProc, branch: PNode) =
 proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
   # analyse 'case' statement:
   var splitPoint = ifSwitchSplitPoint(p, n)
-  
+
   # generate if part (might be empty):
   var a: TLoc
   initLocExpr(p, n.sons[0], a)
   var lend = if splitPoint > 0: genIfForCaseUntil(p, n, d,
                     rangeFormat = "if ($1 >= $2 && $1 <= $3) goto $4;$n",
-                    eqFormat = "if ($1 == $2) goto $3;$n", 
+                    eqFormat = "if ($1 == $2) goto $3;$n",
                     splitPoint, a) else: nil
-  
+
   # generate switch part (might be empty):
   if splitPoint+1 < n.len:
     lineF(p, cpsStmts, "switch ($1) {$n", [rdCharLoc(a)])
     var hasDefault = false
-    for i in splitPoint+1 .. < n.len: 
+    for i in splitPoint+1 .. < n.len:
       var branch = n[i]
-      if branch.kind == nkOfBranch: 
+      if branch.kind == nkOfBranch:
         genCaseRange(p, branch)
-      else: 
+      else:
         # else part of case statement:
         lineF(p, cpsStmts, "default:$n")
         hasDefault = true
       exprBlock(p, branch.lastSon, d)
       lineF(p, cpsStmts, "break;$n")
-    if (hasAssume in CC[cCompiler].props) and not hasDefault: 
+    if (hasAssume in CC[cCompiler].props) and not hasDefault:
       lineF(p, cpsStmts, "default: __assume(0);$n")
     lineF(p, cpsStmts, "}$n")
   if lend != nil: fixLabel(p, lend)
-  
-proc genCase(p: BProc, t: PNode, d: var TLoc) = 
+
+proc genCase(p: BProc, t: PNode, d: var TLoc) =
   genLineDir(p, t)
   if not isEmptyType(t.typ) and d.k == locNone:
     getTemp(p, t.typ, d)
   case skipTypes(t.sons[0].typ, abstractVarRange).kind
   of tyString:
     genStringCase(p, t, d)
-  of tyFloat..tyFloat128: 
-    genCaseGeneric(p, t, d, "if ($1 >= $2 && $1 <= $3) goto $4;$n", 
+  of tyFloat..tyFloat128:
+    genCaseGeneric(p, t, d, "if ($1 >= $2 && $1 <= $3) goto $4;$n",
                             "if ($1 == $2) goto $3;$n")
   else:
     genOrdinalCase(p, t, d)
-  
-proc hasGeneralExceptSection(t: PNode): bool = 
+
+proc hasGeneralExceptSection(t: PNode): bool =
   var length = sonsLen(t)
   var i = 1
-  while (i < length) and (t.sons[i].kind == nkExceptBranch): 
+  while (i < length) and (t.sons[i].kind == nkExceptBranch):
     var blen = sonsLen(t.sons[i])
-    if blen == 1: 
+    if blen == 1:
       return true
     inc(i)
   result = false
@@ -798,7 +810,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
       lineF(p, cpsStmts, "if ($1) ", [orExpr])
       exprBlock(p, t.sons[i].sons[blen-1], d)
     inc(i)
-  
+
   # reraise the exception if there was no catch all
   # and none of the handlers matched
   if not catchAllPresent:
@@ -811,15 +823,15 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
 
     line(p, cpsStmts, ~"throw;$n")
     endBlock(p)
-  
+
   lineF(p, cpsStmts, "}$n") # end of catch block
   dec p.inExceptBlock
-  
+
   discard pop(p.nestedTryStmts)
   if (i < length) and (t.sons[i].kind == nkFinally):
     genSimpleBlock(p, t.sons[i].sons[0])
-  
-proc genTry(p: BProc, t: PNode, d: var TLoc) = 
+
+proc genTry(p: BProc, t: PNode, d: var TLoc) =
   # code to generate:
   #
   # XXX: There should be a standard dispatch algorithm
@@ -841,7 +853,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
   #      clearException();
   #    }
   #  }
-  #  { 
+  #  {
   #    /* finally: */
   #    printf('fin!\n');
   #  }
@@ -927,14 +939,14 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope =
         res.add(rdLoc(a).ropeToStr)
       else:
         var r = sym.loc.r
-        if r == nil: 
+        if r == nil:
           # if no name has already been given,
           # it doesn't matter much:
           r = mangleName(sym)
           sym.loc.r = r       # but be consequent!
         res.add(r.ropeToStr)
     else: internalError(t.sons[i].info, "genAsmOrEmitStmt()")
-  
+
   if isAsmStmt and hasGnuAsm in CC[cCompiler].props:
     for x in splitLines(res):
       var j = 0
@@ -952,40 +964,43 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope =
     res.add(tnl)
     result = res.toRope
 
-proc genAsmStmt(p: BProc, t: PNode) = 
+proc genAsmStmt(p: BProc, t: PNode) =
   assert(t.kind == nkAsmStmt)
   genLineDir(p, t)
   var s = genAsmOrEmitStmt(p, t, isAsmStmt=true)
+  # see bug #2362, "top level asm statements" seem to be a mis-feature
+  # but even if we don't do this, the example in #2362 cannot possibly
+  # work:
   if p.prc == nil:
     # top level asm statement?
     appf(p.module.s[cfsProcHeaders], CC[cCompiler].asmStmtFrmt, [s])
   else:
     lineF(p, cpsStmts, CC[cCompiler].asmStmtFrmt, [s])
 
-proc genEmit(p: BProc, t: PNode) = 
+proc genEmit(p: BProc, t: PNode) =
   genLineDir(p, t)
   var s = genAsmOrEmitStmt(p, t.sons[1])
-  if p.prc == nil: 
+  if p.prc == nil:
     # top level emit pragma?
     app(p.module.s[cfsProcHeaders], s)
   else:
     line(p, cpsStmts, s)
 
-var 
+var
   breakPointId: int = 0
   gBreakpoints: PRope # later the breakpoints are inserted into the main proc
 
-proc genBreakPoint(p: BProc, t: PNode) = 
+proc genBreakPoint(p: BProc, t: PNode) =
   var name: string
   if optEndb in p.options:
-    if t.kind == nkExprColonExpr: 
+    if t.kind == nkExprColonExpr:
       assert(t.sons[1].kind in {nkStrLit..nkTripleStrLit})
       name = normalize(t.sons[1].strVal)
-    else: 
+    else:
       inc(breakPointId)
       name = "bp" & $breakPointId
     genLineDir(p, t)          # BUGFIX
-    appcg(p.module, gBreakpoints, 
+    appcg(p.module, gBreakpoints,
          "#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [
         toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)),
         makeCString(name)])
@@ -1006,14 +1021,14 @@ proc genPragma(p: BProc, n: PNode) =
     of wEmit: genEmit(p, it)
     of wBreakpoint: genBreakPoint(p, it)
     of wWatchPoint: genWatchpoint(p, it)
-    of wInjectStmt: 
+    of wInjectStmt:
       var p = newProc(nil, p.module)
       p.options = p.options - {optLineTrace, optStackTrace}
       genStmts(p, it.sons[1])
       p.module.injectStmt = p.s(cpsStmts)
     else: discard
 
-proc fieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool = 
+proc fieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool =
   if optFieldCheck in p.options:
     var le = asgn.sons[0]
     if le.kind == nkCheckedFieldExpr:
@@ -1021,23 +1036,23 @@ proc fieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool =
       result = sfDiscriminant in field.flags
     elif le.kind == nkDotExpr:
       var field = le.sons[1].sym
-      result = sfDiscriminant in field.flags      
+      result = sfDiscriminant in field.flags
 
-proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType, 
-                          field: PSym) = 
+proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
+                          field: PSym) =
   var t = skipTypes(objtype, abstractVar)
   assert t.kind == tyObject
   discard genTypeInfo(p.module, t)
   var L = lengthOrd(field.typ)
   if not containsOrIncl(p.module.declaredThings, field.id):
-    appcg(p.module, cfsVars, "extern $1", 
+    appcg(p.module, cfsVars, "extern $1",
           discriminatorTableDecl(p.module, t, field))
   lineCg(p, cpsStmts,
         "#FieldDiscriminantCheck((NI)(NU)($1), (NI)(NU)($2), $3, $4);$n",
         [rdLoc(a), rdLoc(tmp), discriminatorTableName(p.module, t, field),
          intLiteral(L+1)])
 
-proc asgnFieldDiscriminant(p: BProc, e: PNode) = 
+proc asgnFieldDiscriminant(p: BProc, e: PNode) =
   var a, tmp: TLoc
   var dotExpr = e.sons[0]
   var d: PSym
@@ -1047,8 +1062,8 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) =
   expr(p, e.sons[1], tmp)
   genDiscriminantCheck(p, a, tmp, dotExpr.sons[0].typ, dotExpr.sons[1].sym)
   genAssignment(p, a, tmp, {})
-  
-proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) = 
+
+proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) =
   genLineDir(p, e)
   if not fieldDiscriminantCheckNeeded(p, e):
     var a: TLoc
@@ -1059,7 +1074,7 @@ proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) =
   else:
     asgnFieldDiscriminant(p, e)
 
-proc genStmts(p: BProc, t: PNode) = 
+proc genStmts(p: BProc, t: PNode) =
   var a: TLoc
   expr(p, t, a)
   internalAssert a.k in {locNone, locTemp, locLocalVar}
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index cc376d87a..0b0526b65 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -9,7 +9,7 @@
 
 ## This module implements the C code generator.
 
-import 
+import
   ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
   options, intsets,
   nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
@@ -25,7 +25,7 @@ when options.hasTinyCBackend:
 var
   generatedHeader: BModule
 
-proc addForwardedProc(m: BModule, prc: PSym) = 
+proc addForwardedProc(m: BModule, prc: PSym) =
   m.forwardedProcs.add(prc)
   inc(gForwardedProcsCounter)
 
@@ -33,7 +33,7 @@ proc getCgenModule(s: PSym): BModule =
   result = if s.position >= 0 and s.position < gModules.len: gModules[s.position]
            else: nil
 
-proc findPendingModule(m: BModule, s: PSym): BModule = 
+proc findPendingModule(m: BModule, s: PSym): BModule =
   var ms = getModule(s)
   result = gModules[ms.position]
 
@@ -41,21 +41,21 @@ proc emitLazily(s: PSym): bool {.inline.} =
   result = optDeadCodeElim in gGlobalOptions or
            sfDeadCodeElim in getModule(s).flags
 
-proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) = 
+proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) =
   result.k = k
   result.s = s
   result.t = typ
   result.r = nil
   result.flags = {}
 
-proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) = 
+proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) =
   # fills the loc if it is not already initialized
-  if a.k == locNone: 
+  if a.k == locNone:
     a.k = k
     a.t = typ
     a.s = s
     if a.r == nil: a.r = r
-  
+
 proc isSimpleConst(typ: PType): bool =
   let t = skipTypes(typ, abstractVar)
   result = t.kind notin
@@ -67,43 +67,43 @@ proc useStringh(m: BModule) =
     m.includesStringh = true
     discard lists.includeStr(m.headerFiles, "<string.h>")
 
-proc useHeader(m: BModule, sym: PSym) = 
-  if lfHeader in sym.loc.flags: 
+proc useHeader(m: BModule, sym: PSym) =
+  if lfHeader in sym.loc.flags:
     assert(sym.annex != nil)
     discard lists.includeStr(m.headerFiles, getStr(sym.annex.path))
 
 proc cgsym(m: BModule, name: string): PRope
 
-proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope = 
+proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
   var i = 0
   var length = len(frmt)
   result = nil
   var num = 0
-  while i < length: 
-    if frmt[i] == '$': 
+  while i < length:
+    if frmt[i] == '$':
       inc(i)                  # skip '$'
       case frmt[i]
-      of '$': 
+      of '$':
         app(result, "$")
         inc(i)
-      of '#': 
+      of '#':
         inc(i)
         app(result, args[num])
         inc(num)
-      of '0'..'9': 
+      of '0'..'9':
         var j = 0
-        while true: 
+        while true:
           j = (j * 10) + ord(frmt[i]) - ord('0')
           inc(i)
-          if i >= length or not (frmt[i] in {'0'..'9'}): break 
+          if i >= length or not (frmt[i] in {'0'..'9'}): break
         num = j
-        if j > high(args) + 1: 
+        if j > high(args) + 1:
           internalError("ropes: invalid format string $" & $j)
         app(result, args[j-1])
       of 'n':
         if optLineDir notin gOptions: app(result, rnl)
         inc(i)
-      of 'N': 
+      of 'N':
         app(result, rnl)
         inc(i)
       else: internalError("ropes: invalid format string $" & frmt[i])
@@ -117,37 +117,37 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
     elif frmt[i] == '#' and frmt[i+1] == '$':
       inc(i, 2)
       var j = 0
-      while frmt[i] in Digits: 
+      while frmt[i] in Digits:
         j = (j * 10) + ord(frmt[i]) - ord('0')
         inc(i)
       app(result, cgsym(m, args[j-1].ropeToStr))
     var start = i
-    while i < length: 
+    while i < length:
       if frmt[i] != '$' and frmt[i] != '#': inc(i)
-      else: break 
-    if i - 1 >= start: 
+      else: break
+    if i - 1 >= start:
       app(result, substr(frmt, start, i - 1))
 
 template rfmt(m: BModule, fmt: string, args: varargs[PRope]): expr =
   ropecg(m, fmt, args)
 
-proc appcg(m: BModule, c: var PRope, frmt: TFormatStr, 
-           args: varargs[PRope]) = 
+proc appcg(m: BModule, c: var PRope, frmt: TFormatStr,
+           args: varargs[PRope]) =
   app(c, ropecg(m, frmt, args))
 
-proc appcg(m: BModule, s: TCFileSection, frmt: TFormatStr, 
-           args: varargs[PRope]) = 
+proc appcg(m: BModule, s: TCFileSection, frmt: TFormatStr,
+           args: varargs[PRope]) =
   app(m.s[s], ropecg(m, frmt, args))
 
-proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr, 
-           args: varargs[PRope]) = 
+proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr,
+           args: varargs[PRope]) =
   app(p.s(s), ropecg(p.module, frmt, args))
 
 var indent = "\t".toRope
 proc indentLine(p: BProc, r: PRope): PRope =
   result = r
   for i in countup(0, p.blocks.len-1): prepend(result, indent)
-  
+
 proc line(p: BProc, s: TCProcSection, r: PRope) =
   app(p.s(s), indentLine(p, r))
 
@@ -180,7 +180,7 @@ proc genCLineDir(r: var PRope, filename: string, line: int) =
     appf(r, "$N#line $2 $1$N",
         [toRope(makeSingleLineCString(filename)), toRope(line)])
 
-proc genCLineDir(r: var PRope, info: TLineInfo) = 
+proc genCLineDir(r: var PRope, info: TLineInfo) =
   genCLineDir(r, info.toFullPath, info.safeLineNm)
 
 proc genLineDir(p: BProc, t: PNode) =
@@ -261,7 +261,9 @@ proc isComplexValueType(t: PType): bool {.inline.} =
 
 proc resetLoc(p: BProc, loc: var TLoc) =
   let containsGcRef = containsGarbageCollectedRef(loc.t)
-  if not isComplexValueType(skipTypes(loc.t, abstractVarRange)):
+  let typ = skipTypes(loc.t, abstractVarRange)
+  if isImportedCppType(typ): return
+  if not isComplexValueType(typ):
     if containsGcRef:
       var nilLoc: TLoc
       initLoc(nilLoc, locTemp, loc.t, OnStack)
@@ -282,35 +284,37 @@ proc resetLoc(p: BProc, loc: var TLoc) =
       useStringh(p.module)
       linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n",
               addrLoc(loc), rdLoc(loc))
-      # XXX: We can be extra clever here and call memset only 
+      # XXX: We can be extra clever here and call memset only
       # on the bytes following the m_type field?
       genObjectInit(p, cpsStmts, loc.t, loc, true)
 
 proc constructLoc(p: BProc, loc: TLoc, isTemp = false) =
-  if not isComplexValueType(skipTypes(loc.t, abstractRange)):
+  let typ = skipTypes(loc.t, abstractRange)
+  if not isComplexValueType(typ):
     linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc))
   else:
     if not isTemp or containsGarbageCollectedRef(loc.t):
       # don't use memset for temporary values for performance if we can
       # avoid it:
-      useStringh(p.module)
-      linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n",
-              addrLoc(loc), rdLoc(loc))
+      if not isImportedCppType(typ):
+        useStringh(p.module)
+        linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n",
+                addrLoc(loc), rdLoc(loc))
     genObjectInit(p, cpsStmts, loc.t, loc, true)
 
 proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
   if sfNoInit notin v.flags:
     # we know it is a local variable and thus on the stack!
     # If ``not immediateAsgn`` it is not initialized in a binding like
-    # ``var v = X`` and thus we need to init it. 
+    # ``var v = X`` and thus we need to init it.
     # If ``v`` contains a GC-ref we may pass it to ``unsureAsgnRef`` somehow
     # which requires initialization. However this can really only happen if
-    # ``var v = X()`` gets transformed into ``X(&v)``. 
+    # ``var v = X()`` gets transformed into ``X(&v)``.
     # Nowadays the logic in ccgcalls deals with this case however.
     if not immediateAsgn:
       constructLoc(p, v.loc)
 
-proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) = 
+proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) =
   inc(p.labels)
   result.r = con("LOC", toRope(p.labels))
   linefmt(p, cpsLocals, "$1 $2;$n", getTypeDesc(p.module, t), result.r)
@@ -353,20 +357,9 @@ proc deinitGCFrame(p: BProc): PRope =
   if p.gcFrameId > 0:
     result = ropecg(p.module,
                     "if (((NU)&GCFRAME) < 4096) #nimGCFrame(&GCFRAME);$n")
-  
-proc allocParam(p: BProc, s: PSym) = 
-  assert(s.kind == skParam)
-  if lfParamCopy notin s.loc.flags: 
-    inc(p.labels)
-    var tmp = con("%LOC", toRope(p.labels))
-    incl(s.loc.flags, lfParamCopy)
-    incl(s.loc.flags, lfIndirect)
-    lineF(p, cpsInit, "$1 = alloca $3$n" & "store $3 $2, $3* $1$n",
-         [tmp, s.loc.r, getTypeDesc(p.module, s.loc.t)])
-    s.loc.r = tmp
-
-proc localDebugInfo(p: BProc, s: PSym) = 
-  if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return 
+
+proc localDebugInfo(p: BProc, s: PSym) =
+  if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return
   # XXX work around a bug: No type information for open arrays possible:
   if skipTypes(s.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: return
   var a = con("&", s.loc.r)
@@ -379,7 +372,7 @@ proc localDebugInfo(p: BProc, s: PSym) =
   inc p.blocks[p.blocks.len-1].frameLen
 
 proc localVarDecl(p: BProc; s: PSym): PRope =
-  if s.loc.k == locNone: 
+  if s.loc.k == locNone:
     fillLoc(s.loc, locLocalVar, s.typ, mangleName(s), OnStack)
     if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy)
   result = getTypeDesc(p.module, s.loc.t)
@@ -406,22 +399,22 @@ include ccgthreadvars
 proc varInDynamicLib(m: BModule, sym: PSym)
 proc mangleDynLibProc(sym: PSym): PRope
 
-proc assignGlobalVar(p: BProc, s: PSym) = 
-  if s.loc.k == locNone: 
+proc assignGlobalVar(p: BProc, s: PSym) =
+  if s.loc.k == locNone:
     fillLoc(s.loc, locGlobalVar, s.typ, mangleName(s), OnHeap)
-  
+
   if lfDynamicLib in s.loc.flags:
     var q = findPendingModule(p.module, s)
-    if q != nil and not containsOrIncl(q.declaredThings, s.id): 
+    if q != nil and not containsOrIncl(q.declaredThings, s.id):
       varInDynamicLib(q, s)
     else:
       s.loc.r = mangleDynLibProc(s)
     return
   useHeader(p.module, s)
   if lfNoDecl in s.loc.flags: return
-  if sfThread in s.flags: 
+  if sfThread in s.flags:
     declareThreadVar(p.module, s, sfImportc in s.flags)
-  else: 
+  else:
     var decl: PRope = nil
     var td = getTypeDesc(p.module, s.loc.t)
     if s.constraint.isNil:
@@ -437,25 +430,25 @@ proc assignGlobalVar(p: BProc, s: PSym) =
     # fixes tests/run/tzeroarray:
     resetLoc(p, s.loc)
   if p.module.module.options * {optStackTrace, optEndb} ==
-                               {optStackTrace, optEndb}: 
-    appcg(p.module, p.module.s[cfsDebugInit], 
-          "#dbgRegisterGlobal($1, &$2, $3);$n", 
-         [makeCString(normalize(s.owner.name.s & '.' & s.name.s)), 
+                               {optStackTrace, optEndb}:
+    appcg(p.module, p.module.s[cfsDebugInit],
+          "#dbgRegisterGlobal($1, &$2, $3);$n",
+         [makeCString(normalize(s.owner.name.s & '.' & s.name.s)),
           s.loc.r, genTypeInfo(p.module, s.typ)])
-  
-proc assignParam(p: BProc, s: PSym) = 
+
+proc assignParam(p: BProc, s: PSym) =
   assert(s.loc.r != nil)
   localDebugInfo(p, s)
 
-proc fillProcLoc(sym: PSym) = 
-  if sym.loc.k == locNone: 
+proc fillProcLoc(sym: PSym) =
+  if sym.loc.k == locNone:
     fillLoc(sym.loc, locProc, sym.typ, mangleName(sym), OnStack)
-  
-proc getLabel(p: BProc): TLabel = 
+
+proc getLabel(p: BProc): TLabel =
   inc(p.labels)
   result = con("LA", toRope(p.labels))
 
-proc fixLabel(p: BProc, labl: TLabel) = 
+proc fixLabel(p: BProc, labl: TLabel) =
   lineF(p, cpsStmts, "$1: ;$n", [labl])
 
 proc genVarPrototype(m: BModule, sym: PSym)
@@ -467,6 +460,7 @@ proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc)
 proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags)
 proc intLiteral(i: BiggestInt): PRope
 proc genLiteral(p: BProc, n: PNode): PRope
+proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType): PRope
 
 proc initLocExpr(p: BProc, e: PNode, result: var TLoc) =
   initLoc(result, locNone, e.typ, OnUnknown)
@@ -487,12 +481,12 @@ include ccgcalls, "ccgstmts.nim", "ccgexprs.nim"
 
 proc isGetProcAddr(lib: PLib): bool =
   let n = lib.path
-  result = n.kind in nkCallKinds and n.typ != nil and 
+  result = n.kind in nkCallKinds and n.typ != nil and
     n.typ.kind in {tyPointer, tyProc}
 
-proc loadDynamicLib(m: BModule, lib: PLib) = 
+proc loadDynamicLib(m: BModule, lib: PLib) =
   assert(lib != nil)
-  if not lib.generated: 
+  if not lib.generated:
     lib.generated = true
     var tmp = getGlobalTempName()
     assert(lib.name == nil)
@@ -504,14 +498,14 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
       if gVerbosity >= 2:
         msgWriteln("Dependency: " & lib.path.strVal)
       var loadlib: PRope = nil
-      for i in countup(0, high(s)): 
+      for i in countup(0, high(s)):
         inc(m.labels)
         if i > 0: app(loadlib, "||")
-        appcg(m, loadlib, "($1 = #nimLoadLibrary((#NimStringDesc*) &$2))$n", 
+        appcg(m, loadlib, "($1 = #nimLoadLibrary((#NimStringDesc*) &$2))$n",
               [tmp, getStrLit(m, s[i])])
-      appcg(m, m.s[cfsDynLibInit], 
-            "if (!($1)) #nimLoadLibraryError((#NimStringDesc*) &$2);$n", 
-            [loadlib, getStrLit(m, lib.path.strVal)]) 
+      appcg(m, m.s[cfsDynLibInit],
+            "if (!($1)) #nimLoadLibraryError((#NimStringDesc*) &$2);$n",
+            [loadlib, getStrLit(m, lib.path.strVal)])
     else:
       var p = newProc(nil, m)
       p.options = p.options - {optStackTrace, optEndb}
@@ -520,20 +514,20 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
       app(m.s[cfsVars], p.s(cpsLocals))
       app(m.s[cfsDynLibInit], p.s(cpsInit))
       app(m.s[cfsDynLibInit], p.s(cpsStmts))
-      appcg(m, m.s[cfsDynLibInit], 
-           "if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n", 
+      appcg(m, m.s[cfsDynLibInit],
+           "if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n",
            [tmp, rdLoc(dest)])
-      
+
   if lib.name == nil: internalError("loadDynamicLib")
-  
+
 proc mangleDynLibProc(sym: PSym): PRope =
-  if sfCompilerProc in sym.flags: 
+  if sfCompilerProc in sym.flags:
     # NOTE: sym.loc.r is the external name!
     result = toRope(sym.name.s)
   else:
     result = ropef("Dl_$1", [toRope(sym.id)])
-  
-proc symInDynamicLib(m: BModule, sym: PSym) = 
+
+proc symInDynamicLib(m: BModule, sym: PSym) =
   var lib = sym.annex
   let isCall = isGetProcAddr(lib)
   var extname = sym.loc.r
@@ -565,13 +559,13 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
     else:
       internalError(sym.info, "wrong index: " & idx)
   else:
-    appcg(m, m.s[cfsDynLibInit], 
-        "\t$1 = ($2) #nimGetProcAddr($3, $4);$n", 
-        [tmp, getTypeDesc(m, sym.typ), 
+    appcg(m, m.s[cfsDynLibInit],
+        "\t$1 = ($2) #nimGetProcAddr($3, $4);$n",
+        [tmp, getTypeDesc(m, sym.typ),
         lib.name, makeCString(ropeToStr(extname))])
   appf(m.s[cfsVars], "$2 $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)])
 
-proc varInDynamicLib(m: BModule, sym: PSym) = 
+proc varInDynamicLib(m: BModule, sym: PSym) =
   var lib = sym.annex
   var extname = sym.loc.r
   loadDynamicLib(m, lib)
@@ -579,9 +573,9 @@ proc varInDynamicLib(m: BModule, sym: PSym) =
   var tmp = mangleDynLibProc(sym)
   sym.loc.r = tmp             # from now on we only need the internal name
   inc(m.labels, 2)
-  appcg(m, m.s[cfsDynLibInit], 
-      "$1 = ($2*) #nimGetProcAddr($3, $4);$n", 
-      [tmp, getTypeDesc(m, sym.typ), 
+  appcg(m, m.s[cfsDynLibInit],
+      "$1 = ($2*) #nimGetProcAddr($3, $4);$n",
+      [tmp, getTypeDesc(m, sym.typ),
       lib.name, makeCString(ropeToStr(extname))])
   appf(m.s[cfsVars], "$2* $1;$n",
       [sym.loc.r, getTypeDesc(m, sym.loc.t)])
@@ -590,9 +584,9 @@ proc symInDynamicLibPartial(m: BModule, sym: PSym) =
   sym.loc.r = mangleDynLibProc(sym)
   sym.typ.sym = nil           # generate a new name
 
-proc cgsym(m: BModule, name: string): PRope = 
+proc cgsym(m: BModule, name: string): PRope =
   var sym = magicsys.getCompilerProc(name)
-  if sym != nil: 
+  if sym != nil:
     case sym.kind
     of skProc, skMethod, skConverter, skIterators: genProc(m, sym)
     of skVar, skResult, skLet: genVarPrototype(m, sym)
@@ -604,18 +598,18 @@ proc cgsym(m: BModule, name: string): PRope =
     # we're picky here for the system module too:
     rawMessage(errSystemNeeds, name)
   result = sym.loc.r
-  
+
 proc generateHeaders(m: BModule) =
   app(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl)
   var it = PStrEntry(m.headerFiles.head)
   while it != nil:
-    if it.data[0] notin {'\"', '<'}: 
+    if it.data[0] notin {'\"', '<'}:
       appf(m.s[cfsHeaders], "$N#include \"$1\"$N", [toRope(it.data)])
     else:
       appf(m.s[cfsHeaders], "$N#include $1$N", [toRope(it.data)])
     it = PStrEntry(it.next)
 
-proc retIsNotVoid(s: PSym): bool = 
+proc retIsNotVoid(s: PSym): bool =
   result = (s.typ.sons[0] != nil) and not isInvalidReturnType(s.typ.sons[0])
 
 proc initFrame(p: BProc, procname, filename: PRope): PRope =
@@ -663,11 +657,11 @@ proc genProcAux(m: BModule, prc: PSym) =
     else:
       fillResult(res)
       assignParam(p, res)
-      if skipTypes(res.typ, abstractInst).kind == tyArray: 
+      if skipTypes(res.typ, abstractInst).kind == tyArray:
         incl(res.loc.flags, lfIndirect)
         res.loc.s = OnUnknown
-    
-  for i in countup(1, sonsLen(prc.typ.n) - 1): 
+
+  for i in countup(1, sonsLen(prc.typ.n) - 1):
     var param = prc.typ.n.sons[i].sym
     if param.typ.isCompileTimeOnly: continue
     assignParam(p, param)
@@ -682,11 +676,11 @@ proc genProcAux(m: BModule, prc: PSym) =
   else:
     generatedProc = rfmt(nil, "$N$1 {$N", header)
     app(generatedProc, initGCFrame(p))
-    if optStackTrace in prc.options: 
+    if optStackTrace in prc.options:
       app(generatedProc, p.s(cpsLocals))
       var procname = makeCString(prc.name.s)
       app(generatedProc, initFrame(p, procname, prc.info.quotedFilename))
-    else: 
+    else:
       app(generatedProc, p.s(cpsLocals))
     if optProfiler in prc.options:
       # invoke at proc entry for recursion:
@@ -706,12 +700,12 @@ proc crossesCppBoundary(m: BModule; sym: PSym): bool {.inline.} =
            sfCompileToCpp notin sym.getModule().flags and
            gCmd != cmdCompileToCpp
 
-proc genProcPrototype(m: BModule, sym: PSym) = 
+proc genProcPrototype(m: BModule, sym: PSym) =
   useHeader(m, sym)
-  if lfNoDecl in sym.loc.flags: return 
+  if lfNoDecl in sym.loc.flags: return
   if lfDynamicLib in sym.loc.flags:
     if getModule(sym).id != m.module.id and
-        not containsOrIncl(m.declaredThings, sym.id): 
+        not containsOrIncl(m.declaredThings, sym.id):
       app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
                         getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
   elif not containsOrIncl(m.declaredProtos, sym.id):
@@ -722,13 +716,13 @@ proc genProcPrototype(m: BModule, sym: PSym) =
       header.app(" __attribute__((naked))")
     app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))
 
-proc genProcNoForward(m: BModule, prc: PSym) = 
+proc genProcNoForward(m: BModule, prc: PSym) =
   fillProcLoc(prc)
   useHeader(m, prc)
   if lfImportCompilerProc in prc.loc.flags:
     # dependency to a compilerproc:
     discard cgsym(m, prc.name.s)
-    return  
+    return
   genProcPrototype(m, prc)
   if lfNoDecl in prc.loc.flags: discard
   elif prc.typ.callConv == ccInline:
@@ -738,13 +732,13 @@ proc genProcNoForward(m: BModule, prc: PSym) =
     if not containsOrIncl(m.declaredThings, prc.id): genProcAux(m, prc)
   elif lfDynamicLib in prc.loc.flags:
     var q = findPendingModule(m, prc)
-    if q != nil and not containsOrIncl(q.declaredThings, prc.id): 
+    if q != nil and not containsOrIncl(q.declaredThings, prc.id):
       symInDynamicLib(q, prc)
     else:
       symInDynamicLibPartial(m, prc)
   elif sfImportc notin prc.flags:
     var q = findPendingModule(m, prc)
-    if q != nil and not containsOrIncl(q.declaredThings, prc.id): 
+    if q != nil and not containsOrIncl(q.declaredThings, prc.id):
       genProcAux(q, prc)
 
 proc requestConstImpl(p: BProc, sym: PSym) =
@@ -770,7 +764,7 @@ proc requestConstImpl(p: BProc, sym: PSym) =
 
 proc isActivated(prc: PSym): bool = prc.typ != nil
 
-proc genProc(m: BModule, prc: PSym) = 
+proc genProc(m: BModule, prc: PSym) =
   if sfBorrow in prc.flags or not isActivated(prc): return
   fillProcLoc(prc)
   if sfForward in prc.flags: addForwardedProc(m, prc)
@@ -780,19 +774,19 @@ proc genProc(m: BModule, prc: PSym) =
         generatedHeader != nil and lfNoDecl notin prc.loc.flags:
       genProcPrototype(generatedHeader, prc)
       if prc.typ.callConv == ccInline:
-        if not containsOrIncl(generatedHeader.declaredThings, prc.id): 
+        if not containsOrIncl(generatedHeader.declaredThings, prc.id):
           genProcAux(generatedHeader, prc)
 
-proc genVarPrototypeAux(m: BModule, sym: PSym) = 
+proc genVarPrototypeAux(m: BModule, sym: PSym) =
   assert(sfGlobal in sym.flags)
   useHeader(m, sym)
   fillLoc(sym.loc, locGlobalVar, sym.typ, mangleName(sym), OnHeap)
-  if (lfNoDecl in sym.loc.flags) or containsOrIncl(m.declaredThings, sym.id): 
-    return 
-  if sym.owner.id != m.module.id: 
+  if (lfNoDecl in sym.loc.flags) or containsOrIncl(m.declaredThings, sym.id):
+    return
+  if sym.owner.id != m.module.id:
     # else we already have the symbol generated!
     assert(sym.loc.r != nil)
-    if sfThread in sym.flags: 
+    if sfThread in sym.flags:
       declareThreadVar(m, sym, true)
     else:
       app(m.s[cfsVars], "extern ")
@@ -838,7 +832,7 @@ proc genFilenames(m: BModule): PRope =
     result.appf("dbgRegisterFilename($1);$N", fileInfos[i].projPath.makeCString)
 
 proc genMainProc(m: BModule) =
-  const 
+  const
     # The use of a volatile function pointer to call Pre/NimMainInner
     # prevents inlining of the NimMainInner function and dependent
     # functions, which might otherwise merge their stack frames.
@@ -859,7 +853,7 @@ proc genMainProc(m: BModule) =
 
     MainProcs =
       "\tNimMain();$N"
-    
+
     MainProcsWithResult =
       MainProcs & "\treturn nim_program_result;$N"
 
@@ -880,7 +874,7 @@ proc genMainProc(m: BModule) =
       "char** cmdLine;$N" &
       "char** gEnv;$N" &
       NimMainBody
-  
+
     PosixCMain =
       "int main(int argc, char** args, char** env) {$N" &
         "\tcmdLine = args;$N" &
@@ -888,20 +882,20 @@ proc genMainProc(m: BModule) =
         "\tgEnv = env;$N" &
         MainProcsWithResult &
       "}$N$N"
-  
+
     StandaloneCMain =
       "int main(void) {$N" &
         MainProcs &
         "\treturn 0;$N" &
       "}$N$N"
-    
+
     WinNimMain = NimMainBody
-    
+
     WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $N" &
       "                        HINSTANCE hPrevInstance, $N" &
       "                        LPSTR lpCmdLine, int nCmdShow) {$N" &
       MainProcsWithResult & "}$N$N"
-  
+
     WinNimDllMain = "N_LIB_EXPORT " & NimMainBody
 
     WinCDllMain =
@@ -911,7 +905,7 @@ proc genMainProc(m: BModule) =
       "\treturn 1;$N}$N$N"
 
     PosixNimDllMain = WinNimDllMain
-    
+
     PosixCDllMain =
       "void NIM_POSIX_INIT NimMainInit(void) {$N" &
         MainProcs &
@@ -919,11 +913,11 @@ proc genMainProc(m: BModule) =
 
   var nimMain, otherMain: TFormatStr
   if platform.targetOS == osWindows and
-      gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}: 
-    if optGenGuiApp in gGlobalOptions: 
+      gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}:
+    if optGenGuiApp in gGlobalOptions:
       nimMain = WinNimMain
       otherMain = WinCMain
-    else: 
+    else:
       nimMain = WinNimDllMain
       otherMain = WinCDllMain
     discard lists.includeStr(m.headerFiles, "<windows.h>")
@@ -939,7 +933,7 @@ proc genMainProc(m: BModule) =
   if gBreakpoints != nil: discard cgsym(m, "dbgRegisterBreakpoint")
   if optEndb in gOptions:
     gBreakpoints.app(m.genFilenames)
-  
+
   let initStackBottomCall =
     if platform.targetOS == osStandalone: "".toRope
     else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N")
@@ -964,11 +958,11 @@ proc getSomeInitName(m: PSym, suffix: string): PRope =
     result.app "_"
   result.app m.name.s
   result.app suffix
-  
+
 proc getInitName(m: PSym): PRope = getSomeInitName(m, "Init")
 proc getDatInitName(m: PSym): PRope = getSomeInitName(m, "DatInit")
 
-proc registerModuleToMain(m: PSym) = 
+proc registerModuleToMain(m: PSym) =
   var
     init = m.getInitName
     datInit = m.getDatInitName
@@ -981,19 +975,19 @@ proc registerModuleToMain(m: PSym) =
       app(mainModInit, initCall)
     else:
       app(otherModsInit, initCall)
-    
-proc genInitCode(m: BModule) = 
+
+proc genInitCode(m: BModule) =
   var initname = getInitName(m.module)
   var prc = ropef("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N", [initname])
-  if m.typeNodes > 0: 
-    appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n", 
+  if m.typeNodes > 0:
+    appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
           [m.typeNodesName, toRope(m.typeNodes)])
-  if m.nimTypes > 0: 
-    appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n", 
+  if m.nimTypes > 0:
+    appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n",
           [m.nimTypesName, toRope(m.nimTypes)])
-  
+
   app(prc, initGCFrame(m.initProc))
- 
+
   app(prc, genSectionStart(cpsLocals))
   app(prc, m.preInitProc.s(cpsLocals))
   app(prc, m.initProc.s(cpsLocals))
@@ -1009,7 +1003,7 @@ proc genInitCode(m: BModule) =
       app(prc, initFrame(m.initProc, procname, m.module.info.quotedFilename))
     else:
       app(prc, ~"\tTFrame F; F.len = 0;$N")
-    
+
   app(prc, genSectionStart(cpsInit))
   app(prc, m.preInitProc.s(cpsInit))
   app(prc, m.initProc.s(cpsInit))
@@ -1033,27 +1027,27 @@ proc genInitCode(m: BModule) =
     app(prc, genSectionStart(i))
     app(prc, m.s[i])
     app(prc, genSectionEnd(i))
-  
+
   appf(prc, "}$N$N")
   # we cannot simply add the init proc to ``m.s[cfsProcs]`` anymore because
   # that would lead to a *nesting* of merge sections which the merger does
   # not support. So we add it to another special section: ``cfsInitProc``
   app(m.s[cfsInitProc], prc)
-  
+
   for i, el in pairs(m.extensionLoaders):
     if el != nil:
       let ex = ropef("N_NIMCALL(void, nimLoadProcs$1)(void) {$2}$N$N",
         (i.ord - '0'.ord).toRope, el)
       app(m.s[cfsInitProc], ex)
 
-proc genModule(m: BModule, cfile: string): PRope = 
+proc genModule(m: BModule, cfile: string): PRope =
   result = getFileHeader(cfile)
   result.app(genMergeInfo(m))
-  
+
   generateHeaders(m)
 
   generateThreadLocalStorage(m)
-  for i in countup(cfsHeaders, cfsProcs): 
+  for i in countup(cfsHeaders, cfsProcs):
     app(result, genSectionStart(i))
     app(result, m.s[i])
     app(result, genSectionEnd(i))
@@ -1069,7 +1063,7 @@ proc newPostInitProc(m: BModule): BProc =
   # little hack so that unique temporaries are generated:
   result.labels = 200_000
 
-proc initProcOptions(m: BModule): TOptions = 
+proc initProcOptions(m: BModule): TOptions =
   if sfSystemModule in m.module.flags: gOptions-{optStackTrace} else: gOptions
 
 proc rawNewModule(module: PSym, filename: string): BModule =
@@ -1124,11 +1118,11 @@ proc resetModule*(m: BModule) =
   m.typeNodes = 0
   m.nimTypes = 0
   nullify m.extensionLoaders
-  
+
   # indicate that this is now cached module
   # the cache will be invalidated by nullifying gModules
   m.fromCache = true
-  
+
   # we keep only the "merge info" information for the module
   # and the properties that can't change:
   # m.filename
@@ -1155,11 +1149,11 @@ proc newModule(module: PSym): BModule =
   growCache gModules, module.position
   gModules[module.position] = result
 
-  if (optDeadCodeElim in gGlobalOptions): 
-    if (sfDeadCodeElim in module.flags): 
+  if (optDeadCodeElim in gGlobalOptions):
+    if (sfDeadCodeElim in module.flags):
       internalError("added pending module twice: " & module.filename)
 
-proc myOpen(module: PSym): PPassContext = 
+proc myOpen(module: PSym): PPassContext =
   result = newModule(module)
   if optGenIndex in gGlobalOptions and generatedHeader == nil:
     let f = if headerFile.len > 0: headerFile else: gProjectFull
@@ -1175,12 +1169,12 @@ proc writeHeader(m: BModule) =
   generateHeaders(m)
 
   generateThreadLocalStorage(m)
-  for i in countup(cfsHeaders, cfsProcs): 
+  for i in countup(cfsHeaders, cfsProcs):
     app(result, genSectionStart(i))
     app(result, m.s[i])
     app(result, genSectionEnd(i))
   app(result, m.s[cfsInitProc])
-  
+
   if optGenDynLib in gGlobalOptions:
     result.app("N_LIB_IMPORT ")
   result.appf("N_CDECL(void, NimMain)(void);$n")
@@ -1200,20 +1194,20 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
   readMergeInfo(getCFile(m), m)
   result = m
 
-proc myProcess(b: PPassContext, n: PNode): PNode = 
+proc myProcess(b: PPassContext, n: PNode): PNode =
   result = n
   if b == nil or passes.skipCodegen(n): return
   var m = BModule(b)
   m.initProc.options = initProcOptions(m)
   genStmts(m.initProc, n)
 
-proc finishModule(m: BModule) = 
+proc finishModule(m: BModule) =
   var i = 0
-  while i <= high(m.forwardedProcs): 
+  while i <= high(m.forwardedProcs):
     # Note: ``genProc`` may add to ``m.forwardedProcs``, so we cannot use
     # a ``for`` loop here
     var prc = m.forwardedProcs[i]
-    if sfForward in prc.flags: 
+    if sfForward in prc.flags:
       internalError(prc.info, "still forwarded: " & prc.name.s)
     genProcNoForward(m, prc)
     inc(i)
@@ -1221,13 +1215,13 @@ proc finishModule(m: BModule) =
   dec(gForwardedProcsCounter, i)
   setLen(m.forwardedProcs, 0)
 
-proc shouldRecompile(code: PRope, cfile: string): bool = 
+proc shouldRecompile(code: PRope, cfile: string): bool =
   result = true
   if optForceFullMake notin gGlobalOptions:
     var objFile = toObjFile(cfile)
-    if writeRopeIfNotEqual(code, cfile): return 
+    if writeRopeIfNotEqual(code, cfile): return
     if existsFile(objFile) and os.fileNewer(objFile, cfile): result = false
-  else: 
+  else:
     writeRope(code, cfile)
 
 # We need 2 different logics here: pending modules (including
@@ -1240,15 +1234,15 @@ proc writeModule(m: BModule, pending: bool) =
   # generate code for the init statements of the module:
   var cfile = getCFile(m)
   var cfilenoext = changeFileExt(cfile, "")
-  
+
   if not m.fromCache or optForceFullMake in gGlobalOptions:
     genInitCode(m)
     finishTypeDescriptions(m)
-    if sfMainModule in m.module.flags: 
+    if sfMainModule in m.module.flags:
       # generate main file:
       app(m.s[cfsProcHeaders], mainModProcs)
       generateThreadVarsSize(m)
-    
+
     var code = genModule(m, cfile)
     when hasTinyCBackend:
       if gCmd == cmdRun:
@@ -1269,13 +1263,13 @@ proc writeModule(m: BModule, pending: bool) =
     # ``system.c`` but then compilation fails due to an error. This means
     # that ``system.o`` is missing, so we need to call the C compiler for it:
     addFileToCompile(cfile)
-  
+
   addFileToLink(cfilenoext)
 
 proc updateCachedModule(m: BModule) =
   let cfile = getCFile(m)
   let cfilenoext = changeFileExt(cfile, "")
-  
+
   if mergeRequired(m) and sfMainModule notin m.module.flags:
     mergeFiles(cfile, m)
     genInitCode(m)
@@ -1286,17 +1280,17 @@ proc updateCachedModule(m: BModule) =
 
   addFileToLink(cfilenoext)
 
-proc myClose(b: PPassContext, n: PNode): PNode = 
+proc myClose(b: PPassContext, n: PNode): PNode =
   result = n
-  if b == nil or passes.skipCodegen(n): return 
+  if b == nil or passes.skipCodegen(n): return
   var m = BModule(b)
-  if n != nil: 
+  if n != nil:
     m.initProc.options = initProcOptions(m)
     genStmts(m.initProc, n)
-  # cached modules need to registered too: 
+  # cached modules need to registered too:
   registerModuleToMain(m.module)
 
-  if sfMainModule in m.module.flags: 
+  if sfMainModule in m.module.flags:
     m.objHasKidsValid = true
     var disp = generateMethodDispatchers()
     for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym)
diff --git a/compiler/guards.nim b/compiler/guards.nim
index b0420cb75..cedd2be2b 100644
--- a/compiler/guards.nim
+++ b/compiler/guards.nim
@@ -373,13 +373,28 @@ proc addFactNeg*(m: var TModel, n: PNode) =
   let n = n.neg
   if n != nil: addFact(m, n)
 
+proc canonOpr(opr: PSym): PSym =
+  case opr.magic
+  of someEq: result = opEq
+  of someLe: result = opLe
+  of someLt: result = opLt
+  of someLen: result = opLen
+  of someAdd: result = opAdd
+  of someSub: result = opSub
+  of someMul: result = opMul
+  of someDiv: result = opDiv
+  else: result = opr
+
 proc sameTree*(a, b: PNode): bool =
   result = false
   if a == b:
     result = true
-  elif (a != nil) and (b != nil) and (a.kind == b.kind):
+  elif a != nil and b != nil and a.kind == b.kind:
     case a.kind
-    of nkSym: result = a.sym == b.sym
+    of nkSym:
+      result = a.sym == b.sym
+      if not result and a.sym.magic != mNone:
+        result = a.sym.magic == b.sym.magic or canonOpr(a.sym) == canonOpr(b.sym)
     of nkIdent: result = a.ident.id == b.ident.id
     of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
     of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
@@ -643,7 +658,7 @@ proc factImplies(fact, prop: PNode): TImplication =
       if a == b: return ~a
       return impUnknown
     else:
-      internalError(fact.info, "invalid fact")
+      return impUnknown
   of mAnd:
     result = factImplies(fact.sons[1], prop)
     if result != impUnknown: return result
@@ -657,7 +672,7 @@ proc factImplies(fact, prop: PNode): TImplication =
   of someLe: result = impliesLe(fact, prop.sons[1], prop.sons[2])
   of someLt: result = impliesLt(fact, prop.sons[1], prop.sons[2])
   of mInSet: result = impliesIn(fact, prop.sons[2], prop.sons[1])
-  else: internalError(prop.info, "invalid proposition")
+  else: result = impUnknown
 
 proc doesImply*(facts: TModel, prop: PNode): TImplication =
   assert prop.kind in nkCallKinds
diff --git a/compiler/lookups.nim b/compiler/lookups.nim
index 6d3379bb9..88e32404a 100644
--- a/compiler/lookups.nim
+++ b/compiler/lookups.nim
@@ -9,8 +9,8 @@
 
 # This module implements lookup helpers.
 
-import 
-  intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread, 
+import
+  intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
   renderer, wordrecg, idgen, nimfix.prettybase
 
 proc ensureNoMissingOrUnusedSymbols(scope: PScope)
@@ -87,14 +87,14 @@ proc searchInScopes*(c: PContext, s: PIdent): PSym =
     if result != nil: return
   result = nil
 
-proc debugScopes*(c: PContext) {.deprecated.} =
+proc debugScopes*(c: PContext; limit=0) {.deprecated.} =
   var i = 0
   for scope in walkScopes(c.currentScope):
     echo "scope ", i
     for h in 0 .. high(scope.symbols.data):
       if scope.symbols.data[h] != nil:
         echo scope.symbols.data[h].name.s
-    if i == 2: break
+    if i == limit: break
     inc i
 
 proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym =
@@ -108,7 +108,7 @@ proc errorSym*(c: PContext, n: PNode): PSym =
   var m = n
   # ensure that 'considerQuotedIdent' can't fail:
   if m.kind == nkDotExpr: m = m.sons[1]
-  let ident = if m.kind in {nkIdent, nkSym, nkAccQuoted}: 
+  let ident = if m.kind in {nkIdent, nkSym, nkAccQuoted}:
       considerQuotedIdent(m)
     else:
       getIdent("err:" & renderTree(m))
@@ -119,11 +119,11 @@ proc errorSym*(c: PContext, n: PNode): PSym =
   if gCmd != cmdInteractive and c.inCompilesContext == 0:
     c.importTable.addSym(result)
 
-type 
-  TOverloadIterMode* = enum 
+type
+  TOverloadIterMode* = enum
     oimDone, oimNoQualifier, oimSelfModule, oimOtherModule, oimSymChoice,
     oimSymChoiceLocalLookup
-  TOverloadIter*{.final.} = object 
+  TOverloadIter*{.final.} = object
     it*: TIdentIter
     m*: PSym
     mode*: TOverloadIterMode
@@ -131,7 +131,7 @@ type
     scope*: PScope
     inSymChoice: IntSet
 
-proc getSymRepr*(s: PSym): string = 
+proc getSymRepr*(s: PSym): string =
   case s.kind
   of skProc, skMethod, skConverter, skIterators: result = getProcHeader(s)
   else: result = s.name.s
@@ -148,7 +148,7 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
       if missingImpls == 0:
         localError(s.info, errImplOfXexpected, getSymRepr(s))
       inc missingImpls
-    elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options: 
+    elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options:
       # BUGFIX: check options in s!
       if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}:
         # XXX: implicit type params are currently skTypes
@@ -156,11 +156,11 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
         if s.typ != nil and tfImplicitTypeParam notin s.typ.flags:
           message(s.info, hintXDeclaredButNotUsed, getSymRepr(s))
     s = nextIter(it, scope.symbols)
-  
+
 proc wrongRedefinition*(info: TLineInfo, s: string) =
   if gCmd != cmdInteractive:
     localError(info, errAttemptToRedefine, s)
-  
+
 proc addDecl*(c: PContext, sym: PSym) =
   if not c.currentScope.addUniqueSym(sym):
     wrongRedefinition(sym.info, sym.name.s)
@@ -172,7 +172,7 @@ proc addDeclAt*(scope: PScope, sym: PSym) =
   if not scope.addUniqueSym(sym):
     wrongRedefinition(sym.info, sym.name.s)
 
-proc addInterfaceDeclAux(c: PContext, sym: PSym) = 
+proc addInterfaceDeclAux(c: PContext, sym: PSym) =
   if sfExported in sym.flags:
     # add to interface:
     if c.module != nil: strTableAdd(c.module.tab, sym)
@@ -183,16 +183,16 @@ proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) =
   addInterfaceDeclAux(c, sym)
 
 proc addOverloadableSymAt*(scope: PScope, fn: PSym) =
-  if fn.kind notin OverloadableSyms: 
+  if fn.kind notin OverloadableSyms:
     internalError(fn.info, "addOverloadableSymAt")
     return
   let check = strTableGet(scope.symbols, fn.name)
-  if check != nil and check.kind notin OverloadableSyms: 
+  if check != nil and check.kind notin OverloadableSyms:
     wrongRedefinition(fn.info, fn.name.s)
   else:
     scope.addSym(fn)
-  
-proc addInterfaceDecl*(c: PContext, sym: PSym) = 
+
+proc addInterfaceDecl*(c: PContext, sym: PSym) =
   # it adds the symbol to the interface if appropriate
   addDecl(c, sym)
   addInterfaceDeclAux(c, sym)
@@ -221,7 +221,7 @@ when defined(nimfix):
 else:
   template fixSpelling(n: PNode; ident: PIdent; op: expr) = discard
 
-proc lookUp*(c: PContext, n: PNode): PSym = 
+proc lookUp*(c: PContext, n: PNode): PSym =
   # Looks up a symbol. Generates an error in case of nil.
   case n.kind
   of nkIdent:
@@ -242,12 +242,12 @@ proc lookUp*(c: PContext, n: PNode): PSym =
   else:
     internalError(n.info, "lookUp")
     return
-  if contains(c.ambiguousSymbols, result.id): 
+  if contains(c.ambiguousSymbols, result.id):
     localError(n.info, errUseQualifier, result.name.s)
   if result.kind == skStub: loadStub(result)
-  
-type 
-  TLookupFlag* = enum 
+
+type
+  TLookupFlag* = enum
     checkAmbiguity, checkUndeclared
 
 proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
@@ -294,7 +294,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
   else:
     result = nil
   if result != nil and result.kind == skStub: loadStub(result)
-  
+
 proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
   case n.kind
   of nkIdent, nkAccQuoted:
@@ -311,17 +311,17 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
   of nkSym:
     result = n.sym
     o.mode = oimDone
-  of nkDotExpr: 
+  of nkDotExpr:
     o.mode = oimOtherModule
     o.m = qualifiedLookUp(c, n.sons[0])
     if o.m != nil and o.m.kind == skModule:
       var ident: PIdent = nil
-      if n.sons[1].kind == nkIdent: 
+      if n.sons[1].kind == nkIdent:
         ident = n.sons[1].ident
       elif n.sons[1].kind == nkAccQuoted:
         ident = considerQuotedIdent(n.sons[1])
-      if ident != nil: 
-        if o.m == c.module: 
+      if ident != nil:
+        if o.m == c.module:
           # a module may access its private members:
           result = initIdentIter(o.it, c.topLevelScope.symbols,
                                  ident).skipAlias(n)
@@ -329,7 +329,7 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
         else:
           result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n)
       else:
-        localError(n.sons[1].info, errIdentifierExpected, 
+        localError(n.sons[1].info, errIdentifierExpected,
                    renderTree(n.sons[1]))
         result = errorSym(c, n.sons[1])
   of nkClosedSymChoice, nkOpenSymChoice:
@@ -347,12 +347,12 @@ proc lastOverloadScope*(o: TOverloadIter): int =
   of oimSelfModule:  result = 1
   of oimOtherModule: result = 0
   else: result = -1
-  
-proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = 
+
+proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
   case o.mode
-  of oimDone: 
+  of oimDone:
     result = nil
-  of oimNoQualifier: 
+  of oimNoQualifier:
     if o.scope != nil:
       result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n)
       while result == nil:
@@ -360,13 +360,13 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
         if o.scope == nil: break
         result = initIdentIter(o.it, o.scope.symbols, o.it.name).skipAlias(n)
         # BUGFIX: o.it.name <-> n.ident
-    else: 
+    else:
       result = nil
-  of oimSelfModule: 
+  of oimSelfModule:
     result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n)
-  of oimOtherModule: 
+  of oimOtherModule:
     result = nextIdentIter(o.it, o.m.tab).skipAlias(n)
-  of oimSymChoice: 
+  of oimSymChoice:
     if o.symChoiceIndex < sonsLen(n):
       result = n.sons[o.symChoiceIndex].sym
       incl(o.inSymChoice, result.id)
@@ -389,7 +389,7 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
       if o.scope == nil: break
       result = firstIdentExcluding(o.it, o.scope.symbols,
                                    n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
-  
+
   if result != nil and result.kind == skStub: loadStub(result)
 
 proc pickSym*(c: PContext, n: PNode; kind: TSymKind;
diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim
index 58b5c5681..8c0875ab1 100644
--- a/compiler/parampatterns.nim
+++ b/compiler/parampatterns.nim
@@ -174,7 +174,8 @@ type
     arLValue,                 # is an l-value
     arLocalLValue,            # is an l-value, but local var; must not escape
                               # its stack frame!
-    arDiscriminant            # is a discriminant
+    arDiscriminant,           # is a discriminant
+    arStrange                 # it is a strange beast like 'typedesc[var T]'
 
 proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
   ## 'owner' can be nil!
@@ -188,6 +189,9 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
         result = arLocalLValue
       else:
         result = arLValue
+    elif n.sym.kind == skType:
+      let t = n.sym.typ.skipTypes({tyTypeDesc})
+      if t.kind == tyVar: result = arStrange
   of nkDotExpr:
     if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind in
         {tyVar, tyPtr, tyRef}:
@@ -222,7 +226,7 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
     discard
 
 proc isLValue*(n: PNode): bool =
-  isAssignable(nil, n) in {arLValue, arLocalLValue}
+  isAssignable(nil, n) in {arLValue, arLocalLValue, arStrange}
 
 proc matchNodeKinds*(p, n: PNode): bool =
   # matches the parameter constraint 'p' against the concrete AST 'n'.
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 78ee490e2..056e4f4c0 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -9,23 +9,23 @@
 
 # This module implements semantic checking for pragmas
 
-import 
-  os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer, 
+import
+  os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer,
   wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees,
   rodread, types, lookups
 
-const 
+const
   FirstCallConv* = wNimcall
   LastCallConv* = wNoconv
 
 const
-  procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
-    wMagic, wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, 
-    wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, 
+  procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
+    wMagic, wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader,
+    wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
     wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
     wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
     wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
-    wOverride}
+    wOverride, wConstructor}
   converterPragmas* = procPragmas
   methodPragmas* = procPragmas
   templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty,
@@ -33,7 +33,7 @@ const
   macroPragmas* = {FirstCallConv..LastCallConv, wImmediate, wImportc, wExportc,
     wNodecl, wMagic, wNosideeffect, wCompilerproc, wDeprecated, wExtern,
     wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator}
-  iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect, 
+  iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect,
     wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
     wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
     wTags, wLocks, wGcSafe}
@@ -46,18 +46,18 @@ const
     wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
     wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto,
     wInjectStmt, wDeprecated, wExperimental}
-  lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
-    wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, 
+  lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
+    wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader,
     wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame,
     wRaises, wLocks, wTags, wGcSafe}
-  typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, 
+  typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
     wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
     wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
     wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
     wBorrow, wGcSafe}
-  fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, 
+  fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
     wImportCpp, wImportObjC, wError, wGuard}
-  varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, 
+  varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
     wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern,
     wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal,
     wGensym, wInject, wCodegenDecl, wGuard}
@@ -74,18 +74,18 @@ proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
 proc invalidPragma(n: PNode) =
   localError(n.info, errInvalidPragmaX, renderTree(n, {renderNoComments}))
 
-proc pragmaAsm*(c: PContext, n: PNode): char = 
+proc pragmaAsm*(c: PContext, n: PNode): char =
   result = '\0'
-  if n != nil: 
-    for i in countup(0, sonsLen(n) - 1): 
+  if n != nil:
+    for i in countup(0, sonsLen(n) - 1):
       let it = n.sons[i]
       if it.kind == nkExprColonExpr and it.sons[0].kind == nkIdent:
         case whichKeyword(it.sons[0].ident)
-        of wSubsChar: 
+        of wSubsChar:
           if it.sons[1].kind == nkCharLit: result = chr(int(it.sons[1].intVal))
           else: invalidPragma(it)
         else: invalidPragma(it)
-      else: 
+      else:
         invalidPragma(it)
 
 proc setExternName(s: PSym, extname: string) =
@@ -94,7 +94,7 @@ proc setExternName(s: PSym, extname: string) =
     # note that '{.importc.}' is transformed into '{.importc: "$1".}'
     s.loc.flags.incl(lfFullExternalName)
 
-proc makeExternImport(s: PSym, extname: string) = 
+proc makeExternImport(s: PSym, extname: string) =
   setExternName(s, extname)
   incl(s.flags, sfImportc)
   excl(s.flags, sfForward)
@@ -145,7 +145,7 @@ proc newEmptyStrNode(n: PNode): PNode {.noinline.} =
   result.strVal = ""
 
 proc getStrLitNode(c: PContext, n: PNode): PNode =
-  if n.kind != nkExprColonExpr: 
+  if n.kind != nkExprColonExpr:
     localError(n.info, errStringLiteralExpected)
     # error correction:
     result = newEmptyStrNode(n)
@@ -153,62 +153,62 @@ proc getStrLitNode(c: PContext, n: PNode): PNode =
     n.sons[1] = c.semConstExpr(c, n.sons[1])
     case n.sons[1].kind
     of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1]
-    else: 
+    else:
       localError(n.info, errStringLiteralExpected)
       # error correction:
       result = newEmptyStrNode(n)
 
-proc expectStrLit(c: PContext, n: PNode): string = 
+proc expectStrLit(c: PContext, n: PNode): string =
   result = getStrLitNode(c, n).strVal
 
-proc expectIntLit(c: PContext, n: PNode): int = 
-  if n.kind != nkExprColonExpr: 
+proc expectIntLit(c: PContext, n: PNode): int =
+  if n.kind != nkExprColonExpr:
     localError(n.info, errIntLiteralExpected)
-  else: 
+  else:
     n.sons[1] = c.semConstExpr(c, n.sons[1])
     case n.sons[1].kind
     of nkIntLit..nkInt64Lit: result = int(n.sons[1].intVal)
     else: localError(n.info, errIntLiteralExpected)
 
-proc getOptionalStr(c: PContext, n: PNode, defaultStr: string): string = 
+proc getOptionalStr(c: PContext, n: PNode, defaultStr: string): string =
   if n.kind == nkExprColonExpr: result = expectStrLit(c, n)
   else: result = defaultStr
 
 proc processCodegenDecl(c: PContext, n: PNode, sym: PSym) =
   sym.constraint = getStrLitNode(c, n)
 
-proc processMagic(c: PContext, n: PNode, s: PSym) = 
+proc processMagic(c: PContext, n: PNode, s: PSym) =
   #if sfSystemModule notin c.module.flags:
   #  liMessage(n.info, errMagicOnlyInSystem)
-  if n.kind != nkExprColonExpr: 
+  if n.kind != nkExprColonExpr:
     localError(n.info, errStringLiteralExpected)
     return
   var v: string
   if n.sons[1].kind == nkIdent: v = n.sons[1].ident.s
   else: v = expectStrLit(c, n)
-  for m in countup(low(TMagic), high(TMagic)): 
-    if substr($m, 1) == v: 
+  for m in countup(low(TMagic), high(TMagic)):
+    if substr($m, 1) == v:
       s.magic = m
       break
   if s.magic == mNone: message(n.info, warnUnknownMagic, v)
 
-proc wordToCallConv(sw: TSpecialWord): TCallingConvention = 
+proc wordToCallConv(sw: TSpecialWord): TCallingConvention =
   # this assumes that the order of special words and calling conventions is
   # the same
   result = TCallingConvention(ord(ccDefault) + ord(sw) - ord(wNimcall))
 
-proc isTurnedOn(c: PContext, n: PNode): bool = 
+proc isTurnedOn(c: PContext, n: PNode): bool =
   if n.kind == nkExprColonExpr:
     let x = c.semConstBoolExpr(c, n.sons[1])
     n.sons[1] = x
     if x.kind == nkIntLit: return x.intVal != 0
   localError(n.info, errOnOrOffExpected)
 
-proc onOff(c: PContext, n: PNode, op: TOptions) = 
+proc onOff(c: PContext, n: PNode, op: TOptions) =
   if isTurnedOn(c, n): gOptions = gOptions + op
   else: gOptions = gOptions - op
-  
-proc pragmaDeadCodeElim(c: PContext, n: PNode) = 
+
+proc pragmaDeadCodeElim(c: PContext, n: PNode) =
   if isTurnedOn(c, n): incl(c.module.flags, sfDeadCodeElim)
   else: excl(c.module.flags, sfDeadCodeElim)
 
@@ -216,20 +216,20 @@ proc pragmaNoForward(c: PContext, n: PNode) =
   if isTurnedOn(c, n): incl(c.module.flags, sfNoForward)
   else: excl(c.module.flags, sfNoForward)
 
-proc processCallConv(c: PContext, n: PNode) = 
-  if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): 
+proc processCallConv(c: PContext, n: PNode) =
+  if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
     var sw = whichKeyword(n.sons[1].ident)
     case sw
-    of FirstCallConv..LastCallConv: 
+    of FirstCallConv..LastCallConv:
       POptionEntry(c.optionStack.tail).defaultCC = wordToCallConv(sw)
     else: localError(n.info, errCallConvExpected)
-  else: 
+  else:
     localError(n.info, errCallConvExpected)
-  
-proc getLib(c: PContext, kind: TLibKind, path: PNode): PLib = 
+
+proc getLib(c: PContext, kind: TLibKind, path: PNode): PLib =
   var it = PLib(c.libs.head)
-  while it != nil: 
-    if it.kind == kind: 
+  while it != nil:
+    if it.kind == kind:
       if trees.exprStructuralEquivalent(it.path, path): return it
     it = PLib(it.next)
   result = newLib(kind)
@@ -252,10 +252,10 @@ proc expectDynlibNode(c: PContext, n: PNode): PNode =
     if result.typ == nil or result.typ.kind notin {tyPointer, tyString, tyProc}:
       localError(n.info, errStringLiteralExpected)
       result = newEmptyStrNode(n)
-    
-proc processDynLib(c: PContext, n: PNode, sym: PSym) = 
+
+proc processDynLib(c: PContext, n: PNode, sym: PSym) =
   if (sym == nil) or (sym.kind == skModule):
-    POptionEntry(c.optionStack.tail).dynlib = getLib(c, libDynamic, 
+    POptionEntry(c.optionStack.tail).dynlib = getLib(c, libDynamic,
         expectDynlibNode(c, n))
   else:
     if n.kind == nkExprColonExpr:
@@ -268,7 +268,7 @@ proc processDynLib(c: PContext, n: PNode, sym: PSym) =
     # since we'll be loading the dynlib symbols dynamically, we must use
     # a calling convention that doesn't introduce custom name mangling
     # cdecl is the default - the user can override this explicitly
-    if sym.kind in routineKinds and sym.typ != nil and 
+    if sym.kind in routineKinds and sym.typ != nil and
         sym.typ.callConv == ccDefault:
       sym.typ.callConv = ccCDecl
 
@@ -295,10 +295,10 @@ proc processNote(c: PContext, n: PNode) =
     n.sons[1] = x
     if x.kind == nkIntLit and x.intVal != 0: incl(gNotes, nk)
     else: excl(gNotes, nk)
-  else: 
+  else:
     invalidPragma(n)
-  
-proc processOption(c: PContext, n: PNode): bool = 
+
+proc processOption(c: PContext, n: PNode): bool =
   if n.kind != nkExprColonExpr: result = true
   elif n.sons[0].kind == nkBracketExpr: processNote(c, n)
   elif n.sons[0].kind != nkIdent: result = true
@@ -318,34 +318,34 @@ proc processOption(c: PContext, n: PNode): bool =
     of wAssertions: onOff(c, n, {optAssert})
     of wWarnings: onOff(c, n, {optWarns})
     of wHints: onOff(c, n, {optHints})
-    of wCallconv: processCallConv(c, n)   
+    of wCallconv: processCallConv(c, n)
     of wLinedir: onOff(c, n, {optLineDir})
     of wStacktrace: onOff(c, n, {optStackTrace})
     of wLinetrace: onOff(c, n, {optLineTrace})
     of wDebugger: onOff(c, n, {optEndb})
     of wProfiler: onOff(c, n, {optProfiler})
     of wByRef: onOff(c, n, {optByRef})
-    of wDynlib: processDynLib(c, n, nil) 
-    of wOptimization: 
-      if n.sons[1].kind != nkIdent: 
+    of wDynlib: processDynLib(c, n, nil)
+    of wOptimization:
+      if n.sons[1].kind != nkIdent:
         invalidPragma(n)
-      else: 
+      else:
         case n.sons[1].ident.s.normalize
-        of "speed": 
+        of "speed":
           incl(gOptions, optOptimizeSpeed)
           excl(gOptions, optOptimizeSize)
         of "size":
           excl(gOptions, optOptimizeSpeed)
           incl(gOptions, optOptimizeSize)
-        of "none": 
+        of "none":
           excl(gOptions, optOptimizeSpeed)
           excl(gOptions, optOptimizeSize)
         else: localError(n.info, errNoneSpeedOrSizeExpected)
     of wImplicitStatic: onOff(c, n, {optImplicitStatic})
     of wPatterns: onOff(c, n, {optPatterns})
     else: result = true
-  
-proc processPush(c: PContext, n: PNode, start: int) = 
+
+proc processPush(c: PContext, n: PNode, start: int) =
   if n.sons[start-1].kind == nkExprColonExpr:
     localError(n.info, errGenerated, "':' after 'push' not supported")
   var x = newOptionEntry()
@@ -355,41 +355,41 @@ proc processPush(c: PContext, n: PNode, start: int) =
   x.dynlib = y.dynlib
   x.notes = gNotes
   append(c.optionStack, x)
-  for i in countup(start, sonsLen(n) - 1): 
+  for i in countup(start, sonsLen(n) - 1):
     if processOption(c, n.sons[i]):
       # simply store it somewhere:
       if x.otherPragmas.isNil:
         x.otherPragmas = newNodeI(nkPragma, n.info)
       x.otherPragmas.add n.sons[i]
     #localError(n.info, errOptionExpected)
-  
-proc processPop(c: PContext, n: PNode) = 
-  if c.optionStack.counter <= 1: 
+
+proc processPop(c: PContext, n: PNode) =
+  if c.optionStack.counter <= 1:
     localError(n.info, errAtPopWithoutPush)
-  else: 
-    gOptions = POptionEntry(c.optionStack.tail).options 
+  else:
+    gOptions = POptionEntry(c.optionStack.tail).options
     gNotes = POptionEntry(c.optionStack.tail).notes
     remove(c.optionStack, c.optionStack.tail)
 
-proc processDefine(c: PContext, n: PNode) = 
-  if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): 
+proc processDefine(c: PContext, n: PNode) =
+  if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
     defineSymbol(n.sons[1].ident.s)
     message(n.info, warnDeprecated, "define")
-  else: 
+  else:
     invalidPragma(n)
-  
-proc processUndef(c: PContext, n: PNode) = 
-  if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): 
+
+proc processUndef(c: PContext, n: PNode) =
+  if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
     undefSymbol(n.sons[1].ident.s)
     message(n.info, warnDeprecated, "undef")
-  else: 
+  else:
     invalidPragma(n)
-  
-type 
-  TLinkFeature = enum 
+
+type
+  TLinkFeature = enum
     linkNormal, linkSys
 
-proc processCompile(c: PContext, n: PNode) = 
+proc processCompile(c: PContext, n: PNode) =
   var s = expectStrLit(c, n)
   var found = findFile(s)
   if found == "": found = s
@@ -397,7 +397,7 @@ proc processCompile(c: PContext, n: PNode) =
   extccomp.addExternalFileToCompile(found)
   extccomp.addFileToLink(completeCFilePath(trunc, false))
 
-proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) = 
+proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) =
   var f = expectStrLit(c, n)
   if splitFile(f).ext == "": f = addFileExt(f, CC[cCompiler].objExt)
   var found = findFile(f)
@@ -407,8 +407,8 @@ proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) =
   of linkSys:
     extccomp.addFileToLink(libpath / completeCFilePath(found, false))
   else: internalError(n.info, "processCommonLink")
-  
-proc pragmaBreakpoint(c: PContext, n: PNode) = 
+
+proc pragmaBreakpoint(c: PContext, n: PNode) =
   discard getOptionalStr(c, n, "")
 
 proc pragmaWatchpoint(c: PContext, n: PNode) =
@@ -427,59 +427,59 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
       return
     # now parse the string literal and substitute symbols:
     var a = 0
-    while true: 
+    while true:
       var b = strutils.find(str, marker, a)
       var sub = if b < 0: substr(str, a) else: substr(str, a, b - 1)
       if sub != "": addSon(result, newStrNode(nkStrLit, sub))
-      if b < 0: break 
+      if b < 0: break
       var c = strutils.find(str, marker, b + 1)
       if c < 0: sub = substr(str, b + 1)
       else: sub = substr(str, b + 1, c - 1)
-      if sub != "": 
+      if sub != "":
         var e = searchInScopes(con, getIdent(sub))
-        if e != nil: 
+        if e != nil:
           if e.kind == skStub: loadStub(e)
           addSon(result, newSymNode(e))
-        else: 
+        else:
           addSon(result, newStrNode(nkStrLit, sub))
       else:
         # an empty '``' produces a single '`'
         addSon(result, newStrNode(nkStrLit, $marker))
-      if c < 0: break 
+      if c < 0: break
       a = c + 1
   else:
     illFormedAstLocal(n)
     result = newNode(nkAsmStmt, n.info)
-  
-proc pragmaEmit(c: PContext, n: PNode) = 
+
+proc pragmaEmit(c: PContext, n: PNode) =
   discard getStrLitNode(c, n)
   n.sons[1] = semAsmOrEmit(c, n, '`')
 
-proc noVal(n: PNode) = 
+proc noVal(n: PNode) =
   if n.kind == nkExprColonExpr: invalidPragma(n)
 
-proc pragmaUnroll(c: PContext, n: PNode) = 
-  if c.p.nestedLoopCounter <= 0: 
+proc pragmaUnroll(c: PContext, n: PNode) =
+  if c.p.nestedLoopCounter <= 0:
     invalidPragma(n)
   elif n.kind == nkExprColonExpr:
     var unrollFactor = expectIntLit(c, n)
-    if unrollFactor <% 32: 
+    if unrollFactor <% 32:
       n.sons[1] = newIntNode(nkIntLit, unrollFactor)
-    else: 
+    else:
       invalidPragma(n)
 
 proc pragmaLine(c: PContext, n: PNode) =
   if n.kind == nkExprColonExpr:
     n.sons[1] = c.semConstExpr(c, n.sons[1])
     let a = n.sons[1]
-    if a.kind == nkPar: 
+    if a.kind == nkPar:
       var x = a.sons[0]
       var y = a.sons[1]
       if x.kind == nkExprColonExpr: x = x.sons[1]
       if y.kind == nkExprColonExpr: y = y.sons[1]
-      if x.kind != nkStrLit: 
+      if x.kind != nkStrLit:
         localError(n.info, errStringLiteralExpected)
-      elif y.kind != nkIntLit: 
+      elif y.kind != nkIntLit:
         localError(n.info, errIntLiteralExpected)
       else:
         n.info.fileIndex = msgs.fileInfoIdx(x.strVal)
@@ -490,12 +490,12 @@ proc pragmaLine(c: PContext, n: PNode) =
     # sensible default:
     n.info = getInfoContext(-1)
 
-proc processPragma(c: PContext, n: PNode, i: int) = 
+proc processPragma(c: PContext, n: PNode, i: int) =
   var it = n.sons[i]
   if it.kind != nkExprColonExpr: invalidPragma(n)
   elif it.sons[0].kind != nkIdent: invalidPragma(n)
   elif it.sons[1].kind != nkIdent: invalidPragma(n)
-  
+
   var userPragma = newSym(skTemplate, it.sons[1].ident, nil, it.info)
   var body = newNodeI(nkPragma, n.info)
   for j in i+1 .. sonsLen(n)-1: addSon(body, n.sons[j])
@@ -508,7 +508,7 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) =
     if t.kind != tyObject:
       localError(x.info, errGenerated, "invalid type for raises/tags list")
     x.typ = t
-    
+
   if n.kind == nkExprColonExpr:
     let it = n.sons[1]
     if it.kind notin {nkCurly, nkBracket}:
@@ -569,7 +569,7 @@ proc deprecatedStmt(c: PContext; pragma: PNode) =
       localError(n.info, "key:value pair expected")
 
 proc pragmaGuard(c: PContext; it: PNode; kind: TSymKind): PSym =
-  if it.kind != nkExprColonExpr: 
+  if it.kind != nkExprColonExpr:
     invalidPragma(it); return
   let n = it[1]
   if n.kind == nkSym:
@@ -592,9 +592,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
   var key = if it.kind == nkExprColonExpr: it.sons[0] else: it
   if key.kind == nkIdent:
     var userPragma = strTableGet(c.userPragmas, key.ident)
-    if userPragma != nil: 
+    if userPragma != nil:
       inc c.instCounter
-      if c.instCounter > 100: 
+      if c.instCounter > 100:
         globalError(it.info, errRecursiveDependencyX, userPragma.name.s)
       pragma(c, sym, userPragma.ast, validPragmas)
       # ensure the pragma is also remember for generic instantiations in other
@@ -603,9 +603,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
       dec c.instCounter
     else:
       var k = whichKeyword(key.ident)
-      if k in validPragmas: 
+      if k in validPragmas:
         case k
-        of wExportc: 
+        of wExportc:
           makeExternExport(sym, getOptionalStr(c, it, "$1"), it.info)
           incl(sym.flags, sfUsed) # avoid wrong hints
         of wImportc: makeExternImport(sym, getOptionalStr(c, it, "$1"))
@@ -627,16 +627,16 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           var align = expectIntLit(c, it)
           if (not isPowerOfTwo(align) and align != 0) or align >% high(int16):
             localError(it.info, errPowerOfTwoExpected)
-          else: 
+          else:
             sym.typ.align = align.int16
         of wSize:
           if sym.typ == nil: invalidPragma(it)
           var size = expectIntLit(c, it)
-          if not isPowerOfTwo(size) or size <= 0 or size > 8: 
+          if not isPowerOfTwo(size) or size <= 0 or size > 8:
             localError(it.info, errPowerOfTwoExpected)
           else:
             sym.typ.size = size
-        of wNodecl: 
+        of wNodecl:
           noVal(it)
           incl(sym.loc.flags, lfNoDecl)
         of wPure, wAsmNoStackFrame:
@@ -644,19 +644,19 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           if sym != nil:
             if k == wPure and sym.kind in routineKinds: invalidPragma(it)
             else: incl(sym.flags, sfPure)
-        of wVolatile: 
+        of wVolatile:
           noVal(it)
           incl(sym.flags, sfVolatile)
-        of wRegister: 
+        of wRegister:
           noVal(it)
           incl(sym.flags, sfRegister)
-        of wThreadVar: 
+        of wThreadVar:
           noVal(it)
           incl(sym.flags, sfThread)
         of wDeadCodeElim: pragmaDeadCodeElim(c, it)
         of wNoForward: pragmaNoForward(c, it)
         of wMagic: processMagic(c, it, sym)
-        of wCompileTime: 
+        of wCompileTime:
           noVal(it)
           incl(sym.flags, sfCompileTime)
           incl(sym.loc.flags, lfNoDecl)
@@ -664,15 +664,18 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           noVal(it)
           incl(sym.flags, sfGlobal)
           incl(sym.flags, sfPure)
-        of wMerge: 
+        of wMerge:
+          # only supported for backwards compat, doesn't do anything anymore
+          noVal(it)
+        of wConstructor:
           noVal(it)
-          incl(sym.flags, sfMerge)
-        of wHeader: 
+          incl(sym.flags, sfConstructor)
+        of wHeader:
           var lib = getLib(c, libHeader, getStrLitNode(c, it))
           addToLib(lib, sym)
           incl(sym.flags, sfImportc)
           incl(sym.loc.flags, lfHeader)
-          incl(sym.loc.flags, lfNoDecl) 
+          incl(sym.loc.flags, lfNoDecl)
           # implies nodecl, because otherwise header would not make sense
           if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s)
         of wDestructor:
@@ -685,13 +688,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           noVal(it)
           incl(sym.flags, sfNoSideEffect)
           if sym.typ != nil: incl(sym.typ.flags, tfNoSideEffect)
-        of wSideeffect: 
+        of wSideeffect:
           noVal(it)
           incl(sym.flags, sfSideEffect)
-        of wNoreturn: 
+        of wNoreturn:
           noVal(it)
           incl(sym.flags, sfNoReturn)
-        of wDynlib: 
+        of wDynlib:
           processDynLib(c, it, sym)
         of wCompilerproc:
           noVal(it)           # compilerproc may not get a string!
@@ -703,7 +706,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           if it.kind == nkExprColonExpr: deprecatedStmt(c, it)
           elif sym != nil: incl(sym.flags, sfDeprecated)
           else: incl(c.module.flags, sfDeprecated)
-        of wVarargs: 
+        of wVarargs:
           noVal(it)
           if sym.typ == nil: invalidPragma(it)
           else: incl(sym.typ.flags, tfVarargs)
@@ -713,7 +716,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           else:
             noVal(it)
             incl(sym.flags, sfBorrow)
-        of wFinal: 
+        of wFinal:
           noVal(it)
           if sym.typ == nil: invalidPragma(it)
           else: incl(sym.typ.flags, tfFinal)
@@ -745,10 +748,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           else: incl(sym.typ.flags, tfPacked)
         of wHint: message(it.info, hintUser, expectStrLit(c, it))
         of wWarning: message(it.info, warnUser, expectStrLit(c, it))
-        of wError: 
+        of wError:
           if sym != nil and sym.isRoutine:
             # This is subtle but correct: the error *statement* is only
-            # allowed for top level statements. Seems to be easier than 
+            # allowed for top level statements. Seems to be easier than
             # distinguishing properly between
             # ``proc p() {.error}`` and ``proc p() = {.error: "msg".}``
             noVal(it)
@@ -765,11 +768,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
         of wPassc: extccomp.addCompileOption(expectStrLit(c, it))
         of wBreakpoint: pragmaBreakpoint(c, it)
         of wWatchPoint: pragmaWatchpoint(c, it)
-        of wPush: 
+        of wPush:
           processPush(c, n, i + 1)
-          result = true 
+          result = true
         of wPop: processPop(c, it)
-        of wPragma: 
+        of wPragma:
           processPragma(c, n, i)
           result = true
         of wDiscardable:
@@ -779,16 +782,16 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           noVal(it)
           if sym != nil: incl(sym.flags, sfNoInit)
         of wCodegenDecl: processCodegenDecl(c, it, sym)
-        of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, 
-           wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, 
+        of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
+           wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
            wLinedir, wStacktrace, wLinetrace, wOptimization,
-           wCallconv, 
+           wCallconv,
            wDebugger, wProfiler, wFloatchecks, wNanChecks, wInfChecks,
            wPatterns:
           if processOption(c, it):
             # calling conventions (boring...):
             localError(it.info, errOptionExpected)
-        of FirstCallConv..LastCallConv: 
+        of FirstCallConv..LastCallConv:
           assert(sym != nil)
           if sym.typ == nil: invalidPragma(it)
           else: sym.typ.callConv = wordToCallConv(k)
@@ -843,14 +846,14 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
         of wInjectStmt:
           if it.kind != nkExprColonExpr:
             localError(it.info, errExprExpected)
-          else: 
+          else:
             it.sons[1] = c.semExpr(c, it.sons[1])
         of wExperimental:
           noVal(it)
           if isTopLevel(c):
             c.module.flags.incl sfExperimental
           else:
-            localError(it.info, "'experimental' pragma only valid as toplevel statement") 
+            localError(it.info, "'experimental' pragma only valid as toplevel statement")
         else: invalidPragma(it)
       else: invalidPragma(it)
   else: processNote(c, it)
@@ -884,7 +887,7 @@ proc hasPragma*(n: PNode, pragma: TSpecialWord): bool =
     var key = if p.kind == nkExprColonExpr: p[0] else: p
     if key.kind == nkIdent and whichKeyword(key.ident) == pragma:
       return true
-  
+
   return false
 
 proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 36c0342cd..2d2f15fab 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -287,6 +287,7 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
     return n
   result = getConstExpr(c.module, e)
   if result == nil:
+    #if e.kind == nkEmpty: globalError(n.info, errConstExprExpected)
     result = evalConstExpr(c.module, e)
     if result == nil or result.kind == nkEmpty:
       if e.info != n.info:
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 14644a8d6..48f54fa6c 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -8,12 +8,12 @@
 #
 
 import
-  intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, 
+  intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
   wordrecg, strutils, options, guards
 
 # Second semantic checking pass over the AST. Necessary because the old
 # way had some inherent problems. Performs:
-# 
+#
 # * effect+exception tracking
 # * "usage before definition" checking
 # * checks for invalid usages of compiletime magics (not implemented)
@@ -23,7 +23,7 @@ import
 # Predefined effects:
 #   io, time (time dependent), gc (performs GC'ed allocation), exceptions,
 #   side effect (accesses global), store (stores into *type*),
-#   store_unknown (performs some store) --> store(any)|store(x) 
+#   store_unknown (performs some store) --> store(any)|store(x)
 #   load (loads from *type*), recursive (recursive call), unsafe,
 #   endless (has endless loops), --> user effects are defined over *patterns*
 #   --> a TR macro can annotate the proc with user defined annotations
@@ -31,31 +31,31 @@ import
 
 # Load&Store analysis is performed on *paths*. A path is an access like
 # obj.x.y[i].z; splitting paths up causes some problems:
-# 
+#
 # var x = obj.x
 # var z = x.y[i].z
 #
 # Alias analysis is affected by this too! A good solution is *type splitting*:
-# T becomes T1 and T2 if it's known that T1 and T2 can't alias. 
-# 
+# T becomes T1 and T2 if it's known that T1 and T2 can't alias.
+#
 # An aliasing problem and a race condition are effectively the same problem.
 # Type based alias analysis is nice but not sufficient; especially splitting
 # an array and filling it in parallel should be supported but is not easily
 # done: It essentially requires a built-in 'indexSplit' operation and dependent
 # typing.
-  
+
 # ------------------------ exception and tag tracking -------------------------
 
 discard """
   exception tracking:
-  
+
   a() # raises 'x', 'e'
   try:
     b() # raises 'e'
   except e:
     # must not undo 'e' here; hrm
     c()
- 
+
  --> we need a stack of scopes for this analysis
 
   # XXX enhance the algorithm to care about 'dirty' expressions:
@@ -209,8 +209,7 @@ proc useVar(a: PEffects, n: PNode) =
       a.init.add s.id
   if {sfGlobal, sfThread} * s.flags == {sfGlobal} and s.kind in {skVar, skLet}:
     if s.guard != nil: guardGlobal(a, n, s.guard)
-    if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and 
-        tfGcSafe notin s.typ.flags:
+    if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem):
       if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
       markGcUnsafe(a)
 
@@ -321,7 +320,7 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
   dec tracked.inTryStmt
   for i in oldState.. <tracked.init.len:
     addToIntersection(inter, tracked.init[i])
-  
+
   var branches = 1
   var hasFinally = false
   for i in 1 .. < n.len:
@@ -345,7 +344,7 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
       setLen(tracked.init, oldState)
       track(tracked, b.sons[blen-1])
       hasFinally = true
-      
+
   tracked.bottom = oldBottom
   if not hasFinally:
     setLen(tracked.init, oldState)
@@ -356,7 +355,7 @@ proc isIndirectCall(n: PNode, owner: PSym): bool =
   # we don't count f(...) as an indirect call if 'f' is an parameter.
   # Instead we track expressions of type tyProc too. See the manual for
   # details:
-  if n.kind != nkSym: 
+  if n.kind != nkSym:
     result = true
   elif n.sym.kind == skParam:
     result = owner != n.sym.owner or owner == nil
@@ -366,13 +365,13 @@ proc isIndirectCall(n: PNode, owner: PSym): bool =
 proc isForwardedProc(n: PNode): bool =
   result = n.kind == nkSym and sfForward in n.sym.flags
 
-proc trackPragmaStmt(tracked: PEffects, n: PNode) = 
-  for i in countup(0, sonsLen(n) - 1): 
+proc trackPragmaStmt(tracked: PEffects, n: PNode) =
+  for i in countup(0, sonsLen(n) - 1):
     var it = n.sons[i]
     if whichPragma(it) == wEffects:
       # list the computed effects up to here:
       listEffects(tracked)
-      
+
 proc effectSpec(n: PNode, effectType: TSpecialWord): PNode =
   for i in countup(0, sonsLen(n) - 1):
     var it = n.sons[i]
@@ -387,12 +386,12 @@ proc documentEffect(n, x: PNode, effectType: TSpecialWord, idx: int): PNode =
   let spec = effectSpec(x, effectType)
   if isNil(spec):
     let s = n.sons[namePos].sym
-    
+
     let actual = s.typ.n.sons[0]
     if actual.len != effectListLen: return
     let real = actual.sons[idx]
-    
-    # warning: hack ahead: 
+
+    # warning: hack ahead:
     var effects = newNodeI(nkBracket, n.info, real.len)
     for i in 0 .. <real.len:
       var t = typeToString(real[i].typ)
@@ -409,7 +408,7 @@ proc documentRaises*(n: PNode) =
   let pragmas = n.sons[pragmasPos]
   let p1 = documentEffect(n, pragmas, wRaises, exceptionEffects)
   let p2 = documentEffect(n, pragmas, wTags, tagEffects)
-  
+
   if p1 != nil or p2 != nil:
     if pragmas.kind == nkEmpty:
       n.sons[pragmasPos] = newNodeI(nkPragma, n.info)
@@ -445,7 +444,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
   let pragma = s.ast.sons[pragmasPos]
   let spec = effectSpec(pragma, wRaises)
   mergeEffects(tracked, spec, n)
-  
+
   let tagSpec = effectSpec(pragma, wTags)
   mergeTags(tracked, tagSpec, n)
 
@@ -456,17 +455,17 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
 
 proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =
   let n = n.skipConv
-  if paramType != nil and tfNotNil in paramType.flags and 
+  if paramType != nil and tfNotNil in paramType.flags and
       n.typ != nil and tfNotNil notin n.typ.flags:
     if n.kind == nkAddr:
       # addr(x[]) can't be proven, but addr(x) can:
       if not containsNode(n, {nkDerefExpr, nkHiddenDeref}): return
-    elif n.kind == nkSym and n.sym.kind in routineKinds:
+    elif (n.kind == nkSym and n.sym.kind in routineKinds) or n.kind in procDefs:
       # 'p' is not nil obviously:
       return
     case impliesNotNil(tracked.guards, n)
     of impUnknown:
-      message(n.info, errGenerated, 
+      message(n.info, errGenerated,
               "cannot prove '$1' is not nil" % n.renderTree)
     of impNo:
       message(n.info, errGenerated, "'$1' is provably nil" % n.renderTree)
@@ -517,7 +516,7 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
 proc breaksBlock(n: PNode): bool =
   case n.kind
   of nkStmtList, nkStmtListExpr:
-    for c in n: 
+    for c in n:
       if breaksBlock(c): return true
   of nkBreakStmt, nkReturnStmt, nkRaiseStmt:
     return true
@@ -545,7 +544,7 @@ proc trackCase(tracked: PEffects, n: PNode) =
     if not breaksBlock(branch.lastSon): inc toCover
     for i in oldState.. <tracked.init.len:
       addToIntersection(inter, tracked.init[i])
-    
+
   let exh = case skipTypes(n.sons[0].typ, abstractVarRange-{tyTypeDesc}).kind
             of tyFloat..tyFloat128, tyString:
               lastSon(n).kind == nkElse
@@ -590,7 +589,7 @@ proc trackIf(tracked: PEffects, n: PNode) =
       if count >= toCover: tracked.init.add id
     # else we can't merge as it is not exhaustive
   setLen(tracked.guards, oldFacts)
-  
+
 proc trackBlock(tracked: PEffects, n: PNode) =
   if n.kind in {nkStmtList, nkStmtListExpr}:
     var oldState = -1
@@ -782,7 +781,7 @@ proc checkMethodEffects*(disp, branch: PSym) =
     checkRaisesSpec(tagsSpec, actual.sons[tagEffects],
       "can have an unlisted effect: ", hints=off, subtypeRelation)
   if sfThread in disp.flags and notGcSafe(branch.typ):
-    localError(branch.info, "base method is GC-safe, but '$1' is not" % 
+    localError(branch.info, "base method is GC-safe, but '$1' is not" %
                                 branch.name.s)
   if branch.typ.lockLevel > disp.typ.lockLevel:
     when true:
@@ -814,14 +813,14 @@ proc initEffects(effects: PNode; s: PSym; t: var TEffects) =
   newSeq(effects.sons, effectListLen)
   effects.sons[exceptionEffects] = newNodeI(nkArgList, s.info)
   effects.sons[tagEffects] = newNodeI(nkArgList, s.info)
-  
+
   t.exc = effects.sons[exceptionEffects]
   t.tags = effects.sons[tagEffects]
   t.owner = s
   t.init = @[]
   t.guards = @[]
   t.locked = @[]
-  
+
 proc trackProc*(s: PSym, body: PNode) =
   var effects = s.typ.n.sons[0]
   internalAssert effects.kind == nkEffectList
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 8a9f4a988..245f86427 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -352,7 +352,7 @@ proc semAnonTuple(c: PContext, n: PNode, prev: PType): PType =
   for i in countup(0, sonsLen(n) - 1):
     addSonSkipIntLit(result, semTypeNode(c, n.sons[i], nil))
 
-proc semTuple(c: PContext, n: PNode, prev: PType): PType = 
+proc semTuple(c: PContext, n: PNode, prev: PType): PType =
   var typ: PType
   result = newOrPrevType(tyTuple, prev, c)
   result.n = newNodeI(nkRecList, n.info)
@@ -800,7 +800,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
 
     for i in 0 .. paramType.sonsLen - 2:
       if paramType.sons[i].kind == tyStatic:
-        result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnknown'
+        var x = copyNode(ast.emptyNode)
+        x.typ = paramType.sons[i]
+        result.rawAddSon makeTypeFromExpr(c, x) # aka 'tyUnknown'
       else:
         result.rawAddSon newTypeS(tyAnything, c)
 
@@ -1045,8 +1047,8 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
     var m = newCandidate(c, t)
     matches(c, n, copyTree(n), m)
 
-    if m.state != csMatch:
-      var err = "cannot instantiate " & typeToString(t) & "\n" &
+    if m.state != csMatch and not m.typedescMatched:
+      let err = "cannot instantiate " & typeToString(t) & "\n" &
                 "got: (" & describeArgs(c, n) & ")\n" &
                 "but expected: (" & describeArgs(c, t.n, 0) & ")"
       localError(n.info, errGenerated, err)
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 012782730..9e0716114 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -34,9 +34,9 @@ proc checkPartialConstructedType(info: TLineInfo, t: PType) =
 proc checkConstructedType*(info: TLineInfo, typ: PType) =
   var t = typ.skipTypes({tyDistinct})
   if t.kind in tyTypeClasses: discard
-  elif tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject: 
+  elif tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
     localError(info, errInvalidPragmaX, "acyclic")
-  elif t.kind == tyVar and t.sons[0].kind == tyVar: 
+  elif t.kind == tyVar and t.sons[0].kind == tyVar:
     localError(info, errVarVarTypeNotAllowed)
   elif computeSize(t) == szIllegalRecursion:
     localError(info, errIllegalRecursionInTypeX, typeToString(t))
@@ -44,7 +44,7 @@ proc checkConstructedType*(info: TLineInfo, typ: PType) =
     sharedPtrCheck(info, t)
   when false:
     if t.kind == tyObject and t.sons[0] != nil:
-      if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags: 
+      if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags:
         localError(info, errInheritanceOnlyWithNonFinalObjects)
 
 proc searchInstTypes*(key: PType): PType =
@@ -69,7 +69,7 @@ proc searchInstTypes*(key: PType): PType =
         if not compareTypes(inst.sons[j], key.sons[j],
                             flags = {ExactGenericParams}):
           break matchType
-       
+
       return inst
 
 proc cacheTypeInst*(inst: PType) =
@@ -79,7 +79,7 @@ proc cacheTypeInst*(inst: PType) =
   genericTyp.sym.typeInstCache.safeAdd(inst)
 
 type
-  TReplTypeVars* {.final.} = object 
+  TReplTypeVars* {.final.} = object
     c*: PContext
     typeMap*: TIdTable        # map PType to PType
     symMap*: TIdTable         # map PSym to PSym
@@ -151,7 +151,7 @@ proc reResolveCallsWithTypedescParams(cl: var TReplTypeVars, n: PNode): PNode =
     if needsFixing:
       n.sons[0] = newSymNode(n.sons[0].sym.owner)
       return cl.c.semOverloadedCall(cl.c, n, n, {skProc})
-  
+
   for i in 0 .. <n.safeLen:
     n.sons[i] = reResolveCallsWithTypedescParams(cl, n[i])
 
@@ -203,18 +203,18 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode =
       newSons(result, length)
       for i in countup(0, length - 1):
         result.sons[i] = replaceTypeVarsN(cl, n.sons[i])
-  
-proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = 
+
+proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
   if s == nil: return nil
   result = PSym(idTableGet(cl.symMap, s))
-  if result == nil: 
+  if result == nil:
     result = copySym(s, false)
     incl(result.flags, sfFromGeneric)
     idTablePut(cl.symMap, s, result)
     result.owner = s.owner
     result.typ = replaceTypeVarsT(cl, s.typ)
     result.ast = replaceTypeVarsN(cl, s.ast)
-    
+
 proc lookupTypeVar(cl: var TReplTypeVars, t: PType): PType =
   result = PType(idTableGet(cl.typeMap, t))
   if result == nil:
@@ -234,7 +234,7 @@ proc instCopyType*(cl: var TReplTypeVars, t: PType): PType =
   result.flags.incl tfFromGeneric
   result.flags.excl tfInstClearedFlags
 
-proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = 
+proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
   # tyGenericInvocation[A, tyGenericInvocation[A, B]]
   # is difficult to handle:
   var body = t.sons[0]
@@ -256,7 +256,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
         propagateToOwner(header, x)
     else:
       propagateToOwner(header, x)
-  
+
   if header != t:
     # search again after first pass:
     result = searchInstTypes(header)
@@ -282,7 +282,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
     header.sons[i] = x
     propagateToOwner(header, x)
     idTablePut(cl.typeMap, body.sons[i-1], x)
-  
+
   for i in countup(1, sonsLen(t) - 1):
     # if one of the params is not concrete, we cannot do anything
     # but we already raised an error!
@@ -310,7 +310,7 @@ proc eraseVoidParams*(t: PType) =
   # don't deal with '(): void':
   if t.sons[0] != nil and t.sons[0].kind == tyEmpty:
     t.sons[0] = nil
-  
+
   for i in 1 .. <t.sonsLen:
     # don't touch any memory unless necessary
     if t.sons[i].kind == tyEmpty:
@@ -332,7 +332,7 @@ proc skipIntLiteralParams*(t: PType) =
     if skipped != p:
       t.sons[i] = skipped
       if i > 0: t.n.sons[i].sym.typ = skipped
-  
+
   # when the typeof operator is used on a static input
   # param, the results gets infected with static as well:
   if t.sons[0] != nil and t.sons[0].kind == tyStatic:
@@ -359,7 +359,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
   if t.kind in {tyStatic, tyGenericParam, tyIter} + tyTypeClasses:
     let lookup = PType(idTableGet(cl.typeMap, t))
     if lookup != nil: return lookup
-  
+
   case t.kind
   of tyGenericInvocation:
     result = handleGenericInvocation(cl, t)
@@ -373,7 +373,8 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
     if cl.allowMetaTypes: return
     assert t.n.typ != t
     var n = prepareNode(cl, t.n)
-    n = cl.c.semConstExpr(cl.c, n)
+    if n.kind != nkEmpty:
+      n = cl.c.semConstExpr(cl.c, n)
     if n.typ.kind == tyTypeDesc:
       # XXX: sometimes, chained typedescs enter here.
       # It may be worth investigating why this is happening,
@@ -394,7 +395,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
 
   of tyInt, tyFloat:
     result = skipIntLit(t)
-  
+
   of tyTypeDesc:
     let lookup = PType(idTableGet(cl.typeMap, t)) # lookupTypeVar(cl, t)
     if lookup != nil:
@@ -402,7 +403,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
       if tfUnresolved in t.flags: result = result.base
     elif t.sons[0].kind != tyNone:
       result = makeTypeDesc(cl.c, replaceTypeVarsT(cl, t.sons[0]))
- 
+
   of tyUserTypeClass:
     result = t
 
@@ -411,31 +412,31 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
     for i in 1 .. <result.sonsLen:
       result.sons[i] = replaceTypeVarsT(cl, result.sons[i])
     propagateToOwner(result, result.lastSon)
-  
+
   else:
     if containsGenericType(t):
       result = instCopyType(cl, t)
       result.size = -1 # needs to be recomputed
-      
+
       for i in countup(0, sonsLen(result) - 1):
         if result.sons[i] != nil:
           result.sons[i] = replaceTypeVarsT(cl, result.sons[i])
           propagateToOwner(result, result.sons[i])
 
       result.n = replaceTypeVarsN(cl, result.n)
-     
+
       case result.kind
       of tyArray:
         let idx = result.sons[0]
         internalAssert idx.kind != tyStatic
-       
+
       of tyObject, tyTuple:
         propagateFieldFlags(result, result.n)
-      
+
       of tyProc:
         eraseVoidParams(result)
         skipIntLiteralParams(result)
-      
+
       else: discard
 
 proc initTypeVars*(p: PContext, pt: TIdTable, info: TLineInfo): TReplTypeVars =
@@ -450,7 +451,7 @@ proc replaceTypesInBody*(p: PContext, pt: TIdTable, n: PNode): PNode =
   pushInfoContext(n.info)
   result = replaceTypeVarsN(cl, n)
   popInfoContext()
-  
+
 proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo,
                            t: PType): PType =
   var cl = initTypeVars(p, pt, info)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index e56d82a5b..38340ffb7 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -46,7 +46,7 @@ type
                              # be instantiated
     coerceDistincts*: bool   # this is an explicit coercion that can strip away
                              # a distrinct type
-    typedescMatched: bool
+    typedescMatched*: bool
     inheritancePenalty: int  # to prefer closest father object type
     errors*: CandidateErrors # additional clarifications to be displayed to the
                              # user if overload resolution fails
@@ -989,7 +989,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
           else:
             internalAssert a.sons != nil and a.sons.len > 0
             c.typedescMatched = true
-            result = typeRel(c, f.base, a.skipTypes({tyGenericParam, tyTypeDesc}))
+            var aa = a
+            while aa.kind in {tyTypeDesc, tyGenericParam} and
+                aa.len > 0:
+              aa = lastSon(aa)
+            result = typeRel(c, f.base, aa)
             if result > isGeneric: result = isGeneric
         else:
           result = isNone
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 325ce9d5e..2143b6bec 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -579,8 +579,7 @@ proc getMergeOp(n: PNode): PSym =
   case n.kind
   of nkCall, nkHiddenCallConv, nkCommand, nkInfix, nkPrefix, nkPostfix,
      nkCallStrLit:
-    if (n.sons[0].kind == nkSym) and (n.sons[0].sym.kind == skProc) and
-        (sfMerge in n.sons[0].sym.flags):
+    if n.sons[0].kind == nkSym and n.sons[0].sym.magic == mConStrStr:
       result = n.sons[0].sym
   else: discard
 
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim
index 11d839c41..2b80f6aed 100644
--- a/compiler/vmdeps.nim
+++ b/compiler/vmdeps.nim
@@ -28,7 +28,7 @@ proc opGorge*(cmd, input: string): string =
   except IOError, OSError:
     result = ""
 
-proc opSlurp*(file: string, info: TLineInfo, module: PSym): string = 
+proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
   try:
     let filename = file.findFile
     result = readFile(filename)
@@ -87,7 +87,12 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
       result.add mapTypeToAst(t.sons[i], info)
   of tyGenericInst, tyGenericBody, tyOrdinal, tyUserTypeClassInst:
     result = mapTypeToAst(t.lastSon, info)
-  of tyGenericParam, tyDistinct, tyForward: result = atomicType(t.sym.name.s)
+  of tyDistinct:
+    if allowRecursion:
+      result = mapTypeToBracket("distinct", t, info)
+    else:
+      result = atomicType(t.sym.name.s)
+  of tyGenericParam, tyForward: result = atomicType(t.sym.name.s)
   of tyObject:
     if allowRecursion:
       result = newNodeIT(nkObjectTy, info, t)
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 5b7b0b0fd..2383e2542 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -15,7 +15,7 @@
 #   this doesn't matter. However it matters for strings and other complex
 #   types that use the 'node' field; the reason is that slots are
 #   re-used in a register based VM. Example:
-# 
+#
 # .. code-block:: nim
 #   let s = a & b  # no matter what, create fresh node
 #   s = a & b  # no matter what, keep the node
@@ -64,17 +64,17 @@ proc codeListing(c: PCtx, result: var string, start=0; last = -1) =
       let y = c.code[i+1]
       let z = c.code[i+2]
       result.addf("\t$#\tr$#, r$#, $#, $#", ($opc).substr(3), x.regA, x.regB,
-        c.types[y.regBx-wordExcess].typeToString, 
+        c.types[y.regBx-wordExcess].typeToString,
         c.types[z.regBx-wordExcess].typeToString)
       inc i, 2
     elif opc < firstABxInstr:
-      result.addf("\t$#\tr$#, r$#, r$#", ($opc).substr(3), x.regA, 
+      result.addf("\t$#\tr$#, r$#, r$#", ($opc).substr(3), x.regA,
                   x.regB, x.regC)
     elif opc in relativeJumps:
       result.addf("\t$#\tr$#, L$#", ($opc).substr(3), x.regA,
                   i+x.regBx-wordExcess)
     elif opc in {opcLdConst, opcAsgnConst}:
-      result.addf("\t$#\tr$#, $#", ($opc).substr(3), x.regA, 
+      result.addf("\t$#\tr$#, $#", ($opc).substr(3), x.regA,
         c.constants[x.regBx-wordExcess].renderTree)
     else:
       result.addf("\t$#\tr$#, $#", ($opc).substr(3), x.regA, x.regBx-wordExcess)
@@ -117,7 +117,7 @@ proc gABx(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0; bx: int) =
   # Applies `opc` to `bx` and stores it into register `a`
   # `bx` must be signed and in the range [-32767, 32768]
   if bx >= -32767 and bx <= 32768:
-    let ins = (opc.uint32 or a.uint32 shl 8'u32 or 
+    let ins = (opc.uint32 or a.uint32 shl 8'u32 or
               (bx+wordExcess).uint32 shl 16'u32).TInstr
     c.code.add(ins)
     c.debug.add(n.info)
@@ -174,7 +174,7 @@ proc getTemp(c: PCtx; typ: PType): TRegister =
     if c.slots[i].kind == k and not c.slots[i].inUse:
       c.slots[i].inUse = true
       return TRegister(i)
-      
+
   # if register pressure is high, we re-use more aggressively:
   if c.maxSlots >= HighRegisterPressure:
     for i in 0 .. c.maxSlots-1:
@@ -208,7 +208,7 @@ proc getTempRange(c: PCtx; n: int; kind: TSlotKind): TRegister =
   result = TRegister(c.maxSlots)
   inc c.maxSlots, n
   for k in result .. result+n-1: c.slots[k] = (inUse: true, kind: kind)
-  
+
 proc freeTempRange(c: PCtx; start: TRegister, n: int) =
   for i in start .. start+n-1: c.freeTemp(TRegister(i))
 
@@ -217,7 +217,7 @@ template withTemp(tmp, typ: expr, body: stmt) {.immediate, dirty.} =
   body
   c.freeTemp(tmp)
 
-proc popBlock(c: PCtx; oldLen: int) =  
+proc popBlock(c: PCtx; oldLen: int) =
   for f in c.prc.blocks[oldLen].fixups:
     c.patch(f)
   c.prc.blocks.setLen(oldLen)
@@ -386,7 +386,7 @@ proc genLiteral(c: PCtx; n: PNode): int =
   result = rawGenLiteral(c, n)
 
 proc unused(n: PNode; x: TDest) {.inline.} =
-  if x >= 0: 
+  if x >= 0:
     #debug(n)
     internalError(n.info, "not unused")
 
@@ -446,11 +446,11 @@ proc genTry(c: PCtx; n: PNode; dest: var TDest) =
       var blen = len(it)
       # first opcExcept contains the end label of the 'except' block:
       let endExcept = c.xjmp(it, opcExcept, 0)
-      for j in countup(0, blen - 2): 
+      for j in countup(0, blen - 2):
         assert(it.sons[j].kind == nkType)
         let typ = it.sons[j].typ.skipTypes(abstractPtrs-{tyTypeDesc})
         c.gABx(it, opcExcept, 0, c.genType(typ))
-      if blen == 1: 
+      if blen == 1:
         # general except section:
         c.gABx(it, opcExcept, 0, 0)
       c.gen(it.lastSon, dest)
@@ -498,7 +498,7 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) =
 template isGlobal(s: PSym): bool = sfGlobal in s.flags and s.kind != skForVar
 proc isGlobal(n: PNode): bool = n.kind == nkSym and isGlobal(n.sym)
 
-proc needsAsgnPatch(n: PNode): bool = 
+proc needsAsgnPatch(n: PNode): bool =
   n.kind in {nkBracketExpr, nkDotExpr, nkCheckedFieldExpr,
              nkDerefExpr, nkHiddenDeref} or (n.kind == nkSym and n.sym.isGlobal)
 
@@ -552,9 +552,9 @@ proc genAsgnPatch(c: PCtx; le: PNode, value: TRegister) =
 proc genNew(c: PCtx; n: PNode) =
   let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(n.sons[1].typ)
              else: c.genx(n.sons[1])
-  # we use the ref's base type here as the VM conflates 'ref object' 
+  # we use the ref's base type here as the VM conflates 'ref object'
   # and 'object' since internally we already have a pointer.
-  c.gABx(n, opcNew, dest, 
+  c.gABx(n, opcNew, dest,
          c.genType(n.sons[1].typ.skipTypes(abstractVar-{tyTypeDesc}).sons[0]))
   c.genAsgnPatch(n.sons[1], dest)
   c.freeTemp(dest)
@@ -657,7 +657,7 @@ proc genUnaryStmt(c: PCtx; n: PNode; opc: TOpcode) =
 proc genVarargsABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
   if dest < 0: dest = getTemp(c, n.typ)
   var x = c.getTempRange(n.len-1, slotTempStr)
-  for i in 1..n.len-1: 
+  for i in 1..n.len-1:
     var r: TRegister = x+i-1
     c.gen(n.sons[i], r)
   c.gABC(n, opc, dest, x, n.len-1)
@@ -681,7 +681,7 @@ proc genAddSubInt(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
     genBinaryABC(c, n, dest, opc)
   c.genNarrow(n, dest)
 
-proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) =  
+proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) =
   let tmp = c.genx(arg)
   if dest < 0: dest = c.getTemp(n.typ)
   c.gABC(n, opc, dest, tmp)
@@ -792,12 +792,12 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
     genNarrow(c, n, dest)
   of mUnaryMinusF64: genUnaryABC(c, n, dest, opcUnaryMinusFloat)
   of mUnaryPlusI, mUnaryPlusI64, mUnaryPlusF64: gen(c, n.sons[1], dest)
-  of mBitnotI, mBitnotI64: 
+  of mBitnotI, mBitnotI64:
     genUnaryABC(c, n, dest, opcBitnotInt)
     genNarrowU(c, n, dest)
   of mZe8ToI, mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64,
-     mToU8, mToU16, mToU32, mToFloat, mToBiggestFloat, mToInt, 
-     mToBiggestInt, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, 
+     mToU8, mToU16, mToU32, mToFloat, mToBiggestFloat, mToInt,
+     mToBiggestInt, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr,
      mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr:
     genConv(c, n, n.sons[1], dest)
   of mEqStr: genBinaryABC(c, n, dest, opcEqStr)
@@ -825,7 +825,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
     c.gABC(n, if m == mSetLengthStr: opcSetLenStr else: opcSetLenSeq, d, tmp)
     c.genAsgnPatch(n.sons[1], d)
     c.freeTemp(tmp)
-  of mSwap: 
+  of mSwap:
     unused(n, dest)
     var
       d1 = c.genx(n.sons[1])
@@ -874,7 +874,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
     c.freeTemp(tmp1)
     c.freeTemp(tmp3)
     c.genAsgnPatch(d2AsNode, d2)
-    c.freeTemp(d2)    
+    c.freeTemp(d2)
   of mReset:
     unused(n, dest)
     var d = c.genx(n.sons[1])
@@ -913,7 +913,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
   of mAppendStrCh:
     unused(n, dest)
     genBinaryStmtVar(c, n, opcAddStrCh)
-  of mAppendStrStr: 
+  of mAppendStrStr:
     unused(n, dest)
     genBinaryStmtVar(c, n, opcAddStrStr)
   of mAppendSeqElem:
@@ -923,7 +923,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
     genUnaryABC(c, n, dest, opcParseExprToAst)
   of mParseStmtToAst:
     genUnaryABC(c, n, dest, opcParseStmtToAst)
-  of mTypeTrait: 
+  of mTypeTrait:
     let tmp = c.genx(n.sons[1])
     if dest < 0: dest = c.getTemp(n.typ)
     c.gABx(n, opcSetType, tmp, c.genType(n.sons[1].typ))
@@ -960,19 +960,19 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
   of mNSetIntVal:
     unused(n, dest)
     genBinaryStmt(c, n, opcNSetIntVal)
-  of mNSetFloatVal: 
+  of mNSetFloatVal:
     unused(n, dest)
     genBinaryStmt(c, n, opcNSetFloatVal)
   of mNSetSymbol:
     unused(n, dest)
     genBinaryStmt(c, n, opcNSetSymbol)
-  of mNSetIdent: 
+  of mNSetIdent:
     unused(n, dest)
     genBinaryStmt(c, n, opcNSetIdent)
   of mNSetType:
     unused(n, dest)
     genBinaryStmt(c, n, opcNSetType)
-  of mNSetStrVal: 
+  of mNSetStrVal:
     unused(n, dest)
     genBinaryStmt(c, n, opcNSetStrVal)
   of mNNewNimNode: genBinaryABC(c, n, dest, opcNNewNimNode)
@@ -990,10 +990,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
   of mEqIdent: genBinaryABC(c, n, dest, opcEqIdent)
   of mEqNimrodNode: genBinaryABC(c, n, dest, opcEqNimrodNode)
   of mNLineInfo: genUnaryABC(c, n, dest, opcNLineInfo)
-  of mNHint: 
+  of mNHint:
     unused(n, dest)
     genUnaryStmt(c, n, opcNHint)
-  of mNWarning: 
+  of mNWarning:
     unused(n, dest)
     genUnaryStmt(c, n, opcNWarning)
   of mNError:
@@ -1024,7 +1024,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
     else:
       globalError(n.info, "expandToAst requires a call expression")
   else:
-    # mGCref, mGCunref, 
+    # mGCref, mGCunref,
     internalError(n.info, "cannot generate code for: " & $m)
 
 const
@@ -1056,7 +1056,7 @@ proc unneededIndirection(n: PNode): bool =
   n.typ.skipTypes(abstractInst-{tyTypeDesc}).kind == tyRef
 
 proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
-                  flags: TGenFlags) = 
+                  flags: TGenFlags) =
   # a nop for certain types
   let isAddr = opc in {opcAddrNode, opcAddrReg}
   let newflags = if isAddr: flags+{gfAddrOf} else: flags
@@ -1144,7 +1144,7 @@ proc checkCanEval(c: PCtx; n: PNode) =
   # proc foo() = var x ...
   let s = n.sym
   if {sfCompileTime, sfGlobal} <= s.flags: return
-  if s.kind in {skVar, skTemp, skLet, skParam, skResult} and 
+  if s.kind in {skVar, skTemp, skLet, skParam, skResult} and
       not s.isOwnedBy(c.prc.sym) and s.owner != c.module:
     cannotEval(n)
 
@@ -1338,27 +1338,27 @@ proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
   else:
     genArrAccess2(c, n, dest, opcLdArr, flags)
 
-proc getNullValueAux(obj: PNode, result: PNode) = 
+proc getNullValueAux(obj: PNode, result: PNode) =
   case obj.kind
   of nkRecList:
     for i in countup(0, sonsLen(obj) - 1): getNullValueAux(obj.sons[i], result)
   of nkRecCase:
     getNullValueAux(obj.sons[0], result)
-    for i in countup(1, sonsLen(obj) - 1): 
+    for i in countup(1, sonsLen(obj) - 1):
       getNullValueAux(lastSon(obj.sons[i]), result)
   of nkSym:
     addSon(result, getNullValue(obj.sym.typ, result.info))
   else: internalError(result.info, "getNullValueAux")
-  
-proc getNullValue(typ: PType, info: TLineInfo): PNode = 
+
+proc getNullValue(typ: PType, info: TLineInfo): PNode =
   var t = skipTypes(typ, abstractRange-{tyTypeDesc})
   result = emptyNode
   case t.kind
-  of tyBool, tyEnum, tyChar, tyInt..tyInt64: 
+  of tyBool, tyEnum, tyChar, tyInt..tyInt64:
     result = newNodeIT(nkIntLit, info, t)
   of tyUInt..tyUInt64:
     result = newNodeIT(nkUIntLit, info, t)
-  of tyFloat..tyFloat128: 
+  of tyFloat..tyFloat128:
     result = newNodeIT(nkFloatLit, info, t)
   of tyCString, tyString:
     result = newNodeIT(nkStrLit, info, t)
@@ -1372,7 +1372,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
       result = newNodeIT(nkPar, info, t)
       result.add(newNodeIT(nkNilLit, info, t))
       result.add(newNodeIT(nkNilLit, info, t))
-  of tyObject: 
+  of tyObject:
     result = newNodeIT(nkPar, info, t)
     getNullValueAux(t.n, result)
     # initialize inherited fields:
@@ -1380,9 +1380,9 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
     while base != nil:
       getNullValueAux(skipTypes(base, skipPtrs).n, result)
       base = base.sons[0]
-  of tyArray, tyArrayConstr: 
+  of tyArray, tyArrayConstr:
     result = newNodeIT(nkBracket, info, t)
-    for i in countup(0, int(lengthOrd(t)) - 1): 
+    for i in countup(0, int(lengthOrd(t)) - 1):
       addSon(result, getNullValue(elemType(t), info))
   of tyTuple:
     result = newNodeIT(nkPar, info, t)
@@ -1459,7 +1459,7 @@ proc genArrayConstr(c: PCtx, n: PNode, dest: var TDest) =
     c.gABx(n, opcNewSeq, dest, c.genType(seqType))
     c.gABx(n, opcNewSeq, tmp, 0)
     c.freeTemp(tmp)
-  
+
   if n.len > 0:
     var tmp = getTemp(c, intType)
     c.gABx(n, opcLdNullReg, tmp, c.genType(intType))
@@ -1536,7 +1536,7 @@ proc procIsCallback(c: PCtx; s: PSym): bool =
   if s.offset < -1: return true
   var i = -2
   for key, value in items(c.callbacks):
-    if s.matches(key): 
+    if s.matches(key):
       doAssert s.offset == -1
       s.offset = i
       return true
@@ -1584,7 +1584,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
   of nkNilLit:
     if not n.typ.isEmptyType: genLit(c, getNullValue(n.typ, n.info), dest)
     else: unused(n, dest)
-  of nkAsgn, nkFastAsgn: 
+  of nkAsgn, nkFastAsgn:
     unused(n, dest)
     genAsgn(c, n.sons[0], n.sons[1], n.kind == nkAsgn)
   of nkDotExpr: genObjAccess(c, n, dest, flags)
@@ -1633,7 +1633,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
     let s = n.sons[namePos].sym
     discard genProc(c, s)
     genLit(c, n.sons[namePos], dest)
-  of nkChckRangeF, nkChckRange64, nkChckRange: 
+  of nkChckRangeF, nkChckRange64, nkChckRange:
     let
       tmp0 = c.genx(n.sons[0])
       tmp1 = c.genx(n.sons[1])
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index ae036bc0c..393798947 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -13,44 +13,44 @@
 # does not support strings. Without this the code would
 # be slow and unreadable.
 
-import 
+import
   hashes, strutils, idents
 
 # Keywords must be kept sorted and within a range
 
 type
-  TSpecialWord* = enum 
-    wInvalid, 
-    
-    wAddr, wAnd, wAs, wAsm, wAtomic, 
-    wBind, wBlock, wBreak, wCase, wCast, wConst, 
-    wContinue, wConverter, wDefer, wDiscard, wDistinct, wDiv, wDo, 
+  TSpecialWord* = enum
+    wInvalid,
+
+    wAddr, wAnd, wAs, wAsm, wAtomic,
+    wBind, wBlock, wBreak, wCase, wCast, wConst,
+    wContinue, wConverter, wDefer, wDiscard, wDistinct, wDiv, wDo,
     wElif, wElse, wEnd, wEnum, wExcept, wExport,
-    wFinally, wFor, wFrom, wFunc, wGeneric, wIf, wImport, wIn, 
+    wFinally, wFor, wFrom, wFunc, wGeneric, wIf, wImport, wIn,
     wInclude, wInterface, wIs, wIsnot, wIterator, wLet,
-    wMacro, wMethod, wMixin, wMod, wNil, 
-    wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn, 
-    wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wUsing, wVar, 
+    wMacro, wMethod, wMixin, wMod, wNil,
+    wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn,
+    wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wUsing, wVar,
     wWhen, wWhile, wWith, wWithout, wXor, wYield,
-    
+
     wColon, wColonColon, wEquals, wDot, wDotDot,
     wStar, wMinus,
     wMagic, wThread, wFinal, wProfiler, wObjChecks,
 
     wDestroy,
-    
-    wImmediate, wDestructor, wDelegator, wOverride,
+
+    wImmediate, wConstructor, wDestructor, wDelegator, wOverride,
     wImportCpp, wImportObjC,
     wImportCompilerProc,
     wImportc, wExportc, wIncompleteStruct, wRequiresInit,
     wAlign, wNodecl, wPure, wSideeffect, wHeader,
-    wNosideeffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib, 
-    wCompilerproc, wProcVar, 
-    wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef, 
-    wLinedir, wStacktrace, wLinetrace, wLink, wCompile, 
-    wLinksys, wDeprecated, wVarargs, wCallconv, wBreakpoint, wDebugger, 
-    wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline, 
-    wFastcall, wClosure, wNoconv, wOn, wOff, wChecks, wRangechecks, 
+    wNosideeffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib,
+    wCompilerproc, wProcVar,
+    wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef,
+    wLinedir, wStacktrace, wLinetrace, wLink, wCompile,
+    wLinksys, wDeprecated, wVarargs, wCallconv, wBreakpoint, wDebugger,
+    wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline,
+    wFastcall, wClosure, wNoconv, wOn, wOff, wChecks, wRangechecks,
     wBoundchecks, wOverflowchecks, wNilchecks,
     wFloatchecks, wNanChecks, wInfChecks,
     wAssertions, wPatterns, wWarnings,
@@ -59,11 +59,11 @@ type
     wPragma,
     wCompileTime, wNoInit,
     wPassc, wPassl, wBorrow, wDiscardable,
-    wFieldChecks, 
-    wWatchPoint, wSubsChar, 
-    wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, 
+    wFieldChecks,
+    wWatchPoint, wSubsChar,
+    wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto,
     wInjectStmt, wExperimental,
-    wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, 
+    wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
     wAsmNoStackFrame,
     wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
 
@@ -82,38 +82,38 @@ type
     wStdIn, wStdOut, wStdErr,
 
     wInOut, wByCopy, wByRef, wOneWay,
-    
+
   TSpecialWords* = set[TSpecialWord]
 
-const 
+const
   oprLow* = ord(wColon)
   oprHigh* = ord(wDotDot)
-  
+
   nimKeywordsLow* = ord(wAsm)
   nimKeywordsHigh* = ord(wYield)
-  
+
   ccgKeywordsLow* = ord(wAuto)
   ccgKeywordsHigh* = ord(wOneWay)
-  
+
   cppNimSharedKeywords* = {
     wAsm, wBreak, wCase, wConst, wContinue, wDo, wElse, wEnum, wExport,
     wFor, wIf, wReturn, wStatic, wTemplate, wTry, wWhile, wUsing}
 
-  specialWords*: array[low(TSpecialWord)..high(TSpecialWord), string] = ["", 
-    
-    "addr", "and", "as", "asm", "atomic", 
-    "bind", "block", "break", "case", "cast", 
+  specialWords*: array[low(TSpecialWord)..high(TSpecialWord), string] = ["",
+
+    "addr", "and", "as", "asm", "atomic",
+    "bind", "block", "break", "case", "cast",
     "const", "continue", "converter",
     "defer", "discard", "distinct", "div", "do",
-    "elif", "else", "end", "enum", "except", "export", 
-    "finally", "for", "from", "func", "generic", "if", 
+    "elif", "else", "end", "enum", "except", "export",
+    "finally", "for", "from", "func", "generic", "if",
     "import", "in", "include", "interface", "is", "isnot", "iterator",
     "let",
     "macro", "method", "mixin", "mod", "nil", "not", "notin",
-    "object", "of", "or", 
+    "object", "of", "or",
     "out", "proc", "ptr", "raise", "ref", "return",
     "shl", "shr", "static",
-    "template", "try", "tuple", "type", "using", "var", 
+    "template", "try", "tuple", "type", "using", "var",
     "when", "while", "with", "without", "xor",
     "yield",
 
@@ -122,22 +122,22 @@ const
     "magic", "thread", "final", "profiler", "objchecks",
 
     "destroy",
-    
-    "immediate", "destructor", "delegator", "override",
+
+    "immediate", "constructor", "destructor", "delegator", "override",
     "importcpp", "importobjc",
     "importcompilerproc", "importc", "exportc", "incompletestruct",
     "requiresinit", "align", "nodecl", "pure", "sideeffect",
-    "header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib", 
-    "compilerproc", "procvar", "fatal", "error", "warning", "hint", "line", 
-    "push", "pop", "define", "undef", "linedir", "stacktrace", "linetrace", 
-    "link", "compile", "linksys", "deprecated", "varargs", 
-    "callconv", "breakpoint", "debugger", "nimcall", "stdcall", 
+    "header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib",
+    "compilerproc", "procvar", "fatal", "error", "warning", "hint", "line",
+    "push", "pop", "define", "undef", "linedir", "stacktrace", "linetrace",
+    "link", "compile", "linksys", "deprecated", "varargs",
+    "callconv", "breakpoint", "debugger", "nimcall", "stdcall",
     "cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "closure",
-    "noconv", "on", "off", "checks", "rangechecks", "boundchecks", 
+    "noconv", "on", "off", "checks", "rangechecks", "boundchecks",
     "overflowchecks", "nilchecks",
     "floatchecks", "nanchecks", "infchecks",
 
-    "assertions", "patterns", "warnings", "hints", 
+    "assertions", "patterns", "warnings", "hints",
     "optimization", "raises", "writes", "reads", "size", "effects", "tags",
     "deadcodeelim", "safecode", "noforward",
     "pragma",
@@ -149,7 +149,7 @@ const
     "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
     "asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
     "guard", "locks",
-    
+
     "auto", "bool", "catch", "char", "class",
     "const_cast", "default", "delete", "double",
     "dynamic_cast", "explicit", "extern", "false",
@@ -169,22 +169,22 @@ const
     "inout", "bycopy", "byref", "oneway",
     ]
 
-proc findStr*(a: openArray[string], s: string): int = 
-  for i in countup(low(a), high(a)): 
-    if cmpIgnoreStyle(a[i], s) == 0: 
+proc findStr*(a: openArray[string], s: string): int =
+  for i in countup(low(a), high(a)):
+    if cmpIgnoreStyle(a[i], s) == 0:
       return i
   result = - 1
 
-proc whichKeyword*(id: PIdent): TSpecialWord = 
+proc whichKeyword*(id: PIdent): TSpecialWord =
   if id.id < 0: result = wInvalid
   else: result = TSpecialWord(id.id)
 
-proc whichKeyword*(id: string): TSpecialWord = 
+proc whichKeyword*(id: string): TSpecialWord =
   result = whichKeyword(getIdent(id))
-  
-proc initSpecials() = 
+
+proc initSpecials() =
   # initialize the keywords:
-  for s in countup(succ(low(specialWords)), high(specialWords)): 
+  for s in countup(succ(low(specialWords)), high(specialWords)):
     getIdent(specialWords[s], hashIgnoreStyle(specialWords[s])).id = ord(s)
-  
+
 initSpecials()
diff --git a/doc/nimc.txt b/doc/nimc.txt
index c6b0b5255..831fce567 100644
--- a/doc/nimc.txt
+++ b/doc/nimc.txt
@@ -545,6 +545,20 @@ instead:
   let x = newFoo(3, 4)
 
 
+Wrapping constructors
+~~~~~~~~~~~~~~~~~~~~~
+
+Sometimes a C++ class has a private copy constructor and so code like
+``Class c = Class(1,2);`` must not be generated but instead ``Class c(1,2);``.
+For this purpose the Nim proc that wraps a C++ constructor needs to be
+annotated with the `constructor`:idx: pragma. This pragma also helps to generate
+faster C++ code since construction then doesn't invoke the copy constructor:
+
+.. code-block:: nim
+  # a better constructor of 'Foo':
+  proc constructFoo(a, b: cint): Foo {.importcpp: "Foo(@)", constructor.}
+
+
 Wrapping destructors
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -608,7 +622,7 @@ allows *sloppy* interfacing with libraries written in Objective C:
 
   - (void)greet:(long)x y:(long)dummy
   {
-	  printf("Hello, World!\n");
+    printf("Hello, World!\n");
   }
   @end
 
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index f73dbd241..c18e805e0 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -85,11 +85,11 @@ type
     ntyInt8, ntyInt16, ntyInt32, ntyInt64,
     ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128,
     ntyUInt, ntyUInt8, ntyUInt16, ntyUInt32, ntyUInt64,
-    ntyBigNum, 
-    ntyConst, ntyMutable, ntyVarargs, 
+    ntyBigNum,
+    ntyConst, ntyMutable, ntyVarargs,
     ntyIter,
     ntyError
-    
+
   TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
   NimSymKind* = enum
     nskUnknown, nskConditional, nskDynLib, nskParam,
@@ -120,12 +120,10 @@ const
   nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
                    nnkCallStrLit}
 
-{.push warning[deprecated]: off.}
-
-proc `[]`*(n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild", noSideEffect.}
+proc `[]`*(n: NimNode, i: int): NimNode {.magic: "NChild", noSideEffect.}
   ## get `n`'s `i`'th child.
 
-proc `[]=`*(n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild",
+proc `[]=`*(n: NimNode, i: int, child: NimNode) {.magic: "NSetChild",
   noSideEffect.}
   ## set `n`'s `i`'th child to `child`.
 
@@ -141,34 +139,34 @@ proc `$`*(s: NimSym): string {.magic: "IdentToStr", noSideEffect.}
 proc `==`*(a, b: NimIdent): bool {.magic: "EqIdent", noSideEffect.}
   ## compares two Nim identifiers
 
-proc `==`*(a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.}
+proc `==`*(a, b: NimNode): bool {.magic: "EqNimrodNode", noSideEffect.}
   ## compares two Nim nodes
 
-proc len*(n: PNimrodNode): int {.magic: "NLen", noSideEffect.}
+proc len*(n: NimNode): int {.magic: "NLen", noSideEffect.}
   ## returns the number of children of `n`.
 
-proc add*(father, child: PNimrodNode): PNimrodNode {.magic: "NAdd", discardable,
+proc add*(father, child: NimNode): NimNode {.magic: "NAdd", discardable,
   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 {.
+proc add*(father: NimNode, children: varargs[NimNode]): NimNode {.
   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.
 
-proc del*(father: PNimrodNode, idx = 0, n = 1) {.magic: "NDel", noSideEffect.}
+proc del*(father: NimNode, idx = 0, n = 1) {.magic: "NDel", noSideEffect.}
   ## deletes `n` children of `father` starting at index `idx`.
 
-proc kind*(n: PNimrodNode): TNimrodNodeKind {.magic: "NKind", noSideEffect.}
+proc kind*(n: NimNode): NimNodeKind {.magic: "NKind", noSideEffect.}
   ## returns the `kind` of the node `n`.
 
-proc intVal*(n: PNimrodNode): BiggestInt {.magic: "NIntVal", noSideEffect.}
-proc floatVal*(n: PNimrodNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
-proc symbol*(n: PNimrodNode): NimSym {.magic: "NSymbol", noSideEffect.}
-proc ident*(n: PNimrodNode): NimIdent {.magic: "NIdent", noSideEffect.}
+proc intVal*(n: NimNode): BiggestInt {.magic: "NIntVal", noSideEffect.}
+proc floatVal*(n: NimNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
+proc symbol*(n: NimNode): NimSym {.magic: "NSymbol", noSideEffect.}
+proc ident*(n: NimNode): NimIdent {.magic: "NIdent", noSideEffect.}
 
-proc getType*(n: PNimrodNode): PNimrodNode {.magic: "NGetType", noSideEffect.}
+proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
   ## with 'getType' you can access the node's `type`:idx:. A Nim type is
   ## mapped to a Nim AST too, so it's slightly confusing but it means the same
   ## API can be used to traverse types. Recursive types are flattened for you
@@ -176,30 +174,30 @@ proc getType*(n: PNimrodNode): PNimrodNode {.magic: "NGetType", noSideEffect.}
   ## resolve recursive types, you have to call 'getType' again. To see what
   ## kind of type it is, call `typeKind` on getType's result.
 
-proc typeKind*(n: PNimrodNode): NimTypeKind {.magic: "NGetType", noSideEffect.}
+proc typeKind*(n: NimNode): NimTypeKind {.magic: "NGetType", noSideEffect.}
   ## Returns the type kind of the node 'n' that should represent a type, that
   ## means the node should have been obtained via `getType`.
 
-proc strVal*(n: PNimrodNode): string  {.magic: "NStrVal", noSideEffect.}
+proc strVal*(n: NimNode): string  {.magic: "NStrVal", noSideEffect.}
 
-proc `intVal=`*(n: PNimrodNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.}
-proc `floatVal=`*(n: PNimrodNode, val: BiggestFloat) {.magic: "NSetFloatVal", noSideEffect.}
-proc `symbol=`*(n: PNimrodNode, val: NimSym) {.magic: "NSetSymbol", noSideEffect.}
-proc `ident=`*(n: PNimrodNode, val: NimIdent) {.magic: "NSetIdent", noSideEffect.}
-#proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".}
+proc `intVal=`*(n: NimNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.}
+proc `floatVal=`*(n: NimNode, val: BiggestFloat) {.magic: "NSetFloatVal", noSideEffect.}
+proc `symbol=`*(n: NimNode, val: NimSym) {.magic: "NSetSymbol", noSideEffect.}
+proc `ident=`*(n: NimNode, val: NimIdent) {.magic: "NSetIdent", noSideEffect.}
+#proc `typ=`*(n: NimNode, typ: typedesc) {.magic: "NSetType".}
 # this is not sound! Unfortunately forbidding 'typ=' is not enough, as you
 # can easily do:
 #   let bracket = semCheck([1, 2])
 #   let fake = semCheck(2.0)
 #   bracket[0] = fake  # constructs a mixed array with ints and floats!
 
-proc `strVal=`*(n: PNimrodNode, val: string) {.magic: "NSetStrVal", noSideEffect.}
+proc `strVal=`*(n: NimNode, val: string) {.magic: "NSetStrVal", noSideEffect.}
 
-proc newNimNode*(kind: TNimrodNodeKind,
-                 n: PNimrodNode=nil): PNimrodNode {.magic: "NNewNimNode", noSideEffect.}
+proc newNimNode*(kind: NimNodeKind,
+                 n: NimNode=nil): NimNode {.magic: "NNewNimNode", noSideEffect.}
 
-proc copyNimNode*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimNode", noSideEffect.}
-proc copyNimTree*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimTree", noSideEffect.}
+proc copyNimNode*(n: NimNode): NimNode {.magic: "NCopyNimNode", noSideEffect.}
+proc copyNimTree*(n: NimNode): NimNode {.magic: "NCopyNimTree", noSideEffect.}
 
 proc error*(msg: string) {.magic: "NError", benign.}
   ## writes an error message at compile time
@@ -210,27 +208,27 @@ proc warning*(msg: string) {.magic: "NWarning", benign.}
 proc hint*(msg: string) {.magic: "NHint", benign.}
   ## writes a hint message at compile time
 
-proc newStrLitNode*(s: string): PNimrodNode {.compileTime, noSideEffect.} =
+proc newStrLitNode*(s: string): NimNode {.compileTime, noSideEffect.} =
   ## creates a string literal node from `s`
   result = newNimNode(nnkStrLit)
   result.strVal = s
 
-proc newIntLitNode*(i: BiggestInt): PNimrodNode {.compileTime.} =
+proc newIntLitNode*(i: BiggestInt): NimNode {.compileTime.} =
   ## creates a int literal node from `i`
   result = newNimNode(nnkIntLit)
   result.intVal = i
 
-proc newFloatLitNode*(f: BiggestFloat): PNimrodNode {.compileTime.} =
+proc newFloatLitNode*(f: BiggestFloat): NimNode {.compileTime.} =
   ## creates a float literal node from `f`
   result = newNimNode(nnkFloatLit)
   result.floatVal = f
 
-proc newIdentNode*(i: NimIdent): PNimrodNode {.compileTime.} =
+proc newIdentNode*(i: NimIdent): NimNode {.compileTime.} =
   ## creates an identifier node from `i`
   result = newNimNode(nnkIdent)
   result.ident = i
 
-proc newIdentNode*(i: string): PNimrodNode {.compileTime.} =
+proc newIdentNode*(i: string): NimNode {.compileTime.} =
   ## creates an identifier node from `i`
   result = newNimNode(nnkIdent)
   result.ident = !i
@@ -247,7 +245,7 @@ type
 
 {.deprecated: [TBindSymRule: BindSymRule].}
 
-proc bindSym*(ident: string, rule: BindSymRule = brClosed): PNimrodNode {.
+proc bindSym*(ident: string, rule: BindSymRule = brClosed): NimNode {.
               magic: "NBindSym", noSideEffect.}
   ## creates a node that binds `ident` to a symbol node. The bound symbol
   ## may be an overloaded symbol.
@@ -258,48 +256,48 @@ proc bindSym*(ident: string, rule: BindSymRule = brClosed): PNimrodNode {.
   ## If ``rule == brForceOpen`` always an ``nkOpenSymChoice`` tree is
   ## returned even if the symbol is not ambiguous.
 
-proc genSym*(kind: NimSymKind = nskLet; ident = ""): PNimrodNode {.
+proc genSym*(kind: NimSymKind = nskLet; ident = ""): NimNode {.
   magic: "NGenSym", noSideEffect.}
   ## generates a fresh symbol that is guaranteed to be unique. The symbol
   ## needs to occur in a declaration context.
 
-proc callsite*(): PNimrodNode {.magic: "NCallSite", benign.}
+proc callsite*(): NimNode {.magic: "NCallSite", benign.}
   ## returns the AST of the invocation expression that invoked this macro.
 
-proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
+proc toStrLit*(n: NimNode): NimNode {.compileTime.} =
   ## converts the AST `n` to the concrete Nim code and wraps that
   ## in a string literal node
   return newStrLitNode(repr(n))
 
-proc lineinfo*(n: PNimrodNode): string {.magic: "NLineInfo", noSideEffect.}
+proc lineinfo*(n: NimNode): string {.magic: "NLineInfo", noSideEffect.}
   ## returns the position the node appears in the original source file
   ## in the form filename(line, col)
 
-proc internalParseExpr(s: string): PNimrodNode {.
+proc internalParseExpr(s: string): NimNode {.
   magic: "ParseExprToAst", noSideEffect.}
 
-proc internalParseStmt(s: string): PNimrodNode {.
+proc internalParseStmt(s: string): NimNode {.
   magic: "ParseStmtToAst", noSideEffect.}
 
 proc internalErrorFlag*(): string {.magic: "NError", noSideEffect.}
   ## Some builtins set an error flag. This is then turned into a proper
   ## exception. **Note**: Ordinary application code should not call this.
 
-proc parseExpr*(s: string): PNimrodNode {.noSideEffect, compileTime.} =
+proc parseExpr*(s: string): NimNode {.noSideEffect, compileTime.} =
   ## Compiles the passed string to its AST representation.
   ## Expects a single expression. Raises ``ValueError`` for parsing errors.
   result = internalParseExpr(s)
   let x = internalErrorFlag()
   if x.len > 0: raise newException(ValueError, x)
 
-proc parseStmt*(s: string): PNimrodNode {.noSideEffect, compileTime.} =
+proc parseStmt*(s: string): NimNode {.noSideEffect, compileTime.} =
   ## Compiles the passed string to its AST representation.
   ## Expects one or more statements. Raises ``ValueError`` for parsing errors.
   result = internalParseStmt(s)
   let x = internalErrorFlag()
   if x.len > 0: raise newException(ValueError, x)
 
-proc getAst*(macroOrTemplate: expr): PNimrodNode {.magic: "ExpandToAst", noSideEffect.}
+proc getAst*(macroOrTemplate: expr): NimNode {.magic: "ExpandToAst", noSideEffect.}
   ## Obtains the AST nodes returned from a macro or template invocation.
   ## Example:
   ##
@@ -308,10 +306,10 @@ proc getAst*(macroOrTemplate: expr): PNimrodNode {.magic: "ExpandToAst", noSideE
   ##   macro FooMacro() =
   ##     var ast = getAst(BarTemplate())
 
-proc quote*(bl: stmt, op = "``"): PNimrodNode {.magic: "QuoteAst", noSideEffect.}
+proc quote*(bl: stmt, op = "``"): NimNode {.magic: "QuoteAst", noSideEffect.}
   ## Quasi-quoting operator.
   ## Accepts an expression or a block and returns the AST that represents it.
-  ## Within the quoted AST, you are able to interpolate PNimrodNode expressions
+  ## Within the quoted AST, you are able to interpolate NimNode expressions
   ## from the surrounding scope. If no operator is given, quoting is done using
   ## backticks. Otherwise, the given operator must be used as a prefix operator
   ## for any interpolated expression. The original meaning of the interpolation
@@ -339,26 +337,26 @@ proc quote*(bl: stmt, op = "``"): PNimrodNode {.magic: "QuoteAst", noSideEffect.
   ##       if not `ex`:
   ##         echo `info` & ": Check failed: " & `expString`
 
-proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} =
+proc expectKind*(n: NimNode, k: NimNodeKind) {.compileTime.} =
   ## checks that `n` is of kind `k`. If this is not the case,
   ## compilation aborts with an error message. This is useful for writing
   ## macros that check the AST that is passed to them.
   if n.kind != k: error("Expected a node of kind " & $k & ", got " & $n.kind)
 
-proc expectMinLen*(n: PNimrodNode, min: int) {.compileTime.} =
+proc expectMinLen*(n: NimNode, min: int) {.compileTime.} =
   ## checks that `n` has at least `min` children. If this is not the case,
   ## compilation aborts with an error message. This is useful for writing
   ## macros that check its number of arguments.
   if n.len < min: error("macro expects a node with " & $min & " children")
 
-proc expectLen*(n: PNimrodNode, len: int) {.compileTime.} =
+proc expectLen*(n: NimNode, len: int) {.compileTime.} =
   ## checks that `n` has exactly `len` children. If this is not the case,
   ## compilation aborts with an error message. This is useful for writing
   ## macros that check its number of arguments.
   if n.len != len: error("macro expects a node with " & $len & " children")
 
-proc newCall*(theProc: PNimrodNode,
-              args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
+proc newCall*(theProc: NimNode,
+              args: varargs[NimNode]): NimNode {.compileTime.} =
   ## produces a new call node. `theProc` is the proc that is called with
   ## the arguments ``args[0..]``.
   result = newNimNode(nnkCall)
@@ -366,7 +364,7 @@ proc newCall*(theProc: PNimrodNode,
   result.add(args)
 
 proc newCall*(theProc: NimIdent,
-              args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
+              args: varargs[NimNode]): NimNode {.compileTime.} =
   ## produces a new call node. `theProc` is the proc that is called with
   ## the arguments ``args[0..]``.
   result = newNimNode(nnkCall)
@@ -374,35 +372,35 @@ proc newCall*(theProc: NimIdent,
   result.add(args)
 
 proc newCall*(theProc: string,
-              args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
+              args: varargs[NimNode]): NimNode {.compileTime.} =
   ## produces a new call node. `theProc` is the proc that is called with
   ## the arguments ``args[0..]``.
   result = newNimNode(nnkCall)
   result.add(newIdentNode(theProc))
   result.add(args)
 
-proc newLit*(c: char): PNimrodNode {.compileTime.} =
+proc newLit*(c: char): NimNode {.compileTime.} =
   ## produces a new character literal node.
   result = newNimNode(nnkCharLit)
   result.intVal = ord(c)
 
-proc newLit*(i: BiggestInt): PNimrodNode {.compileTime.} =
+proc newLit*(i: BiggestInt): NimNode {.compileTime.} =
   ## produces a new integer literal node.
   result = newNimNode(nnkIntLit)
   result.intVal = i
 
-proc newLit*(f: BiggestFloat): PNimrodNode {.compileTime.} =
+proc newLit*(f: BiggestFloat): NimNode {.compileTime.} =
   ## produces a new float literal node.
   result = newNimNode(nnkFloatLit)
   result.floatVal = f
 
-proc newLit*(s: string): PNimrodNode {.compileTime.} =
+proc newLit*(s: string): NimNode {.compileTime.} =
   ## produces a new string literal node.
   result = newNimNode(nnkStrLit)
   result.strVal = s
 
 proc nestList*(theProc: NimIdent,
-               x: PNimrodNode): PNimrodNode {.compileTime.} =
+               x: NimNode): NimNode {.compileTime.} =
   ## nests the list `x` into a tree of call expressions:
   ## ``[a, b, c]`` is transformed into ``theProc(a, theProc(c, d))``.
   var L = x.len
@@ -413,11 +411,11 @@ proc nestList*(theProc: NimIdent,
     # 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, benign.} =
+proc treeRepr*(n: NimNode): 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) {.benign.} =
+  proc traverse(res: var string, level: int, n: NimNode) {.benign.} =
     for i in 0..level-1: res.add "  "
     res.add(($n.kind).substr(3))
 
@@ -438,7 +436,7 @@ proc treeRepr*(n: PNimrodNode): string {.compileTime, benign.} =
   result = ""
   traverse(result, 0, n)
 
-proc lispRepr*(n: PNimrodNode): string {.compileTime, benign.} =
+proc lispRepr*(n: NimNode): string {.compileTime, benign.} =
   ## Convert the AST `n` to a human-readable lisp-like string,
   ##
   ## See also `repr` and `treeRepr`.
@@ -485,56 +483,56 @@ macro dumpLispImm*(s: stmt): stmt {.immediate, deprecated.} = echo s.lispRepr
   ## The ``immediate`` version of `dumpLisp`.
 
 
-proc newEmptyNode*(): PNimrodNode {.compileTime, noSideEffect.} =
+proc newEmptyNode*(): NimNode {.compileTime, noSideEffect.} =
   ## Create a new empty node
   result = newNimNode(nnkEmpty)
 
-proc newStmtList*(stmts: varargs[PNimrodNode]): PNimrodNode {.compileTime.}=
+proc newStmtList*(stmts: varargs[NimNode]): NimNode {.compileTime.}=
   ## Create a new statement list
   result = newNimNode(nnkStmtList).add(stmts)
 
-proc newPar*(exprs: varargs[PNimrodNode]): PNimrodNode {.compileTime.}=
+proc newPar*(exprs: varargs[NimNode]): NimNode {.compileTime.}=
   ## Create a new parentheses-enclosed expression
   newNimNode(nnkPar).add(exprs)
 
-proc newBlockStmt*(label, body: PNimrodNode): PNimrodNode {.compileTime.} =
+proc newBlockStmt*(label, body: NimNode): NimNode {.compileTime.} =
   ## Create a new block statement with label
   return newNimNode(nnkBlockStmt).add(label, body)
 
-proc newBlockStmt*(body: PNimrodNode): PNimrodNode {.compiletime.} =
+proc newBlockStmt*(body: NimNode): NimNode {.compiletime.} =
   ## Create a new block: stmt
   return newNimNode(nnkBlockStmt).add(newEmptyNode(), body)
 
-proc newVarStmt*(name, value: PNimrodNode): PNimrodNode {.compiletime.} =
+proc newVarStmt*(name, value: NimNode): NimNode {.compiletime.} =
   ## Create a new var stmt
   return newNimNode(nnkVarSection).add(
     newNimNode(nnkIdentDefs).add(name, newNimNode(nnkEmpty), value))
 
-proc newLetStmt*(name, value: PNimrodNode): PNimrodNode {.compiletime.} =
+proc newLetStmt*(name, value: NimNode): NimNode {.compiletime.} =
   ## Create a new let stmt
   return newNimNode(nnkLetSection).add(
     newNimNode(nnkIdentDefs).add(name, newNimNode(nnkEmpty), value))
 
-proc newConstStmt*(name, value: PNimrodNode): PNimrodNode {.compileTime.} =
+proc newConstStmt*(name, value: NimNode): NimNode {.compileTime.} =
   ## Create a new const stmt
   newNimNode(nnkConstSection).add(
     newNimNode(nnkConstDef).add(name, newNimNode(nnkEmpty), value))
 
-proc newAssignment*(lhs, rhs: PNimrodNode): PNimrodNode {.compileTime.} =
+proc newAssignment*(lhs, rhs: NimNode): NimNode {.compileTime.} =
   return newNimNode(nnkAsgn).add(lhs, rhs)
 
-proc newDotExpr*(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc newDotExpr*(a, b: NimNode): NimNode {.compileTime.} =
   ## Create new dot expression
   ## a.dot(b) ->  `a.b`
   return newNimNode(nnkDotExpr).add(a, b)
 
-proc newColonExpr*(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc newColonExpr*(a, b: NimNode): NimNode {.compileTime.} =
   ## Create new colon expression
   ## newColonExpr(a, b) ->  `a: b`
   newNimNode(nnkExprColonExpr).add(a, b)
 
-proc newIdentDefs*(name, kind: PNimrodNode;
-                   default = newEmptyNode()): PNimrodNode {.compileTime.} =
+proc newIdentDefs*(name, kind: NimNode;
+                   default = newEmptyNode()): NimNode {.compileTime.} =
   ## Creates a new ``nnkIdentDefs`` node of a specific kind and value.
   ##
   ## ``nnkIdentDefs`` need to have at least three children, but they can have
@@ -565,13 +563,13 @@ proc newIdentDefs*(name, kind: PNimrodNode;
   ##       newStrLitNode("Hello"))
   newNimNode(nnkIdentDefs).add(name, kind, default)
 
-proc newNilLit*(): PNimrodNode {.compileTime.} =
+proc newNilLit*(): NimNode {.compileTime.} =
   ## New nil literal shortcut
   result = newNimNode(nnkNilLit)
 
-proc high*(node: PNimrodNode): int {.compileTime.} = len(node) - 1
+proc high*(node: NimNode): int {.compileTime.} = len(node) - 1
   ## Return the highest index available for a node
-proc last*(node: PNimrodNode): PNimrodNode {.compileTime.} = node[node.high]
+proc last*(node: NimNode): NimNode {.compileTime.} = node[node.high]
   ## Return the last item in nodes children. Same as `node[node.high()]`
 
 
@@ -581,11 +579,11 @@ const
   CallNodes* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
     nnkCallStrLit, nnkHiddenCallConv}
 
-proc expectKind*(n: PNimrodNode; k: set[TNimrodNodeKind]) {.compileTime.} =
+proc expectKind*(n: NimNode; k: set[NimNodeKind]) {.compileTime.} =
   assert n.kind in k, "Expected one of " & $k & ", got " & $n.kind
 
-proc newProc*(name = newEmptyNode(); params: openArray[PNimrodNode] = [newEmptyNode()];
-    body: PNimrodNode = newStmtList(), procType = nnkProcDef): PNimrodNode {.compileTime.} =
+proc newProc*(name = newEmptyNode(); params: openArray[NimNode] = [newEmptyNode()];
+    body: NimNode = newStmtList(), procType = nnkProcDef): NimNode {.compileTime.} =
   ## shortcut for creating a new proc
   ##
   ## The ``params`` array must start with the return type of the proc,
@@ -600,8 +598,8 @@ proc newProc*(name = newEmptyNode(); params: openArray[PNimrodNode] = [newEmptyN
     newEmptyNode(),
     body)
 
-proc newIfStmt*(branches: varargs[tuple[cond, body: PNimrodNode]]):
-                PNimrodNode {.compiletime.} =
+proc newIfStmt*(branches: varargs[tuple[cond, body: NimNode]]):
+                NimNode {.compiletime.} =
   ## Constructor for ``if`` statements.
   ##
   ## .. code-block:: nim
@@ -616,35 +614,35 @@ proc newIfStmt*(branches: varargs[tuple[cond, body: PNimrodNode]]):
     result.add(newNimNode(nnkElifBranch).add(i.cond, i.body))
 
 
-proc copyChildrenTo*(src, dest: PNimrodNode) {.compileTime.}=
+proc copyChildrenTo*(src, dest: NimNode) {.compileTime.}=
   ## Copy all children from `src` to `dest`
   for i in 0 .. < src.len:
     dest.add src[i].copyNimTree
 
-template expectRoutine(node: PNimrodNode): stmt =
+template expectRoutine(node: NimNode): stmt =
   expectKind(node, RoutineNodes)
 
-proc name*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
+proc name*(someProc: NimNode): NimNode {.compileTime.} =
   someProc.expectRoutine
   result = someProc[0]
-proc `name=`*(someProc: PNimrodNode; val: PNimrodNode) {.compileTime.} =
+proc `name=`*(someProc: NimNode; val: NimNode) {.compileTime.} =
   someProc.expectRoutine
   someProc[0] = val
 
-proc params*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
+proc params*(someProc: NimNode): NimNode {.compileTime.} =
   someProc.expectRoutine
   result = someProc[3]
-proc `params=`* (someProc: PNimrodNode; params: PNimrodNode) {.compileTime.}=
+proc `params=`* (someProc: NimNode; params: NimNode) {.compileTime.}=
   someProc.expectRoutine
   assert params.kind == nnkFormalParams
   someProc[3] = params
 
-proc pragma*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
+proc pragma*(someProc: NimNode): NimNode {.compileTime.} =
   ## Get the pragma of a proc type
   ## These will be expanded
   someProc.expectRoutine
   result = someProc[4]
-proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}=
+proc `pragma=`*(someProc: NimNode; val: NimNode){.compileTime.}=
   ## Set the pragma of a proc type
   someProc.expectRoutine
   assert val.kind in {nnkEmpty, nnkPragma}
@@ -654,7 +652,7 @@ proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}=
 template badNodeKind(k; f): stmt{.immediate.} =
   assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`"
 
-proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
+proc body*(someProc: NimNode): NimNode {.compileTime.} =
   case someProc.kind:
   of RoutineNodes:
     return someProc[6]
@@ -665,7 +663,7 @@ proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
   else:
     badNodeKind someProc.kind, "body"
 
-proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} =
+proc `body=`*(someProc: NimNode, val: NimNode) {.compileTime.} =
   case someProc.kind
   of RoutineNodes:
     someProc[6] = val
@@ -676,10 +674,10 @@ proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} =
   else:
     badNodeKind someProc.kind, "body="
 
-proc basename*(a: PNimrodNode): PNimrodNode {.compiletime, benign.}
+proc basename*(a: NimNode): NimNode {.compiletime, benign.}
 
 
-proc `$`*(node: PNimrodNode): string {.compileTime.} =
+proc `$`*(node: NimNode): string {.compileTime.} =
   ## Get the string of an identifier node
   case node.kind
   of nnkIdent:
@@ -693,14 +691,14 @@ proc `$`*(node: PNimrodNode): string {.compileTime.} =
   else:
     badNodeKind node.kind, "$"
 
-proc ident*(name: string): PNimrodNode {.compileTime,inline.} = newIdentNode(name)
+proc ident*(name: string): NimNode {.compileTime,inline.} = newIdentNode(name)
   ## Create a new ident node from a string
 
-iterator children*(n: PNimrodNode): PNimrodNode {.inline.}=
+iterator children*(n: NimNode): NimNode {.inline.}=
   for i in 0 .. high(n):
     yield n[i]
 
-template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {.
+template findChild*(n: NimNode; cond: expr): NimNode {.
   immediate, dirty.} =
   ## Find the first child node matching condition (or nil).
   ##
@@ -708,14 +706,14 @@ template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {.
   ##   var res = findChild(n, it.kind == nnkPostfix and
   ##                          it.basename.ident == !"foo")
   block:
-    var result: PNimrodNode
+    var result: NimNode
     for it in n.children:
       if cond:
         result = it
         break
     result
 
-proc insert*(a: PNimrodNode; pos: int; b: PNimrodNode) {.compileTime.} =
+proc insert*(a: NimNode; pos: int; b: NimNode) {.compileTime.} =
   ## Insert node B into A at pos
   if high(a) < pos:
     ## add some empty nodes first
@@ -730,7 +728,7 @@ proc insert*(a: PNimrodNode; pos: int; b: PNimrodNode) {.compileTime.} =
       a[i + 1] = a[i]
     a[pos] = b
 
-proc basename*(a: PNimrodNode): PNimrodNode =
+proc basename*(a: NimNode): NimNode =
   ## Pull an identifier from prefix/postfix expressions
   case a.kind
   of nnkIdent: return a
@@ -738,39 +736,39 @@ proc basename*(a: PNimrodNode): PNimrodNode =
   else:
     quit "Do not know how to get basename of ("& treeRepr(a) &")\n"& repr(a)
 
-proc `basename=`*(a: PNimrodNode; val: string) {.compileTime.}=
+proc `basename=`*(a: NimNode; val: string) {.compileTime.}=
   case a.kind
   of nnkIdent: macros.`ident=`(a,  !val)
   of nnkPostfix, nnkPrefix: a[1] = ident(val)
   else:
     quit "Do not know how to get basename of ("& treeRepr(a)& ")\n"& repr(a)
 
-proc postfix*(node: PNimrodNode; op: string): PNimrodNode {.compileTime.} =
+proc postfix*(node: NimNode; op: string): NimNode {.compileTime.} =
   newNimNode(nnkPostfix).add(ident(op), node)
 
-proc prefix*(node: PNimrodNode; op: string): PNimrodNode {.compileTime.} =
+proc prefix*(node: NimNode; op: string): NimNode {.compileTime.} =
   newNimNode(nnkPrefix).add(ident(op), node)
 
-proc infix*(a: PNimrodNode; op: string;
-            b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc infix*(a: NimNode; op: string;
+            b: NimNode): NimNode {.compileTime.} =
   newNimNode(nnkInfix).add(ident(op), a, b)
 
-proc unpackPostfix*(node: PNimrodNode): tuple[node: PNimrodNode; op: string] {.
+proc unpackPostfix*(node: NimNode): tuple[node: NimNode; op: string] {.
   compileTime.} =
   node.expectKind nnkPostfix
   result = (node[0], $node[1])
 
-proc unpackPrefix*(node: PNimrodNode): tuple[node: PNimrodNode; op: string] {.
+proc unpackPrefix*(node: NimNode): tuple[node: NimNode; op: string] {.
   compileTime.} =
   node.expectKind nnkPrefix
   result = (node[0], $node[1])
 
-proc unpackInfix*(node: PNimrodNode): tuple[left: PNimrodNode; op: string;
-                                        right: PNimrodNode] {.compileTime.} =
+proc unpackInfix*(node: NimNode): tuple[left: NimNode; op: string;
+                                        right: NimNode] {.compileTime.} =
   assert node.kind == nnkInfix
   result = (node[0], $node[1], node[2])
 
-proc copy*(node: PNimrodNode): PNimrodNode {.compileTime.} =
+proc copy*(node: NimNode): NimNode {.compileTime.} =
   ## An alias for copyNimTree().
   return node.copyNimTree()
 
@@ -793,7 +791,7 @@ proc cmpIgnoreStyle(a, b: cstring): int {.noSideEffect.} =
 proc eqIdent* (a, b: string): bool = cmpIgnoreStyle(a, b) == 0
   ## Check if two idents are identical.
 
-proc hasArgOfName* (params: PNimrodNode; name: string): bool {.compiletime.}=
+proc hasArgOfName* (params: NimNode; name: string): bool {.compiletime.}=
   ## Search nnkFormalParams for an argument.
   assert params.kind == nnkFormalParams
   for i in 1 .. <params.len:
@@ -801,7 +799,7 @@ proc hasArgOfName* (params: PNimrodNode; name: string): bool {.compiletime.}=
     if name.eqIdent( $ node[0]):
       return true
 
-proc addIdentIfAbsent*(dest: PNimrodNode, ident: string) {.compiletime.} =
+proc addIdentIfAbsent*(dest: NimNode, ident: string) {.compiletime.} =
   ## Add ident to dest if it is not present. This is intended for use
   ## with pragmas.
   for node in dest.children:
@@ -825,5 +823,3 @@ when not defined(booting):
     macro payload: stmt {.gensym.} =
       result = parseStmt(e)
     payload()
-
-{.pop.}
diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim
index dab84c2d5..b8180cd87 100644
--- a/lib/impure/db_mysql.nim
+++ b/lib/impure/db_mysql.nim
@@ -229,3 +229,9 @@ proc open*(connection, user, password, database: string): TDbConn {.
     var errmsg = $mysql.error(result)
     db_mysql.close(result)
     dbError(errmsg)
+
+proc setEncoding*(connection: TDbConn, encoding: string): bool {.
+  tags: [FDb].} =
+  ## sets the encoding of a database connection, returns true for 
+  ## success, false for failure.
+  result = mysql.set_character_set(connection, encoding) == 0
\ No newline at end of file
diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim
index d8ccc4c16..ffb8bbcda 100644
--- a/lib/impure/db_postgres.nim
+++ b/lib/impure/db_postgres.nim
@@ -260,3 +260,9 @@ proc open*(connection, user, password, database: string): TDbConn {.
   ## the nim db api.
   result = pqsetdbLogin(nil, nil, nil, nil, database, user, password)
   if pqStatus(result) != CONNECTION_OK: dbError(result) # result = nil
+
+proc setEncoding*(connection: TDbConn, encoding: string): bool {.
+  tags: [FDb].} =
+  ## sets the encoding of a database connection, returns true for 
+  ## success, false for failure.
+  return pqsetClientEncoding(connection, encoding) == 0
\ No newline at end of file
diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim
index bf1ce75ef..4be692f39 100644
--- a/lib/impure/db_sqlite.nim
+++ b/lib/impure/db_sqlite.nim
@@ -192,7 +192,19 @@ proc open*(connection, user, password, database: string): TDbConn {.
     result = db
   else:
     dbError(db)
-   
+
+proc setEncoding*(connection: TDbConn, encoding: string): bool {.
+  tags: [FDb].} =
+  ## sets the encoding of a database connection, returns true for 
+  ## success, false for failure.
+  ##
+  ## Note that the encoding cannot be changed once it's been set.
+  ## According to SQLite3 documentation, any attempt to change 
+  ## the encoding after the database is created will be silently 
+  ## ignored.
+  exec(connection, sql"PRAGMA encoding = ?", [encoding])
+  result = connection.getValue(sql"PRAGMA encoding") == encoding
+
 when isMainModule:
   var db = open("db.sql", "", "", "")
   exec(db, sql"create table tbl1(one varchar(10), two smallint)", [])
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index a8caf809e..8e0ac8d21 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -1064,13 +1064,13 @@ proc accept*(socket: TAsyncFD,
 
 # -- Await Macro
 
-proc skipUntilStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
+proc skipUntilStmtList(node: NimNode): NimNode {.compileTime.} =
   # Skips a nest of StmtList's.
   result = node
   if node[0].kind == nnkStmtList:
     result = skipUntilStmtList(node[0])
 
-proc skipStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
+proc skipStmtList(node: NimNode): NimNode {.compileTime.} =
   result = node
   if node[0].kind == nnkStmtList:
     result = node[0]
@@ -1098,11 +1098,11 @@ template createCb(retFutureSym, iteratorNameSym,
   cb()
   #{.pop.}
 proc generateExceptionCheck(futSym,
-    tryStmt, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} =
+    tryStmt, rootReceiver, fromNode: NimNode): NimNode {.compileTime.} =
   if tryStmt.kind == nnkNilLit:
     result = rootReceiver
   else:
-    var exceptionChecks: seq[tuple[cond, body: PNimrodNode]] = @[]
+    var exceptionChecks: seq[tuple[cond, body: NimNode]] = @[]
     let errorNode = newDotExpr(futSym, newIdentNode("error"))
     for i in 1 .. <tryStmt.len:
       let exceptBranch = tryStmt[i]
@@ -1110,7 +1110,7 @@ proc generateExceptionCheck(futSym,
         exceptionChecks.add((newIdentNode("true"), exceptBranch[0]))
       else:
         var exceptIdentCount = 0
-        var ifCond: PNimrodNode
+        var ifCond: NimNode
         for i in 0 .. <exceptBranch.len:
           let child = exceptBranch[i]
           if child.kind == nnkIdent:
@@ -1144,10 +1144,10 @@ proc generateExceptionCheck(futSym,
     )
     result.add elseNode
 
-template createVar(result: var PNimrodNode, futSymName: string,
-                   asyncProc: PNimrodNode,
+template createVar(result: var NimNode, futSymName: string,
+                   asyncProc: NimNode,
                    valueReceiver, rootReceiver: expr,
-                   fromNode: PNimrodNode) =
+                   fromNode: NimNode) =
   result = newNimNode(nnkStmtList, fromNode)
   var futSym = genSym(nskVar, "future")
   result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y
@@ -1155,9 +1155,9 @@ template createVar(result: var PNimrodNode, futSymName: string,
   valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future<x>.read
   result.add generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode)
 
-proc processBody(node, retFutureSym: PNimrodNode,
+proc processBody(node, retFutureSym: NimNode,
                  subTypeIsVoid: bool,
-                 tryStmt: PNimrodNode): PNimrodNode {.compileTime.} =
+                 tryStmt: NimNode): NimNode {.compileTime.} =
   #echo(node.treeRepr)
   result = node
   case node.kind
@@ -1183,7 +1183,7 @@ proc processBody(node, retFutureSym: PNimrodNode,
         result = newNimNode(nnkYieldStmt, node).add(node[1]) # -> yield x
       of nnkCall, nnkCommand:
         # await foo(p, x)
-        var futureValue: PNimrodNode
+        var futureValue: NimNode
         result.createVar("future" & $node[1][0].toStrLit, node[1], futureValue,
                   futureValue, node)
       else:
@@ -1232,8 +1232,8 @@ proc processBody(node, retFutureSym: PNimrodNode,
       # working in ``except``?
       tryBody[1] = processBody(n[1], retFutureSym, subTypeIsVoid, nil)
 
-    proc processForTry(n: PNimrodNode, i: var int,
-                       res: PNimrodNode): bool {.compileTime.} =
+    proc processForTry(n: NimNode, i: var int,
+                       res: NimNode): bool {.compileTime.} =
       ## Transforms the body of the tryStmt. Does not transform the
       ## body in ``except``.
       ## Returns true if the tryStmt node was transformed into an ifStmt.
@@ -1275,7 +1275,7 @@ proc processBody(node, retFutureSym: PNimrodNode,
   for i in 0 .. <result.len:
     result[i] = processBody(result[i], retFutureSym, subTypeIsVoid, tryStmt)
 
-proc getName(node: PNimrodNode): string {.compileTime.} =
+proc getName(node: NimNode): string {.compileTime.} =
   case node.kind
   of nnkPostfix:
     return $node[1].ident
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 93a7591ac..feb965af3 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -95,12 +95,12 @@ proc len*[A, B](t: Table[A, B]): int =
   ## returns the number of keys in `t`.
   result = t.counter
 
-iterator pairs*[A, B](t: Table[A, B]): tuple[key: A, val: B] =
+iterator pairs*[A, B](t: Table[A, B]): (A, B) =
   ## iterates over any (key, value) pair in the table `t`.
   for h in 0..high(t.data):
     if isFilled(t.data[h].hcode): yield (t.data[h].key, t.data[h].val)
 
-iterator mpairs*[A, B](t: var Table[A, B]): tuple[key: A, val: var B] =
+iterator mpairs*[A, B](t: var Table[A, B]): (A, var B) =
   ## iterates over any (key, value) pair in the table `t`. The values
   ## can be modified.
   for h in 0..high(t.data):
@@ -314,8 +314,8 @@ proc initTable*[A, B](initialSize=64): Table[A, B] =
   result.counter = 0
   newSeq(result.data, initialSize)
 
-proc toTable*[A, B](pairs: openArray[tuple[key: A, 
-                    val: B]]): Table[A, B] =
+proc toTable*[A, B](pairs: openArray[(A, 
+                    B)]): Table[A, B] =
   ## creates a new hash table that contains the given `pairs`.
   result = initTable[A, B](rightSize(pairs.len))
   for key, val in items(pairs): result[key] = val
@@ -360,12 +360,12 @@ proc len*[A, B](t: TableRef[A, B]): int =
   ## returns the number of keys in `t`.
   result = t.counter
 
-iterator pairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: B] =
+iterator pairs*[A, B](t: TableRef[A, B]): (A, B) =
   ## iterates over any (key, value) pair in the table `t`.
   for h in 0..high(t.data):
     if isFilled(t.data[h].hcode): yield (t.data[h].key, t.data[h].val)
 
-iterator mpairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: var B] =
+iterator mpairs*[A, B](t: TableRef[A, B]): (A, var B) =
   ## iterates over any (key, value) pair in the table `t`. The values
   ## can be modified.
   for h in 0..high(t.data):
@@ -427,7 +427,7 @@ proc newTable*[A, B](initialSize=64): TableRef[A, B] =
   new(result)
   result[] = initTable[A, B](initialSize)
 
-proc newTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): TableRef[A, B] =
+proc newTable*[A, B](pairs: openArray[(A, B)]): TableRef[A, B] =
   ## creates a new hash table that contains the given `pairs`.
   new(result)
   result[] = toTable[A, B](pairs)
@@ -473,13 +473,13 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
     if isFilled(t.data[h].hcode): yieldStmt
     h = nxt
 
-iterator pairs*[A, B](t: OrderedTable[A, B]): tuple[key: A, val: B] =
+iterator pairs*[A, B](t: OrderedTable[A, B]): (A, B) =
   ## iterates over any (key, value) pair in the table `t` in insertion
   ## order.
   forAllOrderedPairs:
     yield (t.data[h].key, t.data[h].val)
 
-iterator mpairs*[A, B](t: var OrderedTable[A, B]): tuple[key: A, val: var B] =
+iterator mpairs*[A, B](t: var OrderedTable[A, B]): (A, var B) =
   ## iterates over any (key, value) pair in the table `t` in insertion
   ## order. The values can be modified.
   forAllOrderedPairs:
@@ -584,8 +584,8 @@ proc initOrderedTable*[A, B](initialSize=64): OrderedTable[A, B] =
   result.last = -1
   newSeq(result.data, initialSize)
 
-proc toOrderedTable*[A, B](pairs: openArray[tuple[key: A, 
-                           val: B]]): OrderedTable[A, B] =
+proc toOrderedTable*[A, B](pairs: openArray[(A, 
+                           B)]): OrderedTable[A, B] =
   ## creates a new ordered hash table that contains the given `pairs`.
   result = initOrderedTable[A, B](rightSize(pairs.len))
   for key, val in items(pairs): result[key] = val
@@ -595,7 +595,7 @@ proc `$`*[A, B](t: OrderedTable[A, B]): string =
   dollarImpl()
 
 proc sort*[A, B](t: var OrderedTable[A, B], 
-                 cmp: proc (x,y: tuple[key: A, val: B]): int) =
+                 cmp: proc (x,y: (A, B)): int) =
   ## sorts `t` according to `cmp`. This modifies the internal list
   ## that kept the insertion order, so insertion order is lost after this
   ## call but key lookup and insertions remain possible after `sort` (in
@@ -651,13 +651,13 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
     if isFilled(t.data[h].hcode): yieldStmt
     h = nxt
 
-iterator pairs*[A, B](t: OrderedTableRef[A, B]): tuple[key: A, val: B] =
+iterator pairs*[A, B](t: OrderedTableRef[A, B]): (A, B) =
   ## iterates over any (key, value) pair in the table `t` in insertion
   ## order.
   forAllOrderedPairs:
     yield (t.data[h].key, t.data[h].val)
 
-iterator mpairs*[A, B](t: OrderedTableRef[A, B]): tuple[key: A, val: var B] =
+iterator mpairs*[A, B](t: OrderedTableRef[A, B]): (A, var B) =
   ## iterates over any (key, value) pair in the table `t` in insertion
   ## order. The values can be modified.
   forAllOrderedPairs:
@@ -721,8 +721,7 @@ proc newOrderedTable*[A, B](initialSize=64): OrderedTableRef[A, B] =
   new(result)
   result[] = initOrderedTable[A, B]()
 
-proc newOrderedTable*[A, B](pairs: openArray[tuple[key: A, 
-                           val: B]]): OrderedTableRef[A, B] =
+proc newOrderedTable*[A, B](pairs: openArray[(A, B)]): OrderedTableRef[A, B] =
   ## creates a new ordered hash table that contains the given `pairs`.
   result = newOrderedTable[A, B](rightSize(pairs.len))
   for key, val in items(pairs): result[key] = val
@@ -732,7 +731,7 @@ proc `$`*[A, B](t: OrderedTableRef[A, B]): string =
   dollarImpl()
 
 proc sort*[A, B](t: OrderedTableRef[A, B], 
-                 cmp: proc (x,y: tuple[key: A, val: B]): int) =
+                 cmp: proc (x,y: (A, B)): int) =
   ## sorts `t` according to `cmp`. This modifies the internal list
   ## that kept the insertion order, so insertion order is lost after this
   ## call but key lookup and insertions remain possible after `sort` (in
@@ -754,12 +753,12 @@ proc len*[A](t: CountTable[A]): int =
   ## returns the number of keys in `t`.
   result = t.counter
 
-iterator pairs*[A](t: CountTable[A]): tuple[key: A, val: int] =
+iterator pairs*[A](t: CountTable[A]): (A, int) =
   ## iterates over any (key, value) pair in the table `t`.
   for h in 0..high(t.data):
     if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val)
 
-iterator mpairs*[A](t: var CountTable[A]): tuple[key: A, val: var int] =
+iterator mpairs*[A](t: var CountTable[A]): (A, var int) =
   ## iterates over any (key, value) pair in the table `t`. The values can
   ## be modified.
   for h in 0..high(t.data):
@@ -902,12 +901,12 @@ proc len*[A](t: CountTableRef[A]): int =
   ## returns the number of keys in `t`.
   result = t.counter
 
-iterator pairs*[A](t: CountTableRef[A]): tuple[key: A, val: int] =
+iterator pairs*[A](t: CountTableRef[A]): (A, int) =
   ## iterates over any (key, value) pair in the table `t`.
   for h in 0..high(t.data):
     if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val)
 
-iterator mpairs*[A](t: CountTableRef[A]): tuple[key: A, val: var int] =
+iterator mpairs*[A](t: CountTableRef[A]): (A, var int) =
   ## iterates over any (key, value) pair in the table `t`. The values can
   ## be modified.
   for h in 0..high(t.data):
@@ -970,11 +969,11 @@ proc inc*[A](t: CountTableRef[A], key: A, val = 1) =
   ## increments `t[key]` by `val`.
   t[].inc(key, val)
 
-proc smallest*[A](t: CountTableRef[A]): tuple[key: A, val: int] =
+proc smallest*[A](t: CountTableRef[A]): (A, int) =
   ## returns the largest (key,val)-pair. Efficiency: O(n)
   t[].smallest
 
-proc largest*[A](t: CountTableRef[A]): tuple[key: A, val: int] =
+proc largest*[A](t: CountTableRef[A]): (A, int) =
   ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n)
   t[].largest
 
diff --git a/lib/pure/future.nim b/lib/pure/future.nim
index 05f25d29f..661afd7b3 100644
--- a/lib/pure/future.nim
+++ b/lib/pure/future.nim
@@ -12,7 +12,7 @@
 
 import macros
 
-proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
   #echo treeRepr(p)
   #echo treeRepr(b)
   result = newNimNode(nnkProcTy)
@@ -44,7 +44,7 @@ proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
     formalParams.add identDefs
   else:
     error("Incorrect type list in proc type declaration.")
-  
+
   result.add formalParams
   result.add newEmptyNode()
   #echo(treeRepr(result))
@@ -59,10 +59,10 @@ macro `=>`*(p, b: expr): expr {.immediate.} =
   ##     f(2, 2)
   ##
   ##   passTwoAndTwo((x, y) => x + y) # 4
-  
+
   #echo treeRepr(p)
   #echo(treeRepr(b))
-  var params: seq[PNimrodNode] = @[newIdentNode("auto")]
+  var params: seq[NimNode] = @[newIdentNode("auto")]
 
   case p.kind
   of nnkPar:
@@ -118,7 +118,7 @@ macro `->`*(p, b: expr): expr {.immediate.} =
   ##
   ##   proc pass2(f: (float, float) -> float): float =
   ##     f(2, 2)
-  ##   
+  ##
   ##   # is the same as:
   ##
   ##   proc pass2(f: proc (x, y: float): float): float =
diff --git a/lib/pure/htmlgen.nim b/lib/pure/htmlgen.nim
index aeb93bebe..d712e53f3 100644
--- a/lib/pure/htmlgen.nim
+++ b/lib/pure/htmlgen.nim
@@ -12,7 +12,7 @@
 ## as ``from htmlgen import nil`` and then fully qualify the macros.
 ##
 ##
-## This module implements a simple `XML`:idx: and `HTML`:idx: code 
+## This module implements a simple `XML`:idx: and `HTML`:idx: code
 ## generator. Each commonly used HTML tag has a corresponding macro
 ## that generates a string with its HTML representation.
 ##
@@ -21,9 +21,9 @@
 ## .. code-block:: Nim
 ##   var nim = "Nim"
 ##   echo h1(a(href="http://nim-lang.org", nim))
-##  
+##
 ## Writes the string::
-##   
+##
 ##   <h1><a href="http://nim-lang.org">Nim</a></h1>
 ##
 
@@ -36,16 +36,16 @@ const
     "onmouseover onmousemove onmouseout onkeypress onkeydown onkeyup "
   commonAttr* = coreAttr & eventAttr
 
-proc getIdent(e: PNimrodNode): string {.compileTime.} = 
+proc getIdent(e: NimNode): string {.compileTime.} =
   case e.kind
   of nnkIdent: result = normalize($e.ident)
-  of nnkAccQuoted: 
+  of nnkAccQuoted:
     result = getIdent(e[0])
     for i in 1 .. e.len-1:
       result.add getIdent(e[i])
   else: error("cannot extract identifier from node: " & toStrLit(e).strVal)
 
-proc delete[T](s: var seq[T], attr: T): bool = 
+proc delete[T](s: var seq[T], attr: T): bool =
   var idx = find(s, attr)
   if idx >= 0:
     var L = s.len
@@ -53,10 +53,10 @@ proc delete[T](s: var seq[T], attr: T): bool =
     setLen(s, L-1)
     result = true
 
-proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
-    isLeaf = false): PNimrodNode {.compileTime.} =
+proc xmlCheckedTag*(e: NimNode, tag: string, optAttr = "", reqAttr = "",
+    isLeaf = false): NimNode {.compileTime.} =
   ## use this procedure to define a new XML tag
-  
+
   # copy the attributes; when iterating over them these lists
   # will be modified, so that each attribute is only given one value
   var req = split(reqAttr)
@@ -66,7 +66,7 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
   result.add(newStrLitNode(tag))
   # first pass over attributes:
   for i in 1..e.len-1:
-    if e[i].kind == nnkExprEqExpr: 
+    if e[i].kind == nnkExprEqExpr:
       var name = getIdent(e[i][0])
       if delete(req, name) or delete(opt, name):
         result.add(newStrLitNode(" "))
@@ -81,7 +81,7 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
     error(req[0] & " attribute for '" & tag & "' element expected")
   if isLeaf:
     for i in 1..e.len-1:
-      if e[i].kind != nnkExprEqExpr: 
+      if e[i].kind != nnkExprEqExpr:
         error("element " & tag & " cannot be nested")
     result.add(newStrLitNode(" />"))
   else:
@@ -95,389 +95,389 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
   result = nestList(!"&", result)
 
 
-macro a*(e: expr): expr {.immediate.} = 
+macro a*(e: expr): expr {.immediate.} =
   ## generates the HTML ``a`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "a", "href charset type hreflang rel rev " &
     "accesskey tabindex" & commonAttr)
 
-macro acronym*(e: expr): expr {.immediate.} = 
+macro acronym*(e: expr): expr {.immediate.} =
   ## generates the HTML ``acronym`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "acronym", commonAttr)
 
-macro address*(e: expr): expr {.immediate.} = 
+macro address*(e: expr): expr {.immediate.} =
   ## generates the HTML ``address`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "address", commonAttr)
 
-macro area*(e: expr): expr {.immediate.} = 
+macro area*(e: expr): expr {.immediate.} =
   ## generates the HTML ``area`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "area", "shape coords href nohref" &
     " accesskey tabindex" & commonAttr, "alt", true)
 
-macro b*(e: expr): expr {.immediate.} = 
+macro b*(e: expr): expr {.immediate.} =
   ## generates the HTML ``b`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "b", commonAttr)
 
-macro base*(e: expr): expr {.immediate.} = 
+macro base*(e: expr): expr {.immediate.} =
   ## generates the HTML ``base`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "base", "", "href", true)
 
-macro big*(e: expr): expr {.immediate.} = 
+macro big*(e: expr): expr {.immediate.} =
   ## generates the HTML ``big`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "big", commonAttr)
 
-macro blockquote*(e: expr): expr {.immediate.} = 
+macro blockquote*(e: expr): expr {.immediate.} =
   ## generates the HTML ``blockquote`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "blockquote", " cite" & commonAttr)
 
-macro body*(e: expr): expr {.immediate.} = 
+macro body*(e: expr): expr {.immediate.} =
   ## generates the HTML ``body`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "body", commonAttr)
 
-macro br*(e: expr): expr {.immediate.} = 
+macro br*(e: expr): expr {.immediate.} =
   ## generates the HTML ``br`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "br", "", "", true)
 
-macro button*(e: expr): expr {.immediate.} = 
+macro button*(e: expr): expr {.immediate.} =
   ## generates the HTML ``button`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "button", "accesskey tabindex " &
     "disabled name type value" & commonAttr)
 
-macro caption*(e: expr): expr {.immediate.} = 
+macro caption*(e: expr): expr {.immediate.} =
   ## generates the HTML ``caption`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "caption", commonAttr)
 
-macro cite*(e: expr): expr {.immediate.} = 
+macro cite*(e: expr): expr {.immediate.} =
   ## generates the HTML ``cite`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "cite", commonAttr)
 
-macro code*(e: expr): expr {.immediate.} = 
+macro code*(e: expr): expr {.immediate.} =
   ## generates the HTML ``code`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "code", commonAttr)
 
-macro col*(e: expr): expr {.immediate.} = 
+macro col*(e: expr): expr {.immediate.} =
   ## generates the HTML ``col`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "col", "span align valign" & commonAttr, "", true)
 
-macro colgroup*(e: expr): expr {.immediate.} = 
+macro colgroup*(e: expr): expr {.immediate.} =
   ## generates the HTML ``colgroup`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "colgroup", "span align valign" & commonAttr)
 
-macro dd*(e: expr): expr {.immediate.} = 
+macro dd*(e: expr): expr {.immediate.} =
   ## generates the HTML ``dd`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "dd", commonAttr)
 
-macro del*(e: expr): expr {.immediate.} = 
+macro del*(e: expr): expr {.immediate.} =
   ## generates the HTML ``del`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "del", "cite datetime" & commonAttr)
 
-macro dfn*(e: expr): expr {.immediate.} = 
+macro dfn*(e: expr): expr {.immediate.} =
   ## generates the HTML ``dfn`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "dfn", commonAttr)
 
-macro `div`*(e: expr): expr {.immediate.} = 
+macro `div`*(e: expr): expr {.immediate.} =
   ## generates the HTML ``div`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "div", commonAttr)
 
-macro dl*(e: expr): expr {.immediate.} = 
+macro dl*(e: expr): expr {.immediate.} =
   ## generates the HTML ``dl`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "dl", commonAttr)
 
-macro dt*(e: expr): expr {.immediate.} = 
+macro dt*(e: expr): expr {.immediate.} =
   ## generates the HTML ``dt`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "dt", commonAttr)
 
-macro em*(e: expr): expr {.immediate.} = 
+macro em*(e: expr): expr {.immediate.} =
   ## generates the HTML ``em`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "em", commonAttr)
 
-macro fieldset*(e: expr): expr {.immediate.} = 
+macro fieldset*(e: expr): expr {.immediate.} =
   ## generates the HTML ``fieldset`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "fieldset", commonAttr)
 
-macro form*(e: expr): expr {.immediate.} = 
+macro form*(e: expr): expr {.immediate.} =
   ## generates the HTML ``form`` element.
   let e = callsite()
-  result = xmlCheckedTag(e, "form", "method encype accept accept-charset" & 
+  result = xmlCheckedTag(e, "form", "method encype accept accept-charset" &
     commonAttr, "action")
 
-macro h1*(e: expr): expr {.immediate.} = 
+macro h1*(e: expr): expr {.immediate.} =
   ## generates the HTML ``h1`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "h1", commonAttr)
 
-macro h2*(e: expr): expr {.immediate.} = 
+macro h2*(e: expr): expr {.immediate.} =
   ## generates the HTML ``h2`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "h2", commonAttr)
 
-macro h3*(e: expr): expr {.immediate.} = 
+macro h3*(e: expr): expr {.immediate.} =
   ## generates the HTML ``h3`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "h3", commonAttr)
 
-macro h4*(e: expr): expr {.immediate.} = 
+macro h4*(e: expr): expr {.immediate.} =
   ## generates the HTML ``h4`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "h4", commonAttr)
 
-macro h5*(e: expr): expr {.immediate.} = 
+macro h5*(e: expr): expr {.immediate.} =
   ## generates the HTML ``h5`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "h5", commonAttr)
 
-macro h6*(e: expr): expr {.immediate.} = 
+macro h6*(e: expr): expr {.immediate.} =
   ## generates the HTML ``h6`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "h6", commonAttr)
 
-macro head*(e: expr): expr {.immediate.} = 
+macro head*(e: expr): expr {.immediate.} =
   ## generates the HTML ``head`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "head", "profile")
 
-macro html*(e: expr): expr {.immediate.} = 
+macro html*(e: expr): expr {.immediate.} =
   ## generates the HTML ``html`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "html", "xmlns", "")
 
-macro hr*(): expr {.immediate.} = 
+macro hr*(): expr {.immediate.} =
   ## generates the HTML ``hr`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "hr", commonAttr, "", true)
 
-macro i*(e: expr): expr {.immediate.} = 
+macro i*(e: expr): expr {.immediate.} =
   ## generates the HTML ``i`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "i", commonAttr)
 
-macro img*(e: expr): expr {.immediate.} = 
+macro img*(e: expr): expr {.immediate.} =
   ## generates the HTML ``img`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "img", "longdesc height width", "src alt", true)
 
-macro input*(e: expr): expr {.immediate.} = 
+macro input*(e: expr): expr {.immediate.} =
   ## generates the HTML ``input`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "input", "name type value checked maxlength src" &
     " alt accept disabled readonly accesskey tabindex" & commonAttr, "", true)
 
-macro ins*(e: expr): expr {.immediate.} = 
+macro ins*(e: expr): expr {.immediate.} =
   ## generates the HTML ``ins`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "ins", "cite datetime" & commonAttr)
 
-macro kbd*(e: expr): expr {.immediate.} = 
+macro kbd*(e: expr): expr {.immediate.} =
   ## generates the HTML ``kbd`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "kbd", commonAttr)
 
-macro label*(e: expr): expr {.immediate.} = 
+macro label*(e: expr): expr {.immediate.} =
   ## generates the HTML ``label`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "label", "for accesskey" & commonAttr)
 
-macro legend*(e: expr): expr {.immediate.} = 
+macro legend*(e: expr): expr {.immediate.} =
   ## generates the HTML ``legend`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "legend", "accesskey" & commonAttr)
 
-macro li*(e: expr): expr {.immediate.} = 
+macro li*(e: expr): expr {.immediate.} =
   ## generates the HTML ``li`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "li", commonAttr)
 
-macro link*(e: expr): expr {.immediate.} = 
+macro link*(e: expr): expr {.immediate.} =
   ## generates the HTML ``link`` element.
   let e = callsite()
-  result = xmlCheckedTag(e, "link", "href charset hreflang type rel rev media" & 
+  result = xmlCheckedTag(e, "link", "href charset hreflang type rel rev media" &
     commonAttr, "", true)
 
-macro map*(e: expr): expr {.immediate.} = 
+macro map*(e: expr): expr {.immediate.} =
   ## generates the HTML ``map`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "map", "class title" & eventAttr, "id", false)
 
-macro meta*(e: expr): expr {.immediate.} = 
+macro meta*(e: expr): expr {.immediate.} =
   ## generates the HTML ``meta`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "meta", "name http-equiv scheme", "content", true)
 
-macro noscript*(e: expr): expr {.immediate.} = 
+macro noscript*(e: expr): expr {.immediate.} =
   ## generates the HTML ``noscript`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "noscript", commonAttr)
 
-macro `object`*(e: expr): expr {.immediate.} = 
+macro `object`*(e: expr): expr {.immediate.} =
   ## generates the HTML ``object`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "object", "classid data codebase declare type " &
     "codetype archive standby width height name tabindex" & commonAttr)
 
-macro ol*(e: expr): expr {.immediate.} = 
+macro ol*(e: expr): expr {.immediate.} =
   ## generates the HTML ``ol`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "ol", commonAttr)
 
-macro optgroup*(e: expr): expr {.immediate.} = 
+macro optgroup*(e: expr): expr {.immediate.} =
   ## generates the HTML ``optgroup`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "optgroup", "disabled" & commonAttr, "label", false)
 
-macro option*(e: expr): expr {.immediate.} = 
+macro option*(e: expr): expr {.immediate.} =
   ## generates the HTML ``option`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "option", "selected value" & commonAttr)
 
-macro p*(e: expr): expr {.immediate.} = 
+macro p*(e: expr): expr {.immediate.} =
   ## generates the HTML ``p`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "p", commonAttr)
 
-macro param*(e: expr): expr {.immediate.} = 
+macro param*(e: expr): expr {.immediate.} =
   ## generates the HTML ``param`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "param", "value id type valuetype", "name", true)
 
-macro pre*(e: expr): expr {.immediate.} = 
+macro pre*(e: expr): expr {.immediate.} =
   ## generates the HTML ``pre`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "pre", commonAttr)
 
-macro q*(e: expr): expr {.immediate.} = 
+macro q*(e: expr): expr {.immediate.} =
   ## generates the HTML ``q`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "q", "cite" & commonAttr)
 
-macro samp*(e: expr): expr {.immediate.} = 
+macro samp*(e: expr): expr {.immediate.} =
   ## generates the HTML ``samp`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "samp", commonAttr)
 
-macro script*(e: expr): expr {.immediate.} = 
+macro script*(e: expr): expr {.immediate.} =
   ## generates the HTML ``script`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "script", "src charset defer", "type", false)
 
-macro select*(e: expr): expr {.immediate.} = 
+macro select*(e: expr): expr {.immediate.} =
   ## generates the HTML ``select`` element.
   let e = callsite()
-  result = xmlCheckedTag(e, "select", "name size multiple disabled tabindex" & 
+  result = xmlCheckedTag(e, "select", "name size multiple disabled tabindex" &
     commonAttr)
 
-macro small*(e: expr): expr {.immediate.} = 
+macro small*(e: expr): expr {.immediate.} =
   ## generates the HTML ``small`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "small", commonAttr)
 
-macro span*(e: expr): expr {.immediate.} = 
+macro span*(e: expr): expr {.immediate.} =
   ## generates the HTML ``span`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "span", commonAttr)
 
-macro strong*(e: expr): expr {.immediate.} = 
+macro strong*(e: expr): expr {.immediate.} =
   ## generates the HTML ``strong`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "strong", commonAttr)
 
-macro style*(e: expr): expr {.immediate.} = 
+macro style*(e: expr): expr {.immediate.} =
   ## generates the HTML ``style`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "style", "media title", "type")
 
-macro sub*(e: expr): expr {.immediate.} = 
+macro sub*(e: expr): expr {.immediate.} =
   ## generates the HTML ``sub`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "sub", commonAttr)
 
-macro sup*(e: expr): expr {.immediate.} = 
+macro sup*(e: expr): expr {.immediate.} =
   ## generates the HTML ``sup`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "sup", commonAttr)
 
-macro table*(e: expr): expr {.immediate.} = 
+macro table*(e: expr): expr {.immediate.} =
   ## generates the HTML ``table`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "table", "summary border cellpadding cellspacing" &
     " frame rules width" & commonAttr)
 
-macro tbody*(e: expr): expr {.immediate.} = 
+macro tbody*(e: expr): expr {.immediate.} =
   ## generates the HTML ``tbody`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "tbody", "align valign" & commonAttr)
 
-macro td*(e: expr): expr {.immediate.} = 
+macro td*(e: expr): expr {.immediate.} =
   ## generates the HTML ``td`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "td", "colspan rowspan abbr axis headers scope" &
     " align valign" & commonAttr)
 
-macro textarea*(e: expr): expr {.immediate.} = 
+macro textarea*(e: expr): expr {.immediate.} =
   ## generates the HTML ``textarea`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "textarea", " name disabled readonly accesskey" &
     " tabindex" & commonAttr, "rows cols", false)
 
-macro tfoot*(e: expr): expr {.immediate.} = 
+macro tfoot*(e: expr): expr {.immediate.} =
   ## generates the HTML ``tfoot`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "tfoot", "align valign" & commonAttr)
 
-macro th*(e: expr): expr {.immediate.} = 
+macro th*(e: expr): expr {.immediate.} =
   ## generates the HTML ``th`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "th", "colspan rowspan abbr axis headers scope" &
     " align valign" & commonAttr)
 
-macro thead*(e: expr): expr {.immediate.} = 
+macro thead*(e: expr): expr {.immediate.} =
   ## generates the HTML ``thead`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "thead", "align valign" & commonAttr)
 
-macro title*(e: expr): expr {.immediate.} = 
+macro title*(e: expr): expr {.immediate.} =
   ## generates the HTML ``title`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "title")
 
-macro tr*(e: expr): expr {.immediate.} = 
+macro tr*(e: expr): expr {.immediate.} =
   ## generates the HTML ``tr`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "tr", "align valign" & commonAttr)
 
-macro tt*(e: expr): expr {.immediate.} = 
+macro tt*(e: expr): expr {.immediate.} =
   ## generates the HTML ``tt`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "tt", commonAttr)
 
-macro ul*(e: expr): expr {.immediate.} = 
+macro ul*(e: expr): expr {.immediate.} =
   ## generates the HTML ``ul`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "ul", commonAttr)
 
-macro `var`*(e: expr): expr {.immediate.} = 
+macro `var`*(e: expr): expr {.immediate.} =
   ## generates the HTML ``var`` element.
   let e = callsite()
   result = xmlCheckedTag(e, "var", commonAttr)
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 5041fe2f6..c3db5bdf8 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -8,8 +8,8 @@
 #
 
 ## This module implements a simple high performance `JSON`:idx:
-## parser. JSON (JavaScript Object Notation) is a lightweight 
-## data-interchange format that is easy for humans to read and write 
+## parser. JSON (JavaScript Object Notation) is a lightweight
+## data-interchange format that is easy for humans to read and write
 ## (unlike XML). It is easy for machines to parse and generate.
 ## JSON is based on a subset of the JavaScript Programming Language,
 ## Standard ECMA-262 3rd Edition - December 1999.
@@ -50,10 +50,10 @@
 ##       }
 ##     ]
 
-import 
+import
   hashes, strutils, lexbase, streams, unicode, macros
 
-type 
+type
   JsonEventKind* = enum  ## enumeration of all events that may occur when parsing
     jsonError,           ## an error occurred during parsing
     jsonEof,             ## end of file reached
@@ -67,7 +67,7 @@ type
     jsonObjectEnd,       ## end of an object: the ``}`` token
     jsonArrayStart,      ## start of an array: the ``[`` token
     jsonArrayEnd         ## start of an array: the ``]`` token
-    
+
   TTokKind = enum        # must be synchronized with TJsonEventKind!
     tkError,
     tkEof,
@@ -83,7 +83,7 @@ type
     tkBracketRi,
     tkColon,
     tkComma
-    
+
   JsonError* = enum        ## enumeration that lists all errors that can occur
     errNone,               ## no error
     errInvalidToken,       ## invalid token
@@ -96,8 +96,8 @@ type
     errEOC_Expected,       ## ``*/`` expected
     errEofExpected,        ## EOF expected
     errExprExpected        ## expr expected
-    
-  ParserState = enum 
+
+  ParserState = enum
     stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma,
     stateExpectObjectComma, stateExpectColon, stateExpectValue
 
@@ -111,7 +111,7 @@ type
 
 {.deprecated: [TJsonEventKind: JsonEventKind, TJsonError: JsonError,
   TJsonParser: JsonParser].}
- 
+
 const
   errorMessages: array [JsonError, string] = [
     "no error",
@@ -146,56 +146,56 @@ proc open*(my: var JsonParser, input: Stream, filename: string) =
   my.state = @[stateStart]
   my.kind = jsonError
   my.a = ""
-  
-proc close*(my: var JsonParser) {.inline.} = 
+
+proc close*(my: var JsonParser) {.inline.} =
   ## closes the parser `my` and its associated input stream.
   lexbase.close(my)
 
-proc str*(my: JsonParser): string {.inline.} = 
-  ## returns the character data for the events: ``jsonInt``, ``jsonFloat``, 
+proc str*(my: JsonParser): string {.inline.} =
+  ## returns the character data for the events: ``jsonInt``, ``jsonFloat``,
   ## ``jsonString``
   assert(my.kind in {jsonInt, jsonFloat, jsonString})
   return my.a
 
-proc getInt*(my: JsonParser): BiggestInt {.inline.} = 
+proc getInt*(my: JsonParser): BiggestInt {.inline.} =
   ## returns the number for the event: ``jsonInt``
   assert(my.kind == jsonInt)
   return parseBiggestInt(my.a)
 
-proc getFloat*(my: JsonParser): float {.inline.} = 
+proc getFloat*(my: JsonParser): float {.inline.} =
   ## returns the number for the event: ``jsonFloat``
   assert(my.kind == jsonFloat)
   return parseFloat(my.a)
 
-proc kind*(my: JsonParser): JsonEventKind {.inline.} = 
+proc kind*(my: JsonParser): JsonEventKind {.inline.} =
   ## returns the current event type for the JSON parser
   return my.kind
-  
-proc getColumn*(my: JsonParser): int {.inline.} = 
+
+proc getColumn*(my: JsonParser): int {.inline.} =
   ## get the current column the parser has arrived at.
   result = getColNumber(my, my.bufpos)
 
-proc getLine*(my: JsonParser): int {.inline.} = 
+proc getLine*(my: JsonParser): int {.inline.} =
   ## get the current line the parser has arrived at.
   result = my.lineNumber
 
-proc getFilename*(my: JsonParser): string {.inline.} = 
+proc getFilename*(my: JsonParser): string {.inline.} =
   ## get the filename of the file that the parser processes.
   result = my.filename
-  
-proc errorMsg*(my: JsonParser): string = 
+
+proc errorMsg*(my: JsonParser): string =
   ## returns a helpful error message for the event ``jsonError``
   assert(my.kind == jsonError)
   result = "$1($2, $3) Error: $4" % [
     my.filename, $getLine(my), $getColumn(my), errorMessages[my.err]]
 
-proc errorMsgExpected*(my: JsonParser, e: string): string = 
+proc errorMsgExpected*(my: JsonParser, e: string): string =
   ## returns an error message "`e` expected" in the same format as the
-  ## other error messages 
+  ## other error messages
   result = "$1($2, $3) Error: $4" % [
     my.filename, $getLine(my), $getColumn(my), e & " expected"]
 
-proc handleHexChar(c: char, x: var int): bool = 
+proc handleHexChar(c: char, x: var int): bool =
   result = true # Success
   case c
   of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
@@ -208,8 +208,8 @@ proc parseString(my: var JsonParser): TTokKind =
   var pos = my.bufpos + 1
   var buf = my.buf
   while true:
-    case buf[pos] 
-    of '\0': 
+    case buf[pos]
+    of '\0':
       my.err = errQuoteExpected
       result = tkError
       break
@@ -218,21 +218,21 @@ proc parseString(my: var JsonParser): TTokKind =
       break
     of '\\':
       case buf[pos+1]
-      of '\\', '"', '\'', '/': 
+      of '\\', '"', '\'', '/':
         add(my.a, buf[pos+1])
         inc(pos, 2)
       of 'b':
         add(my.a, '\b')
-        inc(pos, 2)      
+        inc(pos, 2)
       of 'f':
         add(my.a, '\f')
-        inc(pos, 2)      
+        inc(pos, 2)
       of 'n':
         add(my.a, '\L')
-        inc(pos, 2)      
+        inc(pos, 2)
       of 'r':
         add(my.a, '\C')
-        inc(pos, 2)    
+        inc(pos, 2)
       of 't':
         add(my.a, '\t')
         inc(pos, 2)
@@ -244,15 +244,15 @@ proc parseString(my: var JsonParser): TTokKind =
         if handleHexChar(buf[pos], r): inc(pos)
         if handleHexChar(buf[pos], r): inc(pos)
         add(my.a, toUTF8(Rune(r)))
-      else: 
+      else:
         # don't bother with the error
         add(my.a, buf[pos])
         inc(pos)
-    of '\c': 
+    of '\c':
       pos = lexbase.handleCR(my, pos)
       buf = my.buf
       add(my.a, '\c')
-    of '\L': 
+    of '\L':
       pos = lexbase.handleLF(my, pos)
       buf = my.buf
       add(my.a, '\L')
@@ -260,25 +260,25 @@ proc parseString(my: var JsonParser): TTokKind =
       add(my.a, buf[pos])
       inc(pos)
   my.bufpos = pos # store back
-  
-proc skip(my: var JsonParser) = 
+
+proc skip(my: var JsonParser) =
   var pos = my.bufpos
   var buf = my.buf
-  while true: 
+  while true:
     case buf[pos]
-    of '/': 
-      if buf[pos+1] == '/': 
+    of '/':
+      if buf[pos+1] == '/':
         # skip line comment:
         inc(pos, 2)
         while true:
-          case buf[pos] 
-          of '\0': 
+          case buf[pos]
+          of '\0':
             break
-          of '\c': 
+          of '\c':
             pos = lexbase.handleCR(my, pos)
             buf = my.buf
             break
-          of '\L': 
+          of '\L':
             pos = lexbase.handleLF(my, pos)
             buf = my.buf
             break
@@ -288,44 +288,44 @@ proc skip(my: var JsonParser) =
         # skip long comment:
         inc(pos, 2)
         while true:
-          case buf[pos] 
-          of '\0': 
+          case buf[pos]
+          of '\0':
             my.err = errEOC_Expected
             break
-          of '\c': 
+          of '\c':
             pos = lexbase.handleCR(my, pos)
             buf = my.buf
-          of '\L': 
+          of '\L':
             pos = lexbase.handleLF(my, pos)
             buf = my.buf
           of '*':
             inc(pos)
-            if buf[pos] == '/': 
+            if buf[pos] == '/':
               inc(pos)
               break
           else:
             inc(pos)
-      else: 
+      else:
         break
-    of ' ', '\t': 
+    of ' ', '\t':
       inc(pos)
-    of '\c':  
+    of '\c':
       pos = lexbase.handleCR(my, pos)
       buf = my.buf
-    of '\L': 
+    of '\L':
       pos = lexbase.handleLF(my, pos)
       buf = my.buf
     else:
       break
   my.bufpos = pos
 
-proc parseNumber(my: var JsonParser) = 
+proc parseNumber(my: var JsonParser) =
   var pos = my.bufpos
   var buf = my.buf
-  if buf[pos] == '-': 
+  if buf[pos] == '-':
     add(my.a, '-')
     inc(pos)
-  if buf[pos] == '.': 
+  if buf[pos] == '.':
     add(my.a, "0.")
     inc(pos)
   else:
@@ -350,7 +350,7 @@ proc parseNumber(my: var JsonParser) =
       inc(pos)
   my.bufpos = pos
 
-proc parseName(my: var JsonParser) = 
+proc parseName(my: var JsonParser) =
   var pos = my.bufpos
   var buf = my.buf
   if buf[pos] in IdentStartChars:
@@ -359,11 +359,11 @@ proc parseName(my: var JsonParser) =
       inc(pos)
   my.bufpos = pos
 
-proc getTok(my: var JsonParser): TTokKind = 
+proc getTok(my: var JsonParser): TTokKind =
   setLen(my.a, 0)
   skip(my) # skip whitespace, comments
   case my.buf[my.bufpos]
-  of '-', '.', '0'..'9': 
+  of '-', '.', '0'..'9':
     parseNumber(my)
     if {'.', 'e', 'E'} in my.a:
       result = tkFloat
@@ -393,17 +393,17 @@ proc getTok(my: var JsonParser): TTokKind =
     result = tkEof
   of 'a'..'z', 'A'..'Z', '_':
     parseName(my)
-    case my.a 
+    case my.a
     of "null": result = tkNull
     of "true": result = tkTrue
     of "false": result = tkFalse
     else: result = tkError
-  else: 
+  else:
     inc(my.bufpos)
     result = tkError
   my.tok = result
 
-proc next*(my: var JsonParser) = 
+proc next*(my: var JsonParser) =
   ## retrieves the first/next event. This controls the parser.
   var tk = getTok(my)
   var i = my.state.len-1
@@ -416,13 +416,13 @@ proc next*(my: var JsonParser) =
     else:
       my.kind = jsonError
       my.err = errEofExpected
-  of stateStart: 
-    # tokens allowed? 
+  of stateStart:
+    # tokens allowed?
     case tk
     of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
       my.state[i] = stateEof # expect EOF next!
       my.kind = JsonEventKind(ord(tk))
-    of tkBracketLe: 
+    of tkBracketLe:
       my.state.add(stateArray) # we expect any
       my.kind = jsonArrayStart
     of tkCurlyLe:
@@ -433,12 +433,12 @@ proc next*(my: var JsonParser) =
     else:
       my.kind = jsonError
       my.err = errEofExpected
-  of stateObject: 
+  of stateObject:
     case tk
     of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
       my.state.add(stateExpectColon)
       my.kind = JsonEventKind(ord(tk))
-    of tkBracketLe: 
+    of tkBracketLe:
       my.state.add(stateExpectColon)
       my.state.add(stateArray)
       my.kind = jsonArrayStart
@@ -457,7 +457,7 @@ proc next*(my: var JsonParser) =
     of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
       my.state.add(stateExpectArrayComma) # expect value next!
       my.kind = JsonEventKind(ord(tk))
-    of tkBracketLe: 
+    of tkBracketLe:
       my.state.add(stateExpectArrayComma)
       my.state.add(stateArray)
       my.kind = jsonArrayStart
@@ -472,8 +472,8 @@ proc next*(my: var JsonParser) =
       my.kind = jsonError
       my.err = errBracketRiExpected
   of stateExpectArrayComma:
-    case tk 
-    of tkComma: 
+    case tk
+    of tkComma:
       discard my.state.pop()
       next(my)
     of tkBracketRi:
@@ -484,8 +484,8 @@ proc next*(my: var JsonParser) =
       my.kind = jsonError
       my.err = errBracketRiExpected
   of stateExpectObjectComma:
-    case tk 
-    of tkComma: 
+    case tk
+    of tkComma:
       discard my.state.pop()
       next(my)
     of tkCurlyRi:
@@ -495,9 +495,9 @@ proc next*(my: var JsonParser) =
     else:
       my.kind = jsonError
       my.err = errCurlyRiExpected
-  of stateExpectColon: 
-    case tk 
-    of tkColon: 
+  of stateExpectColon:
+    case tk
+    of tkColon:
       my.state[i] = stateExpectValue
       next(my)
     else:
@@ -508,7 +508,7 @@ proc next*(my: var JsonParser) =
     of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
       my.state[i] = stateExpectObjectComma
       my.kind = JsonEventKind(ord(tk))
-    of tkBracketLe: 
+    of tkBracketLe:
       my.state[i] = stateExpectObjectComma
       my.state.add(stateArray)
       my.kind = jsonArrayStart
@@ -532,8 +532,8 @@ type
     JString,
     JObject,
     JArray
-    
-  JsonNode* = ref JsonNodeObj ## JSON node 
+
+  JsonNode* = ref JsonNodeObj ## JSON node
   JsonNodeObj* {.acyclic.} = object
     case kind*: JsonNodeKind
     of JString:
@@ -644,7 +644,7 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode =
   newSeq(result.elems, elements.len)
   for i, p in pairs(elements): result.elems[i] = p
 
-proc toJson(x: PNimrodNode): PNimrodNode {.compiletime.} =
+proc toJson(x: NimNode): NimNode {.compiletime.} =
   case x.kind
   of nnkBracket:
     result = newNimNode(nnkBracket)
@@ -672,7 +672,7 @@ proc `==`* (a,b: JsonNode): bool =
   if a.isNil:
     if b.isNil: return true
     return false
-  elif b.isNil or a.kind != b.kind: 
+  elif b.isNil or a.kind != b.kind:
     return false
   else:
     return case a.kind
@@ -709,7 +709,7 @@ proc hash* (n:JsonNode): THash =
   of JNull:
     result = hash(0)
 
-proc len*(n: JsonNode): int = 
+proc len*(n: JsonNode): int =
   ## If `n` is a `JArray`, it returns the number of elements.
   ## If `n` is a `JObject`, it returns the number of pairs.
   ## Else it returns 0.
@@ -727,7 +727,7 @@ proc `[]`*(node: JsonNode, name: string): JsonNode =
     if key == name:
       return item
   return nil
-  
+
 proc `[]`*(node: JsonNode, index: int): JsonNode =
   ## Gets the node at `index` in an Array. Result is undefined if `index`
   ## is out of bounds
@@ -744,12 +744,12 @@ proc hasKey*(node: JsonNode, key: string): bool =
 proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key)
   ## Deprecated for `hasKey`
 
-proc add*(father, child: JsonNode) = 
-  ## Adds `child` to a JArray node `father`. 
+proc add*(father, child: JsonNode) =
+  ## Adds `child` to a JArray node `father`.
   assert father.kind == JArray
   father.elems.add(child)
 
-proc add*(obj: JsonNode, key: string, val: JsonNode) = 
+proc add*(obj: JsonNode, key: string, val: JsonNode) =
   ## Adds ``(key, val)`` pair to the JObject node `obj`. For speed
   ## reasons no check for duplicate keys is performed!
   ## But ``[]=`` performs the check.
@@ -760,7 +760,7 @@ proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) =
   ## Sets a field from a `JObject`. Performs a check for duplicate keys.
   assert(obj.kind == JObject)
   for i in 0..obj.fields.len-1:
-    if obj.fields[i].key == key: 
+    if obj.fields[i].key == key:
       obj.fields[i].val = val
       return
   obj.fields.add((key, val))
@@ -815,17 +815,17 @@ proc copy*(p: JsonNode): JsonNode =
 
 # ------------- pretty printing ----------------------------------------------
 
-proc indent(s: var string, i: int) = 
+proc indent(s: var string, i: int) =
   s.add(spaces(i))
 
 proc newIndent(curr, indent: int, ml: bool): int =
   if ml: return curr + indent
   else: return indent
 
-proc nl(s: var string, ml: bool) = 
+proc nl(s: var string, ml: bool) =
   if ml: s.add("\n")
 
-proc escapeJson*(s: string): string = 
+proc escapeJson*(s: string): string =
   ## Converts a string `s` to its JSON representation.
   result = newStringOfCap(s.len + s.len shr 3)
   result.add("\"")
@@ -842,13 +842,13 @@ proc escapeJson*(s: string): string =
       result.add(toHex(r, 4))
   result.add("\"")
 
-proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true, 
+proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
               lstArr = false, currIndent = 0) =
   case node.kind
   of JObject:
     if currIndent != 0 and not lstArr: result.nl(ml)
     result.indent(currIndent) # Indentation
-    if node.fields.len > 0:  
+    if node.fields.len > 0:
       result.add("{")
       result.nl(ml) # New line
       for i in 0..len(node.fields)-1:
@@ -856,17 +856,17 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
           result.add(", ")
           result.nl(ml) # New Line
         # Need to indent more than {
-        result.indent(newIndent(currIndent, indent, ml)) 
+        result.indent(newIndent(currIndent, indent, ml))
         result.add(escapeJson(node.fields[i].key))
         result.add(": ")
-        toPretty(result, node.fields[i].val, indent, ml, false, 
+        toPretty(result, node.fields[i].val, indent, ml, false,
                  newIndent(currIndent, indent, ml))
       result.nl(ml)
       result.indent(currIndent) # indent the same as {
       result.add("}")
     else:
       result.add("{}")
-  of JString: 
+  of JString:
     if lstArr: result.indent(currIndent)
     result.add(escapeJson(node.str))
   of JInt:
@@ -934,11 +934,11 @@ iterator mpairs*(node: var JsonNode): var tuple[key: string, val: JsonNode] =
   for keyVal in mitems(node.fields):
     yield keyVal
 
-proc eat(p: var JsonParser, tok: TTokKind) = 
+proc eat(p: var JsonParser, tok: TTokKind) =
   if p.tok == tok: discard getTok(p)
   else: raiseParseErr(p, tokToStr[tok])
 
-proc parseJson(p: var JsonParser): JsonNode = 
+proc parseJson(p: var JsonParser): JsonNode =
   ## Parses JSON from a JSON Parser `p`.
   case p.tok
   of tkString:
@@ -955,17 +955,17 @@ proc parseJson(p: var JsonParser): JsonNode =
   of tkTrue:
     result = newJBool(true)
     discard getTok(p)
-  of tkFalse: 
+  of tkFalse:
     result = newJBool(false)
     discard getTok(p)
-  of tkNull: 
+  of tkNull:
     result = newJNull()
     discard getTok(p)
-  of tkCurlyLe: 
+  of tkCurlyLe:
     result = newJObject()
     discard getTok(p)
-    while p.tok != tkCurlyRi: 
-      if p.tok != tkString: 
+    while p.tok != tkCurlyRi:
+      if p.tok != tkString:
         raiseParseErr(p, "string literal as key expected")
       var key = p.a
       discard getTok(p)
@@ -978,7 +978,7 @@ proc parseJson(p: var JsonParser): JsonNode =
   of tkBracketLe:
     result = newJArray()
     discard getTok(p)
-    while p.tok != tkBracketRi: 
+    while p.tok != tkBracketRi:
       result.add(parseJson(p))
       if p.tok != tkComma: break
       discard getTok(p)
@@ -1098,10 +1098,10 @@ when false:
     of jsonObjectEnd: echo("}")
     of jsonArrayStart: echo("[")
     of jsonArrayEnd: echo("]")
-    
+
   close(x)
 
-# { "json": 5 } 
+# { "json": 5 }
 # To get that we shall use, obj["json"]
 
 when isMainModule:
diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim
index f4e42ee63..3bf4724b9 100644
--- a/lib/pure/unittest.nim
+++ b/lib/pure/unittest.nim
@@ -47,7 +47,7 @@ type
 
 {.deprecated: [TTestStatus: TestStatus, TOutputLevel: OutputLevel]}
 
-var 
+var
   abortOnError* {.threadvar.}: bool
   outputLevel* {.threadvar.}: OutputLevel
   colorOutput* {.threadvar.}: bool
@@ -144,7 +144,7 @@ macro check*(conditions: stmt): stmt {.immediate.} =
     when compiles(string($value)):
       checkpoint(name & " was " & $value)
 
-  proc inspectArgs(exp: PNimrodNode) =
+  proc inspectArgs(exp: NimNode) =
     for i in 1 .. <exp.len:
       if exp[i].kind notin nnkLiterals:
         inc counter
@@ -202,7 +202,7 @@ template require*(conditions: stmt): stmt {.immediate, dirty.} =
 macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
   let exp = callsite()
   template expectBody(errorTypes, lineInfoLit: expr,
-                      body: stmt): PNimrodNode {.dirty.} =
+                      body: stmt): NimNode {.dirty.} =
     try:
       body
       checkpoint(lineInfoLit & ": Expect Failed, no exception was thrown.")
diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim
index c783158ea..0bf5b52a4 100644
--- a/lib/pure/xmltree.nim
+++ b/lib/pure/xmltree.nim
@@ -12,20 +12,20 @@
 import macros, strtabs
 
 type
-  XmlNode* = ref XmlNodeObj ## an XML tree consists of ``PXmlNode``'s. 
-  
+  XmlNode* = ref XmlNodeObj ## an XML tree consists of ``PXmlNode``'s.
+
   XmlNodeKind* = enum  ## different kinds of ``PXmlNode``'s
     xnText,             ## a text element
     xnElement,          ## an element with 0 or more children
     xnCData,            ## a CDATA node
     xnEntity,           ## an entity (like ``&thing;``)
     xnComment           ## an XML comment
-  
+
   XmlAttributes* = StringTableRef ## an alias for a string to string mapping
-  
-  XmlNodeObj {.acyclic.} = object 
+
+  XmlNodeObj {.acyclic.} = object
     case k: XmlNodeKind # private, use the kind() proc to read this field.
-    of xnText, xnComment, xnCData, xnEntity: 
+    of xnText, xnComment, xnCData, xnEntity:
       fText: string
     of xnElement:
       fTag: string
@@ -41,34 +41,34 @@ proc newXmlNode(kind: XmlNodeKind): XmlNode =
   new(result)
   result.k = kind
 
-proc newElement*(tag: string): XmlNode = 
+proc newElement*(tag: string): XmlNode =
   ## creates a new ``PXmlNode`` of kind ``xnText`` with the given `tag`.
   result = newXmlNode(xnElement)
   result.fTag = tag
   result.s = @[]
   # init attributes lazily to safe memory
 
-proc newText*(text: string): XmlNode = 
+proc newText*(text: string): XmlNode =
   ## creates a new ``PXmlNode`` of kind ``xnText`` with the text `text`.
   result = newXmlNode(xnText)
   result.fText = text
 
-proc newComment*(comment: string): XmlNode = 
+proc newComment*(comment: string): XmlNode =
   ## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `comment`.
   result = newXmlNode(xnComment)
   result.fText = comment
 
-proc newCData*(cdata: string): XmlNode = 
+proc newCData*(cdata: string): XmlNode =
   ## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `cdata`.
   result = newXmlNode(xnCData)
   result.fText = cdata
 
-proc newEntity*(entity: string): XmlNode = 
+proc newEntity*(entity: string): XmlNode =
   ## creates a new ``PXmlNode`` of kind ``xnEntity`` with the text `entity`.
   result = newXmlNode(xnCData)
   result.fText = entity
 
-proc text*(n: XmlNode): string {.inline.} = 
+proc text*(n: XmlNode): string {.inline.} =
   ## gets the associated text with the node `n`. `n` can be a CDATA, Text,
   ## comment, or entity node.
   assert n.k in {xnText, xnComment, xnCData, xnEntity}
@@ -93,16 +93,16 @@ proc innerText*(n: XmlNode): string =
   for i in 0 .. n.s.len-1:
     if n.s[i].k in {xnText, xnEntity}: result.add(n.s[i].fText)
 
-proc tag*(n: XmlNode): string {.inline.} = 
+proc tag*(n: XmlNode): string {.inline.} =
   ## gets the tag name of `n`. `n` has to be an ``xnElement`` node.
   assert n.k == xnElement
   result = n.fTag
-    
-proc add*(father, son: XmlNode) {.inline.} = 
+
+proc add*(father, son: XmlNode) {.inline.} =
   ## adds the child `son` to `father`.
   add(father.s, son)
-  
-proc len*(n: XmlNode): int {.inline.} = 
+
+proc len*(n: XmlNode): int {.inline.} =
   ## returns the number `n`'s children.
   if n.k == xnElement: result = len(n.s)
 
@@ -110,38 +110,38 @@ proc kind*(n: XmlNode): XmlNodeKind {.inline.} =
   ## returns `n`'s kind.
   result = n.k
 
-proc `[]`* (n: XmlNode, i: int): XmlNode {.inline.} = 
+proc `[]`* (n: XmlNode, i: int): XmlNode {.inline.} =
   ## returns the `i`'th child of `n`.
   assert n.k == xnElement
   result = n.s[i]
 
-proc mget* (n: var XmlNode, i: int): var XmlNode {.inline.} = 
+proc mget* (n: var XmlNode, i: int): var XmlNode {.inline.} =
   ## returns the `i`'th child of `n` so that it can be modified
   assert n.k == xnElement
   result = n.s[i]
 
-iterator items*(n: XmlNode): XmlNode {.inline.} = 
+iterator items*(n: XmlNode): XmlNode {.inline.} =
   ## iterates over any child of `n`.
   assert n.k == xnElement
   for i in 0 .. n.len-1: yield n[i]
 
-iterator mitems*(n: var XmlNode): var XmlNode {.inline.} = 
+iterator mitems*(n: var XmlNode): var XmlNode {.inline.} =
   ## iterates over any child of `n`.
   assert n.k == xnElement
   for i in 0 .. n.len-1: yield mget(n, i)
 
-proc attrs*(n: XmlNode): XmlAttributes {.inline.} = 
+proc attrs*(n: XmlNode): XmlAttributes {.inline.} =
   ## gets the attributes belonging to `n`.
   ## Returns `nil` if attributes have not been initialised for this node.
   assert n.k == xnElement
   result = n.fAttr
-  
-proc `attrs=`*(n: XmlNode, attr: XmlAttributes) {.inline.} = 
+
+proc `attrs=`*(n: XmlNode, attr: XmlAttributes) {.inline.} =
   ## sets the attributes belonging to `n`.
   assert n.k == xnElement
   n.fAttr = attr
 
-proc attrsLen*(n: XmlNode): int {.inline.} = 
+proc attrsLen*(n: XmlNode): int {.inline.} =
   ## returns the number of `n`'s attributes.
   assert n.k == xnElement
   if not isNil(n.fAttr): result = len(n.fAttr)
@@ -151,12 +151,12 @@ proc clientData*(n: XmlNode): int {.inline.} =
   ## parser and generator.
   result = n.fClientData
 
-proc `clientData=`*(n: XmlNode, data: int) {.inline.} = 
+proc `clientData=`*(n: XmlNode, data: int) {.inline.} =
   ## sets the client data of `n`. The client data field is used by the HTML
   ## parser and generator.
   n.fClientData = data
 
-proc addEscaped*(result: var string, s: string) = 
+proc addEscaped*(result: var string, s: string) =
   ## same as ``result.add(escape(s))``, but more efficient.
   for c in items(s):
     case c
@@ -168,8 +168,8 @@ proc addEscaped*(result: var string, s: string) =
     of '/': result.add("&#x2F;")
     else: result.add(c)
 
-proc escape*(s: string): string = 
-  ## escapes `s` for inclusion into an XML document. 
+proc escape*(s: string): string =
+  ## escapes `s` for inclusion into an XML document.
   ## Escapes these characters:
   ##
   ## ------------    -------------------
@@ -184,26 +184,26 @@ proc escape*(s: string): string =
   ## ------------    -------------------
   result = newStringOfCap(s.len)
   addEscaped(result, s)
-  
-proc addIndent(result: var string, indent: int) = 
+
+proc addIndent(result: var string, indent: int) =
   result.add("\n")
   for i in 1..indent: result.add(' ')
-  
+
 proc noWhitespace(n: XmlNode): bool =
   #for i in 1..n.len-1:
   #  if n[i].kind != n[0].kind: return true
   for i in 0..n.len-1:
     if n[i].kind in {xnText, xnEntity}: return true
-  
-proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) = 
+
+proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
   ## adds the textual representation of `n` to `result`.
   if n == nil: return
   case n.k
   of xnElement:
     result.add('<')
     result.add(n.fTag)
-    if not isNil(n.fAttr): 
-      for key, val in pairs(n.fAttr): 
+    if not isNil(n.fAttr):
+      for key, val in pairs(n.fAttr):
         result.add(' ')
         result.add(key)
         result.add("=\"")
@@ -217,7 +217,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
           # because this would be wrong. For example: ``a<b>b</b>`` is
           # different from ``a <b>b</b>``.
           for i in 0..n.len-1: result.add(n[i], indent+indWidth, indWidth)
-        else: 
+        else:
           for i in 0..n.len-1:
             result.addIndent(indent+indWidth)
             result.add(n[i], indent+indWidth, indWidth)
@@ -227,7 +227,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
       result.add("</")
       result.add(n.fTag)
       result.add(">")
-    else: 
+    else:
       result.add(" />")
   of xnText:
     result.addEscaped(n.fText)
@@ -245,7 +245,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
     result.add(';')
 
 const
-  xmlHeader* = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" 
+  xmlHeader* = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
     ## header to use for complete XML output
 
 proc `$`*(n: XmlNode): string =
@@ -255,21 +255,21 @@ proc `$`*(n: XmlNode): string =
   result.add(n)
 
 proc newXmlTree*(tag: string, children: openArray[XmlNode],
-                 attributes: XmlAttributes = nil): XmlNode = 
+                 attributes: XmlAttributes = nil): XmlNode =
   ## creates a new XML tree with `tag`, `children` and `attributes`
   result = newXmlNode(xnElement)
   result.fTag = tag
   newSeq(result.s, children.len)
   for i in 0..children.len-1: result.s[i] = children[i]
   result.fAttr = attributes
-  
-proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} =
+
+proc xmlConstructor(e: NimNode): NimNode {.compileTime.} =
   expectLen(e, 2)
   var a = e[1]
   if a.kind == nnkCall:
     result = newCall("newXmlTree", toStrLit(a[0]))
     var attrs = newNimNode(nnkBracket, a)
-    var newStringTabCall = newCall("newStringTable", attrs, 
+    var newStringTabCall = newCall("newStringTable", attrs,
                                    newIdentNode("modeCaseSensitive"))
     var elements = newNimNode(nnkBracket, a)
     for i in 1..a.len-1:
@@ -280,13 +280,13 @@ proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} =
       else:
         elements.add(a[i])
     result.add(elements)
-    if attrs.len > 1: 
+    if attrs.len > 1:
       #echo repr(newStringTabCall)
       result.add(newStringTabCall)
   else:
     result = newCall("newXmlTree", toStrLit(a))
 
-macro `<>`*(x: expr): expr {.immediate.} = 
+macro `<>`*(x: expr): expr {.immediate.} =
   ## Constructor macro for XML. Example usage:
   ##
   ## .. code-block:: nim
diff --git a/lib/system.nim b/lib/system.nim
index ea35bd54a..23c911a19 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1224,7 +1224,7 @@ type # these work for most platforms:
     ## This is the same as the type ``unsigned char`` in *C*.
   cushort* {.importc: "unsigned short", nodecl.} = uint16
     ## This is the same as the type ``unsigned short`` in *C*.
-  cuint* {.importc: "int", nodecl.} = uint32
+  cuint* {.importc: "unsigned int", nodecl.} = uint32
     ## This is the same as the type ``unsigned int`` in *C*.
   culonglong* {.importc: "unsigned long long", nodecl.} = uint64
     ## This is the same as the type ``unsigned long long`` in *C*.
@@ -3149,15 +3149,9 @@ proc shallow*(s: var string) {.noSideEffect, inline.} =
 type
   NimNodeObj = object
 
-when defined(nimnode):
-  type
-    NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj
-      ## represents a Nim AST node. Macros operate on this type.
-  {.deprecated: [PNimrodNode: NimNode].}
-else:
-  type
-    PNimrodNode* {.magic: "PNimrodNode".} = ref NimNodeObj
-      ## represents a Nim AST node. Macros operate on this type.
+  NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj
+    ## represents a Nim AST node. Macros operate on this type.
+{.deprecated: [PNimrodNode: NimNode].}
 
 when false:
   template eval*(blk: stmt): stmt =
diff --git a/tests/caas/idetools_api.nim b/tests/caas/idetools_api.nim
index 8f1061e27..281e562d7 100644
--- a/tests/caas/idetools_api.nim
+++ b/tests/caas/idetools_api.nim
@@ -58,7 +58,7 @@ macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
   ## Expect docstrings
   let exp = callsite()
   template expectBody(errorTypes, lineInfoLit: expr,
-                      body: stmt): PNimrodNode {.dirty.} =
+                      body: stmt): NimNode {.dirty.} =
     try:
       body
       assert false
diff --git a/tests/collections/ttablesref.nim b/tests/collections/ttablesref.nim
index b57aedf4a..16b0d831e 100644
--- a/tests/collections/ttablesref.nim
+++ b/tests/collections/ttablesref.nim
@@ -2,7 +2,7 @@ discard """
   output: '''true'''
 """
 
-import hashes, tables
+import hashes, tables, sequtils
 
 const
   data = {
@@ -103,9 +103,10 @@ block countTableTest1:
 
 block SyntaxTest:
   var x = newTable[int, string]({:})
+  discard x
 
 block nilTest:
-  var i, j: PTable[int, int] = nil
+  var i, j: TableRef[int, int] = nil
   assert i == j
   j = newTable[int, int]()
   assert i != j
@@ -131,6 +132,10 @@ proc orderedTableSortTest() =
   # check that insert still works:
   t["newKeyHere"] = 80
 
+block anonZipTest:
+  let keys = @['a','b','c']
+  let values = @[1, 2, 3]
+  doAssert "{a: 1, b: 2, c: 3}" == $ toTable zip(keys, values)
 
 orderedTableSortTest()
 echo "true"
diff --git a/tests/metatype/udtcmanual.nim b/tests/concepts/tmanual.nim
index dd44298dc..243992aed 100644
--- a/tests/metatype/udtcmanual.nim
+++ b/tests/concepts/tmanual.nim
@@ -12,6 +12,7 @@ e
 s
 t
 '''
+  disabled: "true"
 """
 
 template accept(e: expr) =
diff --git a/tests/metatype/swizzle.nim b/tests/concepts/tswizzle.nim
index ce18fa234..9bbdb67e6 100644
--- a/tests/metatype/swizzle.nim
+++ b/tests/concepts/tswizzle.nim
@@ -3,6 +3,7 @@ discard """
 [1, 3]
 [2, 1, 2]
 '''
+  disabled: "true"
 """
 
 import macros, strutils
@@ -18,14 +19,14 @@ proc swizzleIdx(c: char): int =
     of 'x': 0
     of 'y': 1
     of 'z': 2
-    of 'w': 3    
+    of 'w': 3
     of 'r': 0
     of 'g': 1
     of 'b': 2
-    of 'a': 3    
+    of 'a': 3
     else: 0
 
-proc isSwizzle(s: string): bool =
+proc isSwizzle(s: string): bool {.compileTime.} =
   template trySet(name, set) =
     block search:
       for c in s:
@@ -35,10 +36,10 @@ proc isSwizzle(s: string): bool =
 
   trySet coords, {'x', 'y', 'z', 'w'}
   trySet colors, {'r', 'g', 'b', 'a'}
-  
+
   return false
 
-type 
+type
   StringIsSwizzle = generic value
     value.isSwizzle
 
@@ -47,33 +48,33 @@ type
 proc foo(x: SwizzleStr) =
   echo "sw"
 
-accept foo("xx")
+#foo("xx")
 reject foo("xe")
 
-type 
+type
   Vec[N: static[int]; T] = array[N, T]
 
+when false:
+  proc card(x: Vec): int = x.N
+  proc `$`(x: Vec): string = x.repr.strip
 
-proc card(x: Vec): int = x.N
-proc `$`(x: Vec): string = x.repr.strip
+  macro `.`(x: Vec, swizzle: SwizzleStr): expr =
+    var
+      cardinality = swizzle.len
+      values = newNimNode(nnkBracket)
+      v = genSym()
 
-macro `.`(x: Vec, swizzle: SwizzleStr): expr =
-  var
-    cardinality = swizzle.len
-    values = newNimNode(nnkBracket)
-    v = genSym()
+    for c in swizzle:
+      values.add newNimNode(nnkBracketExpr).add(
+        v, c.swizzleIdx.newIntLitNode)
 
-  for c in swizzle:
-    values.add newNimNode(nnkBracketExpr).add(
-      v, c.swizzleIdx.newIntLitNode)
-  
-  return quote do:
-    let `v` = `x`
-    Vec[`cardinality`, `v`.T](`values`)
+    return quote do:
+      let `v` = `x`
+      Vec[`cardinality`, `v`.T](`values`)
 
 var z = Vec([1, 2, 3])
 
-echo z.card
-echo z.xz
-echo z.yxy
+#echo z.card
+#echo z.xz
+#echo z.yxy
 
diff --git a/tests/metatype/tusertypeclasses.nim b/tests/concepts/tusertypeclasses.nim
index 4e5e6221c..4e5e6221c 100644
--- a/tests/metatype/tusertypeclasses.nim
+++ b/tests/concepts/tusertypeclasses.nim
diff --git a/tests/metatype/tusertypeclasses2.nim b/tests/concepts/tusertypeclasses2.nim
index 77c70d7a6..77c70d7a6 100644
--- a/tests/metatype/tusertypeclasses2.nim
+++ b/tests/concepts/tusertypeclasses2.nim
diff --git a/tests/converter/ttypeconverter1.nim b/tests/converter/ttypeconverter1.nim
index fd3a0318a..510b84700 100644
--- a/tests/converter/ttypeconverter1.nim
+++ b/tests/converter/ttypeconverter1.nim
@@ -1,5 +1,5 @@
 discard """
-  ouput: '''foo
+  output: '''foo
 true'''
 """
 
diff --git a/tests/generics/tarray_with_somenumber.nim b/tests/generics/tarray_with_somenumber.nim
new file mode 100644
index 000000000..0bf2537a1
--- /dev/null
+++ b/tests/generics/tarray_with_somenumber.nim
@@ -0,0 +1,11 @@
+discard """
+  output: '''@[0.9, 0.1]'''
+"""
+
+# bug #2304
+
+type TV2*[T:SomeNumber] = array[0..1, T]
+proc newV2T*[T](x, y: T=0): TV2[T] = [x, y]
+
+let x = newV2T[float](0.9, 0.1)
+echo(@x)
diff --git a/tests/generics/tunique_type.nim b/tests/generics/tunique_type.nim
index 29367181c..e78640caa 100644
--- a/tests/generics/tunique_type.nim
+++ b/tests/generics/tunique_type.nim
@@ -20,13 +20,13 @@ import strutils
 # This serves the same purpose as D's `alias` parameters for types, used heavily
 # in its popular `ranges` and `algorithm` modules.
 
-var exprNodes {.compileTime.} = newSeq[PNimrodNode]()
+var exprNodes {.compileTime.} = newSeq[NimNode]()
 
-proc refExpr(exprNode: PNimrodNode): string {.compileTime.} =
+proc refExpr(exprNode: NimNode): string {.compileTime.} =
   exprNodes.add exprNode.copy
   "expr" & $(exprNodes.len - 1)
 
-proc derefExpr(exprRef: string): PNimrodNode {.compileTime.} =
+proc derefExpr(exprRef: string): NimNode {.compileTime.} =
   exprNodes[parseInt(exprRef[4 .. -1])]
 
 #===============================================================================
diff --git a/tests/let/tlet2.nim b/tests/let/tlet2.nim
index 8b1ddf940..66dd5a55b 100644
--- a/tests/let/tlet2.nim
+++ b/tests/let/tlet2.nim
@@ -1,6 +1,6 @@
 discard """
   line: "13"
-  errormsg: "for a 'var' type a variable needs to be passed"
+  errormsg: "type mismatch: got (int literal(8), int literal(5), int, int)"
 """
 
 proc divmod(a, b: int, res, remainder: var int) =
diff --git a/tests/macros/tbugs.nim b/tests/macros/tbugs.nim
index 3db851dd1..1ecb0d4cc 100644
--- a/tests/macros/tbugs.nim
+++ b/tests/macros/tbugs.nim
@@ -46,13 +46,13 @@ echotest()
 
 # bug #1103
 
-type 
+type
     Td = tuple
         a:string
         b:int
 
 proc get_data(d: Td) : string {.compileTime.} =
-    result = d.a # Works if a literal string is used here. 
+    result = d.a # Works if a literal string is used here.
     # Bugs if line A or B is active. Works with C
     result &= "aa"          # A
     #result.add("aa")       # B
@@ -69,7 +69,7 @@ m(s)
 
 # bug #933
 
-proc nilcheck(): PNimrodNode {.compileTime.} =
+proc nilcheck(): NimNode {.compileTime.} =
   echo(result == nil) # true
   echo(result.isNil) # true
   echo(repr(result)) # nil
diff --git a/tests/macros/tdumpast.nim b/tests/macros/tdumpast.nim
index 160e4e194..e3388591a 100644
--- a/tests/macros/tdumpast.nim
+++ b/tests/macros/tdumpast.nim
@@ -1,4 +1,4 @@
-# Dump the contents of a PNimrodNode
+# Dump the contents of a NimNode
 
 import macros
 
@@ -7,7 +7,7 @@ template plus(a, b: expr): expr {.dirty} =
 
 macro call(e: expr): expr =
   result = newCall("foo", newStrLitNode("bar"))
-  
+
 macro dumpAST(n: stmt): stmt {.immediate.} =
   # dump AST as a side-effect and return the inner node
   let n = callsite()
@@ -24,10 +24,10 @@ macro dumpAST(n: stmt): stmt {.immediate.} =
   echo e.lispRepr
 
   result = n[1]
-  
+
 dumpAST:
   proc add(x, y: int): int =
     return x + y
-  
+
   proc sub(x, y: int): int = return x - y
 
diff --git a/tests/macros/tdumpast2.nim b/tests/macros/tdumpast2.nim
index 2a7024a01..6b694fa77 100644
--- a/tests/macros/tdumpast2.nim
+++ b/tests/macros/tdumpast2.nim
@@ -1,13 +1,13 @@
-# Dump the contents of a PNimrodNode
+# Dump the contents of a NimNode
 
 import macros
 
-proc dumpit(n: PNimrodNode): string {.compileTime.} = 
+proc dumpit(n: NimNode): string {.compileTime.} =
   if n == nil: return "nil"
   result = $n.kind
   add(result, "(")
   case n.kind
-  of nnkEmpty: discard # same as nil node in this representation 
+  of nnkEmpty: discard # same as nil node in this representation
   of nnkNilLit:                  add(result, "nil")
   of nnkCharLit..nnkInt64Lit:    add(result, $n.intVal)
   of nnkFloatLit..nnkFloat64Lit: add(result, $n.floatVal)
@@ -20,17 +20,17 @@ proc dumpit(n: PNimrodNode): string {.compileTime.} =
       add(result, ", ")
       add(result, dumpit(n[j]))
   add(result, ")")
-  
-macro dumpAST(n: stmt): stmt {.immediate.} = 
+
+macro dumpAST(n: stmt): stmt {.immediate.} =
   # dump AST as a side-effect and return the inner node
   let n = callsite()
   echo dumpit(n)
   result = n[1]
-  
+
 dumpAST:
   proc add(x, y: int): int =
     return x + y
-  
+
   proc sub(x, y: int): int = return x - y
 
 
diff --git a/tests/macros/tgensym.nim b/tests/macros/tgensym.nim
index 3f4140ff4..b3aef0a2c 100644
--- a/tests/macros/tgensym.nim
+++ b/tests/macros/tgensym.nim
@@ -2,7 +2,7 @@ import rawsockets, asyncdispatch, macros
 var p = newDispatcher()
 var sock = newAsyncRawSocket()
 
-proc convertReturns(node, retFutureSym: PNimrodNode): PNimrodNode {.compileTime.} =
+proc convertReturns(node, retFutureSym: NimNode): NimNode {.compileTime.} =
   case node.kind
   of nnkReturnStmt:
     result = newCall(newIdentNode("complete"), retFutureSym, node[0])
@@ -19,19 +19,19 @@ macro async2(prc: stmt): stmt {.immediate.} =
   # -> var retFuture = newFuture[T]()
   var retFutureSym = newIdentNode("retFuture") #genSym(nskVar, "retFuture")
   outerProcBody.add(
-    newVarStmt(retFutureSym, 
+    newVarStmt(retFutureSym,
       newCall(
         newNimNode(nnkBracketExpr).add(
           newIdentNode("newFuture"),
           prc[3][0][1])))) # Get type from return type of this proc.
 
-  # -> iterator nameIter(): PFutureBase {.closure.} = <proc_body>
+  # -> iterator nameIter(): FutureBase {.closure.} = <proc_body>
   # Changing this line to: newIdentNode($prc[0].ident & "Iter") # will make it work.
   var iteratorNameSym = genSym(nskIterator, $prc[0].ident & "Iter")
   #var iteratorNameSym = newIdentNode($prc[0].ident & "Iter")
   var procBody = prc[6].convertReturns(retFutureSym)
 
-  var closureIterator = newProc(iteratorNameSym, [newIdentNode("PFutureBase")],
+  var closureIterator = newProc(iteratorNameSym, [newIdentNode("FutureBase")],
                                 procBody, nnkIteratorDef)
   closureIterator[4] = newNimNode(nnkPragma).add(newIdentNode("closure"))
   outerProcBody.add(closureIterator)
@@ -55,8 +55,8 @@ macro async2(prc: stmt): stmt {.immediate.} =
 
   result[6] = outerProcBody
 
-proc readStuff(): PFuture[string] {.async2.} =
-  var fut = connect(sock, "irc.freenode.org", TPort(6667))
+proc readStuff(): Future[string] {.async2.} =
+  var fut = connect(sock, "irc.freenode.org", Port(6667))
   yield fut
   var fut2 = recv(sock, 50)
   yield fut2
diff --git a/tests/macros/tgentemplates.nim b/tests/macros/tgentemplates.nim
index a7727c597..764b94bc7 100644
--- a/tests/macros/tgentemplates.nim
+++ b/tests/macros/tgentemplates.nim
@@ -2,7 +2,7 @@
 
 import parseutils, macros
 
-proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool {.compiletime.} =
+proc parse_until_symbol(node: NimNode, value: string, index: var int): bool {.compiletime.} =
     var splitValue: string
     var read = value.parseUntil(splitValue, '$', index)
 
@@ -15,7 +15,7 @@ proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool
     if splitValue.len > 0:
         node.insert node.len, newCall("add", ident("result"), newStrLitNode(splitValue))
 
-proc parse_template(node: PNimrodNode, value: string) {.compiletime.} =
+proc parse_template(node: NimNode, value: string) {.compiletime.} =
     var index = 0
     while index < value.len and
         parse_until_symbol(node, value, index): discard
diff --git a/tests/macros/tmacro1.nim b/tests/macros/tmacro1.nim
index 3a67c2611..2dd5c31df 100644
--- a/tests/macros/tmacro1.nim
+++ b/tests/macros/tmacro1.nim
@@ -3,17 +3,17 @@ import  macros
 from uri import `/`
 
 macro test*(a: stmt): stmt {.immediate.} =
-  var nodes: tuple[a, b: int]  
+  var nodes: tuple[a, b: int]
   nodes.a = 4
   nodes[1] = 45
-  
+
   type
     TTypeEx = object
       x, y: int
       case b: bool
       of false: nil
       of true: z: float
-      
+
   var t: TTypeEx
   t.b = true
   t.z = 4.5
diff --git a/tests/macros/tmacro3.nim b/tests/macros/tmacro3.nim
index 162212326..d7421ff7f 100644
--- a/tests/macros/tmacro3.nim
+++ b/tests/macros/tmacro3.nim
@@ -4,7 +4,7 @@ discard """
 
 import  macros
 
-type 
+type
     TA = tuple[a: int]
     PA = ref TA
 
@@ -19,7 +19,7 @@ test:
 macro test2*(a: stmt): stmt {.immediate.} =
   proc testproc(recurse: int) =
     echo "Thats weird"
-    var o : PNimrodNode = nil
+    var o : NimNode = nil
     echo "  no its not!"
     o = newNimNode(nnkNone)
     if recurse > 0:
diff --git a/tests/macros/tmacro4.nim b/tests/macros/tmacro4.nim
index 10a23b159..a56369369 100644
--- a/tests/macros/tmacro4.nim
+++ b/tests/macros/tmacro4.nim
@@ -7,7 +7,7 @@ import
 
 macro test_macro*(n: stmt): stmt {.immediate.} =
   result = newNimNode(nnkStmtList)
-  var ass : PNimrodNode = newNimNode(nnkAsgn)
+  var ass : NimNode = newNimNode(nnkAsgn)
   add(ass, newIdentNode("str"))
   add(ass, newStrLitNode("after"))
   add(result, ass)
diff --git a/tests/macros/tmacro5.nim b/tests/macros/tmacro5.nim
index 9882ad90d..d7a4fe8c8 100644
--- a/tests/macros/tmacro5.nim
+++ b/tests/macros/tmacro5.nim
@@ -1,7 +1,7 @@
 import macros,json
 
-var decls{.compileTime.}: seq[PNimrodNode] = @[]
-var impls{.compileTime.}: seq[PNimrodNode] = @[]
+var decls{.compileTime.}: seq[NimNode] = @[]
+var impls{.compileTime.}: seq[NimNode] = @[]
 
 macro importImpl_forward(name, returns): stmt {.immediate.} =
   result = newNimNode(nnkEmpty)
@@ -38,7 +38,7 @@ macro importImpl_forward(name, returns): stmt {.immediate.} =
   decls.add res
   echo(repr(res))
 
-macro importImpl(name, returns: expr, body: stmt): stmt {.immediate.} = 
+macro importImpl(name, returns: expr, body: stmt): stmt {.immediate.} =
   #var res = getAST(importImpl_forward(name, returns))
   discard getAST(importImpl_forward(name, returns))
   var res = copyNimTree(decls[decls.high])
@@ -56,4 +56,4 @@ importImpl(Item, int):
 importImpl(Foo, int16):
   echo 77
 
-okayy
\ No newline at end of file
+okayy
diff --git a/tests/macros/tmacros1.nim b/tests/macros/tmacros1.nim
index 3c814ad6d..1a1073a44 100644
--- a/tests/macros/tmacros1.nim
+++ b/tests/macros/tmacros1.nim
@@ -15,10 +15,10 @@ macro outterMacro*(n: stmt): stmt {.immediate.} =
   expectKind(n, TNimrodNodeKind.nnkCall)
   if n.len != 3 or n[1].kind != TNimrodNodeKind.nnkIdent:
     error("Macro " & callNode.repr &
-      " requires the ident passed as parameter (eg: " & callNode.repr & 
+      " requires the ident passed as parameter (eg: " & callNode.repr &
       "(the_name_you_want)): statements.")
   result = newNimNode(TNimrodNodeKind.nnkStmtList)
-  var ass : PNimrodNode = newNimNode(nnkAsgn)
+  var ass : NimNode = newNimNode(nnkAsgn)
   ass.add(newIdentNode(n[1].ident))
   ass.add(newStrLitNode(innerProc(4)))
   result.add(ass)
diff --git a/tests/macros/tnimnode_for_runtime.nim b/tests/macros/tnimnode_for_runtime.nim
index 69c7aedd2..0520cd0dd 100644
--- a/tests/macros/tnimnode_for_runtime.nim
+++ b/tests/macros/tnimnode_for_runtime.nim
@@ -3,7 +3,7 @@ discard """
 """
 
 import macros
-proc makeMacro: PNimrodNode =
+proc makeMacro: NimNode =
   result = nil
 
 var p = makeMacro()
diff --git a/tests/macros/tstringinterp.nim b/tests/macros/tstringinterp.nim
index a500ed56e..bc79cdaba 100644
--- a/tests/macros/tstringinterp.nim
+++ b/tests/macros/tstringinterp.nim
@@ -19,7 +19,7 @@ template processInterpolations(e: expr) =
 
 macro formatStyleInterpolation(e: expr): expr =
   let e = callsite()
-  var 
+  var
     formatString = ""
     arrayNode = newNimNode(nnkBracket)
     idx = 1
@@ -27,14 +27,14 @@ macro formatStyleInterpolation(e: expr): expr =
   proc addString(s: string) =
     formatString.add(s)
 
-  proc addExpr(e: PNimrodNode) =
+  proc addExpr(e: NimNode) =
     arrayNode.add(e)
     formatString.add("$" & $(idx))
     inc idx
 
   proc addDollar() =
     formatString.add("$$")
-    
+
   processInterpolations(e)
 
   result = parseExpr("\"x\" % [y]")
@@ -43,11 +43,11 @@ macro formatStyleInterpolation(e: expr): expr =
 
 macro concatStyleInterpolation(e: expr): expr =
   let e = callsite()
-  var args: seq[PNimrodNode]
+  var args: seq[NimNode]
   newSeq(args, 0)
 
   proc addString(s: string)    = args.add(newStrLitNode(s))
-  proc addExpr(e: PNimrodNode) = args.add(e)
+  proc addExpr(e: NimNode) = args.add(e)
   proc addDollar()             = args.add(newStrLitNode"$")
 
   processInterpolations(e)
@@ -59,7 +59,7 @@ macro concatStyleInterpolation(e: expr): expr =
 proc sum(a, b, c: int): int =
   return (a + b + c)
 
-var 
+var
   alice = "Alice"
   bob = "Bob"
   a = 10
diff --git a/tests/macros/tvarnimnode.nim b/tests/macros/tvarnimnode.nim
index 73fcc16ea..ab0f66caa 100644
--- a/tests/macros/tvarnimnode.nim
+++ b/tests/macros/tvarnimnode.nim
@@ -6,7 +6,7 @@ discard """
 
 import macros
 
-proc test(f: var PNimrodNode) {.compileTime.} =
+proc test(f: var NimNode) {.compileTime.} =
   f = newNimNode(nnkStmtList)
   f.add newCall(newIdentNode("echo"), newLit(10))
 
diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim
index ae9dfb39f..3026cc4b9 100644
--- a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim
+++ b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim
@@ -18,9 +18,9 @@ proc `$`*[T](x: seq[T]): string =
     result.add($x[i])
   result.add ']'
 
-macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} = 
+macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
   result = newNimNode(nnkStmtList)
-  let 
+  let
     typeName = quoted2ident(typeNameN)
     packetID = ^"p"
     streamID = ^"s"
@@ -66,7 +66,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
     readBody = newNimNode(nnkStmtList)
     lenNames = 0
   for i in 0.. typeFields.len - 1:
-    let 
+    let
       name = typeFields[i][0]
       dotName = packetID.dot(name)
       resName = newIdentNode(!"result").dot(name)
@@ -91,11 +91,11 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
           newNimNode(nnkDiscardStmt).und(
             newCall("readData", streamID, newNimNode(nnkAddr).und(resName), newCall("sizeof", resName))))
         packBody.add(
-          newCall("writeData", streamID, newNimNode(nnkAddr).und(dotName), newCall("sizeof", dotName))) 
+          newCall("writeData", streamID, newNimNode(nnkAddr).und(dotName), newCall("sizeof", dotName)))
       of "seq":
         ## let lenX = readInt16(s)
         newLenName()
-        let 
+        let
           item = ^"item"  ## item name in our iterators
           seqType = typeFields[i][1][1] ## type of seq
           readName = newIdentNode("read"& $seqType.ident)
@@ -107,7 +107,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
         readBody.add(      ## result.name = @[]
           resName := ("@".prefix(newNimNode(nnkBracket))),
           newNimNode(nnkForStmt).und(  ## for item in 1..len:
-            item, 
+            item,
             infix(1.lit, "..", lenName),
             newNimNode(nnkStmtList).und(
               newCall(  ## add(result.name, unpack[seqType](stream))
@@ -117,7 +117,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
           newNimNode(nnkVarSection).und(newNimNode(nnkIdentDefs).und(
             lenName,  ## var lenName = int16(len(p.name))
             newIdentNode("int16"),
-            newCall("int16", newCall("len", dotName)))), 
+            newCall("int16", newCall("len", dotName)))),
           newCall("writeData", streamID, newNimNode(nnkAddr).und(lenName), 2.lit),
           newNimNode(nnkForStmt).und(  ## for item in 0..length - 1: pack(p.name[item], stream)
             item,
@@ -143,8 +143,8 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
         readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
     else:
       error("I dont know what to do with: "& treerepr(typeFields[i]))
-  
-  var 
+
+  var
     toStringFunc = newNimNode(nnkProcDef).und(
       newNimNode(nnkPostfix).und(
         ^"*",
@@ -161,12 +161,12 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
       emptyNode(),
       newNimNode(nnkStmtList).und(#[6]
         newNimNode(nnkAsgn).und(
-          ^"result",                  ## result = 
+          ^"result",                  ## result =
           newNimNode(nnkCall).und(#[6][0][1]
             ^"format",  ## format
             emptyNode()))))  ## "[TypeName   $1   $2]"
     formatStr = "["& $typeName.ident
-  
+
   const emptyFields = {nnkEmpty, nnkNilLit}
   var objFields = newNimNode(nnkRecList)
   for i in 0.. < len(typeFields):
@@ -186,10 +186,10 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
       prefix("$", packetID.dot(fname)))
     formatStr.add "   $"
     formatStr.add($(i + 1))
-  
+
   formatStr.add ']'
   toStringFunc[6][0][1][1] = formatStr.lit()
-  
+
   result.add(
     newNimNode(nnkTypeSection).und(
       newNimNode(nnkTypeDef).und(
@@ -206,15 +206,15 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
   when defined(GenPacketShowOutput):
     echo(repr(result))
 
-proc `->`(a: string, b: string): PNimrodNode {.compileTime.} =
+proc `->`(a: string, b: string): NimNode {.compileTime.} =
   result = newNimNode(nnkIdentDefs).und(^a, ^b, newNimNode(nnkEmpty))
-proc `->`(a: string, b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc `->`(a: string, b: NimNode): NimNode {.compileTime.} =
   result = newNimNode(nnkIdentDefs).und(^a, b, newNimNode(nnkEmpty))
-proc `->`(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc `->`(a, b: NimNode): NimNode {.compileTime.} =
   a[2] = b
   result = a
 
-proc newProc*(name: string, params: varargs[PNimrodNode], resultType: PNimrodNode): PNimrodNode {.compileTime.} =
+proc newProc*(name: string, params: varargs[NimNode], resultType: NimNode): NimNode {.compileTime.} =
   result = newNimNode(nnkProcDef).und(
     ^name,
     emptyNode(),
@@ -227,7 +227,7 @@ proc newProc*(name: string, params: varargs[PNimrodNode], resultType: PNimrodNod
 macro forwardPacket*(typeName: expr, underlyingType: typedesc): stmt {.immediate.} =
   result = newNimNode(nnkStmtList).und(
     newProc(
-      "read"& $typeName.ident, 
+      "read"& $typeName.ident,
       ["s" -> "PStream" -> newNimNode(nnkNilLit)],
       typeName),
     newProc(
@@ -258,21 +258,21 @@ when isMainModule:
       A = 0'i8,
       B, C
   forwardPacket(SomeEnum, int8)
-  
-  
+
+
   defPacket(Foo, tuple[x: array[0..4, int8]])
   var f = newFoo([4'i8, 3'i8, 2'i8, 1'i8, 0'i8])
   var s2 = newStringStream("")
   f.pack(s2)
   assert s2.data == "\4\3\2\1\0"
-  
+
   var s = newStringStream()
   s.flushImpl = proc(s: PStream) =
     var z = PStringStream(s)
     z.setPosition(0)
     z.data.setLen(0)
-  
-  
+
+
   s.setPosition(0)
   s.data.setLen(0)
   var o = B
@@ -283,7 +283,7 @@ when isMainModule:
   o.pack(s)
   assert s.data == "\1\0\2"
   s.flush
-  
+
   defPacket(Y, tuple[z: int8])
   proc `$`(z: Y): string = result = "Y("& $z.z &")"
   defPacket(TestPkt, tuple[x: seq[Y]])
@@ -292,4 +292,4 @@ when isMainModule:
   for itm in test.x:
     echo(itm)
   test.pack(s)
-  echo(repr(s.data))
\ No newline at end of file
+  echo(repr(s.data))
diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim
index 4f2fb1ea3..7cfd67c49 100644
--- a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim
+++ b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim
@@ -9,9 +9,9 @@ template defPacketImports*(): stmt {.immediate, dirty.} =
   import macros, macro_dsl, estreams
   from strutils import format
 
-macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} = 
+macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
   result = newNimNode(nnkStmtList)
-  let 
+  let
     typeName = quoted2ident(typeNameN)
     packetID = ^"p"
     streamID = ^"s"
@@ -57,7 +57,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
     readBody = newNimNode(nnkStmtList)
     lenNames = 0
   for i in 0.. typeFields.len - 1:
-    let 
+    let
       name = typeFields[i][0]
       dotName = packetID.dot(name)
       resName = newIdentNode(!"result").dot(name)
@@ -67,7 +67,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
       of "seq":
         ## let lenX = readInt16(s)
         newLenName()
-        let 
+        let
           item = ^"item"  ## item name in our iterators
           seqType = typeFields[i][1][1] ## type of seq
           readName = newIdentNode("read"& $seqType.ident)
@@ -79,7 +79,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
         readBody.add(      ## result.name = @[]
           resName := ("@".prefix(newNimNode(nnkBracket))),
           newNimNode(nnkForStmt).und(  ## for item in 1..len:
-            item, 
+            item,
             infix(1.lit, "..", lenName),
             newNimNode(nnkStmtList).und(
               newCall(  ## add(result.name, unpack[seqType](stream))
@@ -89,7 +89,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
           newNimNode(nnkVarSection).und(newNimNode(nnkIdentDefs).und(
             lenName,  ## var lenName = int16(len(p.name))
             newIdentNode("int16"),
-            newCall("int16", newCall("len", dotName)))), 
+            newCall("int16", newCall("len", dotName)))),
           newCall("writeBE", streamID, lenName),
           newNimNode(nnkForStmt).und(  ## for item in 0..length - 1: pack(p.name[item], stream)
             item,
@@ -115,8 +115,8 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
         readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
     else:
       error("I dont know what to do with: "& treerepr(typeFields[i]))
-  
-  var 
+
+  var
     toStringFunc = newNimNode(nnkProcDef).und(
       newNimNode(nnkPostfix).und(
         ^"*",
@@ -133,12 +133,12 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
       emptyNode(),
       newNimNode(nnkStmtList).und(#[6]
         newNimNode(nnkAsgn).und(
-          ^"result",                  ## result = 
+          ^"result",                  ## result =
           newNimNode(nnkCall).und(#[6][0][1]
             ^"format",  ## format
             emptyNode()))))  ## "[TypeName   $1   $2]"
     formatStr = "["& $typeName.ident
-  
+
   const emptyFields = {nnkEmpty, nnkNilLit}
   var objFields = newNimNode(nnkRecList)
   for i in 0.. < len(typeFields):
@@ -158,10 +158,10 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
       prefix("$", packetID.dot(fname)))
     formatStr.add "   $"
     formatStr.add($(i + 1))
-  
+
   formatStr.add ']'
   toStringFunc[6][0][1][1] = formatStr.lit()
-  
+
   result.add(
     newNimNode(nnkTypeSection).und(
       newNimNode(nnkTypeDef).und(
@@ -178,7 +178,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
   when defined(GenPacketShowOutput):
     echo(repr(result))
 
-proc newProc*(name: PNimrodNode; params: varargs[PNimrodNode]; resultType: PNimrodNode): PNimrodNode {.compileTime.} =
+proc newProc*(name: NimNode; params: varargs[NimNode]; resultType: NimNode): NimNode {.compileTime.} =
   result = newNimNode(nnkProcDef).und(
     name,
     emptyNode(),
@@ -189,15 +189,15 @@ proc newProc*(name: PNimrodNode; params: varargs[PNimrodNode]; resultType: PNimr
     newNimNode(nnkStmtList))
   result[3].add(params)
 
-proc body*(procNode: PNimrodNode): PNimrodNode {.compileTime.} =
+proc body*(procNode: NimNode): NimNode {.compileTime.} =
   assert procNode.kind == nnkProcDef and procNode[6].kind == nnkStmtList
   result = procNode[6]
 
-proc iddefs*(a, b: string; c: PNimrodNode): PNimrodNode {.compileTime.} =
+proc iddefs*(a, b: string; c: NimNode): NimNode {.compileTime.} =
   result = newNimNode(nnkIdentDefs).und(^a, ^b, c)
-proc iddefs*(a: string; b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc iddefs*(a: string; b: NimNode): NimNode {.compileTime.} =
   result = newNimNode(nnkIdentDefs).und(^a, b, emptyNode())
-proc varTy*(a: PNimrodNode): PNimrodNode {.compileTime.} =
+proc varTy*(a: NimNode): NimNode {.compileTime.} =
   result = newNimNode(nnkVarTy).und(a)
 
 macro forwardPacket*(typeName: expr, underlyingType: expr): stmt {.immediate.} =
@@ -206,7 +206,7 @@ macro forwardPacket*(typeName: expr, underlyingType: expr): stmt {.immediate.} =
     streamID = ^"s"
   result = newNimNode(nnkStmtList).und(
     newProc(
-      (^("read"& $typeName.ident)).postfix("*"), 
+      (^("read"& $typeName.ident)).postfix("*"),
       [ iddefs("s", "PBuffer", newNimNode(nnkNilLit)) ],
       typeName),
     newProc(
@@ -218,7 +218,7 @@ macro forwardPacket*(typeName: expr, underlyingType: expr): stmt {.immediate.} =
     readBody = result[0][6]
     packBody = result[1][6]
     resName = ^"result"
-  
+
   case underlyingType.kind
   of nnkBracketExpr:
     case $underlyingType[0].ident
@@ -250,21 +250,21 @@ when isMainModule:
       A = 0'i8,
       B, C
   forwardPacket(SomeEnum, int8)
-  
-  
+
+
   defPacket(Foo, tuple[x: array[0..4, int8]])
   var f = newFoo([4'i8, 3'i8, 2'i8, 1'i8, 0'i8])
   var s2 = newStringStream("")
   f.pack(s2)
   assert s2.data == "\4\3\2\1\0"
-  
+
   var s = newStringStream()
   s.flushImpl = proc(s: PStream) =
     var z = PStringStream(s)
     z.setPosition(0)
     z.data.setLen(0)
-  
-  
+
+
   s.setPosition(0)
   s.data.setLen(0)
   var o = B
@@ -275,7 +275,7 @@ when isMainModule:
   o.pack(s)
   assert s.data == "\1\0\2"
   s.flush
-  
+
   defPacket(Y, tuple[z: int8])
   proc `$`(z: Y): string = result = "Y("& $z.z &")"
   defPacket(TestPkt, tuple[x: seq[Y]])
diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim b/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim
index c7b577b3d..d3a0c701d 100644
--- a/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim
+++ b/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim
@@ -1,42 +1,42 @@
 import macros
 {.deadCodeElim: on.}
 #Inline macro.add() to allow for easier nesting
-proc und*(a: PNimrodNode; b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc und*(a: NimNode; b: NimNode): NimNode {.compileTime.} =
   a.add(b)
   result = a
-proc und*(a: PNimrodNode; b: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
+proc und*(a: NimNode; b: varargs[NimNode]): NimNode {.compileTime.} =
   a.add(b)
   result = a
 
-proc `^`*(a: string): PNimrodNode {.compileTime.} = 
+proc `^`*(a: string): NimNode {.compileTime.} =
   ## new ident node
   result = newIdentNode(!a)
-proc `[]`*(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc `[]`*(a, b: NimNode): NimNode {.compileTime.} =
   ## new bracket expression: node[node] not to be confused with node[indx]
   result = newNimNode(nnkBracketExpr).und(a, b)
-proc `:=`*(left, right: PNimrodNode): PNimrodNode {.compileTime.} =
+proc `:=`*(left, right: NimNode): NimNode {.compileTime.} =
   ## new Asgn node:  left = right
   result = newNimNode(nnkAsgn).und(left, right)
 
-proc lit*(a: string): PNimrodNode {.compileTime.} =
+proc lit*(a: string): NimNode {.compileTime.} =
   result = newStrLitNode(a)
-proc lit*(a: int): PNimrodNode {.compileTime.} =
+proc lit*(a: int): NimNode {.compileTime.} =
   result = newIntLitNode(a)
-proc lit*(a: float): PNimrodNode {.compileTime.} =
+proc lit*(a: float): NimNode {.compileTime.} =
   result = newFloatLitNode(a)
-proc lit*(a: char): PNimrodNode {.compileTime.} =
+proc lit*(a: char): NimNode {.compileTime.} =
   result = newNimNode(nnkCharLit)
   result.intval = a.ord
 
-proc emptyNode*(): PNimrodNode {.compileTime.} =
+proc emptyNode*(): NimNode {.compileTime.} =
   result = newNimNode(nnkEmpty)
 
-proc dot*(left, right: PNimrodNode): PNimrodNode {.compileTime.} =
+proc dot*(left, right: NimNode): NimNode {.compileTime.} =
   result = newNimNode(nnkDotExpr).und(left, right)
-proc prefix*(a: string, b: PNimrodNode): PNimrodNode {.compileTime.} =
+proc prefix*(a: string, b: NimNode): NimNode {.compileTime.} =
   result = newNimNode(nnkPrefix).und(newIdentNode(!a), b)
 
-proc quoted2ident*(a: PNimrodNode): PNimrodNode {.compileTime.} = 
+proc quoted2ident*(a: NimNode): NimNode {.compileTime.} =
   if a.kind != nnkAccQuoted:
     return a
   var pname = ""
diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim
index 8e47c1f2f..cdd5aaf03 100644
--- a/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim
+++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim
@@ -5,7 +5,8 @@ import
 from strutils import
   formatFloat,
   TFloatFormat,
-  `%`
+  `%`,
+  ffDecimal
 
 from unsigned import
   `shr`,
diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/gl.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/gl.nim
index e731969c1..22d36ef4d 100644
--- a/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/gl.nim
+++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/gl.nim
@@ -54,7 +54,7 @@ else:
     glRealType* = cGLfloat
 
 proc setUniformV4*[T](loc: GLint, vecs: var openarray[TV4[T]]) =
-  glUniform4fv(loc, vecs.len.GLsizei, cast[PGLfloat](vecs[0].addr))
+  glUniform4fv(loc, vecs.len.GLsizei, cast[ptr GLfloat](vecs[0].addr))
 
 proc setUniformV4*[T](loc: GLint, vec: TV4[T]) =
   var vecs = [vec]
diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/primitive.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/primitive.nim
index c67748967..8c26c04eb 100644
--- a/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/primitive.nim
+++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/primitive.nim
@@ -16,7 +16,7 @@ type
     i*      : GLuint
     size*   : GLint
     stride* : GLsizei
-    offset* : PGLvoid
+    offset* : GLvoid
   TVertMode* = enum
     vmTriStrip = GLtriangleStrip,
     vmTriFan   = GLtriangleFan
@@ -44,7 +44,7 @@ proc newVertQuad*(min, minRight, maxLeft, max: TV2[TR]): seq[TVert] =
 proc newVert*(rect: rect.TRect): seq[TVert] =
   newVertQuad(rect.min, newV2(rect.max.x, rect.min.y), newV2(rect.min.x, rect.max.y), rect.max)
 
-proc newVertAttrib(i: GLuint, size: GLint, stride: GLsizei, offset: PGLvoid): TVertAttrib =
+proc newVertAttrib(i: GLuint, size: GLint, stride: GLsizei, offset: GLvoid): TVertAttrib =
   TVertAttrib(i: i, size: size, stride: stride, offset: offset)
 
 proc genBuf*[T](vboTarget, objUsage: GLenum, data: var openarray[T]): GLuint =
@@ -90,7 +90,7 @@ proc disableVertAttribArrs*() =
 proc setVertAttribPointers*() =
   let vertSize {.global.} = TVert.sizeof.GLint
   ?glVertexAttribPointer(0, 2, glRealType, false, vertSize, nil)
-  ?glVertexAttribPointer(1, 2, glRealType, false, vertSize, cast[PGLvoid](TR.sizeof * 2))
+  ?glVertexAttribPointer(1, 2, glRealType, false, vertSize, cast[GLvoid](TR.sizeof * 2))
 
 proc updVerts*(o: PPrimitive, start, `end`: int, f: proc(i: int, vert: var TVert)) =
   assert start <= `end`
@@ -105,7 +105,7 @@ proc updVerts*(o: PPrimitive, start, `end`: int, f: proc(i: int, vert: var TVert
   ?glBufferSubData(GLarrayBuffer,
                    byteOffset.GLintptr, # Offset. Is this right?
                    byteLen.GLsizeiptr, # Size.
-                   cast[PGLvoid](cast[int](o.verts[0].addr) + byteOffset))
+                   cast[GLvoid](cast[int](o.verts[0].addr) + byteOffset))
 
 proc updAllVerts(o: PPrimitive, f: proc(i: int, vert: var TVert)) =
   for i in 0 .. <o.verts.len:
diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/shader.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/shader.nim
index 5972aa4fb..89bb76064 100644
--- a/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/shader.nim
+++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/shader.nim
@@ -25,7 +25,7 @@ proc setSrc*(shader: TShader, src: string) =
   ?glShaderSource(shader.id, 1, cast[cstringarray](s.addr), nil)
 
 proc newShader*(id: GL_handle): TShader =
-  if id != 0 and not (?glIsShader(id)).bool:
+  if id.int != 0 and not (?glIsShader(id)).bool:
     raise newException(E_GL, "Invalid shader ID: " & $id)
 
   result.id = id
@@ -33,7 +33,7 @@ proc newShader*(id: GL_handle): TShader =
 proc shaderInfoLog*(o: TShader): string =
   var log {.global.}: array[0..1024, char]
   var logLen: GLsizei
-  ?glGetShaderInfoLog(o.id, log.len.GLsizei, logLen, cast[PGLchar](log.addr))
+  ?glGetShaderInfoLog(o.id.GLuint, log.len.GLsizei, addr logLen, cast[cstring](log.addr))
   cast[string](log.addr).substr(0, logLen)
 
 proc compile*(shader: TShader, path="") =
@@ -67,7 +67,7 @@ proc attach*(o: TProgram, shader: TShader) =
 proc infoLog*(o: TProgram): string =
   var log {.global.}: array[0..1024, char]
   var logLen: GLsizei
-  ?glGetProgramInfoLog(o.id, log.len.GLsizei, logLen, cast[PGLchar](log.addr))
+  ?glGetProgramInfoLog(o.id.GLuint, log.len.GLsizei, addr logLen, cast[cstring](log.addr))
   cast[string](log.addr).substr(0, logLen)
 
 proc link*(o: TProgram) =
@@ -86,11 +86,11 @@ proc validate*(o: TProgram) =
 
 proc newProgram*(shaders: seq[TShader]): TProgram =
   result.id = ?glCreateProgram()
-  if result.id == 0:
+  if result.id.int == 0:
     return
 
   for shader in shaders:
-    if shader.id == 0:
+    if shader.id.int == 0:
       return
 
     ?result.attach(shader)
diff --git a/tests/misc/tinc.nim b/tests/misc/tinc.nim
index 8038a2a01..b74f85591 100644
--- a/tests/misc/tinc.nim
+++ b/tests/misc/tinc.nim
@@ -1,7 +1,7 @@
 discard """
   file: "tinc.nim"
   line: 8
-  errormsg: "for a \'var\' type a variable needs to be passed"
+  errormsg: "type mismatch: got (int)"
 """
 var x = 0
 
diff --git a/tests/misc/tinout.nim b/tests/misc/tinout.nim
index 034c496f5..4e5908428 100644
--- a/tests/misc/tinout.nim
+++ b/tests/misc/tinout.nim
@@ -1,7 +1,7 @@
 discard """
   file: "tinout.nim"
   line: 12
-  errormsg: "for a \'var\' type a variable needs to be passed"
+  errormsg: "type mismatch: got (int literal(3))"
 """
 # Test in out checking for parameters

 

diff --git a/tests/notnil/tnotnil4.nim b/tests/notnil/tnotnil4.nim
index 23968ee48..2fa888357 100644
--- a/tests/notnil/tnotnil4.nim
+++ b/tests/notnil/tnotnil4.nim
@@ -11,4 +11,10 @@ proc doit() =
    if x[0] != nil:
       check(x[0])
 
-doit()
\ No newline at end of file
+doit()
+
+# bug #2352
+
+proc p(x: proc() {.noconv.} not nil) = discard
+p(proc() {.noconv.} = discard)
+# Error: cannot prove 'proc () {.noconv.} = discard ' is not nil
diff --git a/tests/objvariant/tadrdisc.nim b/tests/objvariant/tadrdisc.nim
index 0e0324562..1afe7d04f 100644
--- a/tests/objvariant/tadrdisc.nim
+++ b/tests/objvariant/tadrdisc.nim
@@ -1,7 +1,7 @@
 discard """
   file: "tadrdisc.nim"
   line: 20
-  errormsg: "for a \'var\' type a variable needs to be passed"
+  errormsg: "type mismatch: got (TKind)"
 """
 # Test that the address of a dicriminants cannot be taken
 
@@ -12,12 +12,9 @@ type
     of ka: x, y: int
     of kb: a, b: string
     of kc: c, d: float
-    
-proc setKind(k: var TKind) = 
-  k = kc
-  
-var a: TA
-setKind(a.k) #ERROR_MSG for a 'var' type a variable needs to be passed
-
 
+proc setKind(k: var TKind) =
+  k = kc
 
+var a: TA
+setKind(a.k)
diff --git a/tests/overload/tspec.nim b/tests/overload/tspec.nim
new file mode 100644
index 000000000..685df503a
--- /dev/null
+++ b/tests/overload/tspec.nim
@@ -0,0 +1,81 @@
+discard """
+  output: '''not a var
+not a var
+a var
+B
+int
+T
+int16
+T
+ref T
+123
+2
+1
+@[123, 2, 1]'''
+"""
+
+# Things that's even in the spec now!
+
+proc byvar(x: var int) = echo "a var"
+proc byvar(x: int) = echo "not a var"
+byvar(89)
+
+let letSym = 0
+var varSym = 13
+
+byvar(letSym)
+byvar(varSym)
+
+type
+  A = object of RootObj
+  B = object of A
+  C = object of B
+
+proc p(obj: A) =
+  echo "A"
+
+proc p(obj: B) =
+  echo "B"
+
+var c = C()
+# not ambiguous, calls 'B', not 'A' since B is a subtype of A
+# but not vice versa:
+p(c)
+
+proc pp(obj: A, obj2: B) = echo "A B"
+proc pp(obj: B, obj2: A) = echo "B A"
+
+# but this is ambiguous:
+#pp(c, c)
+
+proc takesInt(x: int) = echo "int"
+proc takesInt[T](x: T) = echo "T"
+proc takesInt(x: int16) = echo "int16"
+
+takesInt(4) # "int"
+var x: int32
+takesInt(x) # "T"
+var y: int16
+takesInt(y) # "int16"
+var z: range[0..4] = 0
+takesInt(z) # "T"
+
+proc gen[T](x: ref ref T) = echo "ref ref T"
+proc gen[T](x: ref T) = echo "ref T"
+proc gen[T](x: T) = echo "T"
+
+var ri: ref int
+gen(ri) # "ref T"
+
+
+template rem(x: expr) = discard
+#proc rem[T](x: T) = discard
+
+rem unresolvedExpression(undeclaredIdentifier)
+
+
+proc takeV[T](a: varargs[T]) =
+  for x in a: echo x
+
+takeV([123, 2, 1]) # takeV's T is "int", not "array of int"
+echo(@[123, 2, 1])
diff --git a/tests/parallel/tarray_of_channels.nim b/tests/parallel/tarray_of_channels.nim
new file mode 100644
index 000000000..11b523401
--- /dev/null
+++ b/tests/parallel/tarray_of_channels.nim
@@ -0,0 +1,26 @@
+# bug #2257
+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 consumer(ix : int) {.thread.} =
+  echo channels[ix].recv() ###### not GC-safe: 'channels'
+  echo globalB
+
+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/tdont_be_stupid.nim b/tests/parallel/tdont_be_stupid.nim
new file mode 100644
index 000000000..a7e82466a
--- /dev/null
+++ b/tests/parallel/tdont_be_stupid.nim
@@ -0,0 +1,15 @@
+
+import threadpool, os
+
+proc single(time: int) =
+  sleep time
+  echo time
+
+proc sleepsort(nums: openArray[int]) =
+  parallel:
+    var i = 0
+    while i <= len(nums) + -1:
+      spawn single(nums[i])
+      i += 1
+
+sleepsort([50,3,40,25])
diff --git a/tests/parallel/tgc_unsafe.nim b/tests/parallel/tgc_unsafe.nim
new file mode 100644
index 000000000..6548bbec8
--- /dev/null
+++ b/tests/parallel/tgc_unsafe.nim
@@ -0,0 +1,32 @@
+discard """
+  errormsg: "'consumer' is not GC-safe"
+  line: 19
+"""
+
+# bug #2257
+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 consumer(ix : int) {.thread.} =
+  echo channels[ix].recv() ###### not GC-safe: 'channels'
+  echo global
+  echo globalB
+
+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/showoff/tdrdobbs_examples.nim b/tests/showoff/tdrdobbs_examples.nim
index 13a685950..78f711325 100644
--- a/tests/showoff/tdrdobbs_examples.nim
+++ b/tests/showoff/tdrdobbs_examples.nim
@@ -13,7 +13,7 @@ var g = 70
 ++g
 g ++ 7
 g.`++`(10, 20)
-echo g 
+echo g
 
 
 #let lv = stdin.readline
@@ -56,7 +56,7 @@ type
     fkLit,        ## element is a literal like 0.1
     fkAdd,        ## element is an addition operation
     fkMul,        ## element is a multiplication operation
-    fkExp         ## element is an exponentiation operation 
+    fkExp         ## element is an exponentiation operation
 
 type
   Formula = ref object
@@ -78,16 +78,16 @@ proc evaluate(n: Formula, varToVal: proc (name: string): float): float =
 echo evaluate(Formula(kind: fkLit, value: 0.4), nil)
 
 proc isPolyTerm(n: Formula): bool =
-  n.kind == fkMul and n.left.kind == fkLit and (let e = n.right; 
+  n.kind == fkMul and n.left.kind == fkLit and (let e = n.right;
     e.kind == fkExp and e.left.kind == fkVar and e.right.kind == fkLit)
 
 proc isPolynomial(n: Formula): bool =
-  isPolyTerm(n) or 
+  isPolyTerm(n) or
     (n.kind == fkAdd and isPolynomial(n.left) and isPolynomial(n.right))
 
 let myFormula = Formula(kind: fkMul,
                         left: Formula(kind: fkLit, value: 2.0),
-                        right: Formula(kind: fkExp, 
+                        right: Formula(kind: fkExp,
                           left: Formula(kind: fkVar, name: "x"),
                           right: Formula(kind: fkLit, value: 5.0)))
 
@@ -104,7 +104,7 @@ proc pat2kind(pattern: string): FormulaKind =
 
 import macros
 
-proc matchAgainst(n, pattern: PNimrodNode): PNimrodNode {.compileTime.} =
+proc matchAgainst(n, pattern: NimNode): NimNode {.compileTime.} =
   template `@`(current, field: expr): expr =
     newDotExpr(current, newIdentNode(astToStr(field)))
 
diff --git a/tests/template/t_otemplates.nim b/tests/template/t_otemplates.nim
index 1a9075d20..db535d818 100644
--- a/tests/template/t_otemplates.nim
+++ b/tests/template/t_otemplates.nim
@@ -18,7 +18,7 @@ const identChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}
 

 

 # Procedure Declarations

-proc parse_template(node: PNimrodNode, value: string) {.compiletime.}

+proc parse_template(node: NimNode, value: string) {.compiletime.}

 

 

 # Procedure Definitions

@@ -166,7 +166,7 @@ iterator parse_compound_statements(value, identifier: string, index: int): strin
             get_next_ident(["try", "$except", "$finally"])

 

 

-proc parse_complex_stmt(value, identifier: string, index: var int): PNimrodNode {.compiletime.} =

+proc parse_complex_stmt(value, identifier: string, index: var int): NimNode {.compiletime.} =

     ## Parses if/when/try /elif /else /except /finally statements

 

     # Build up complex statement string

@@ -218,7 +218,7 @@ proc parse_complex_stmt(value, identifier: string, index: var int): PNimrodNode
         inc(resultIndex)

 

 

-proc parse_simple_statement(value: string, index: var int): PNimrodNode {.compiletime.} =

+proc parse_simple_statement(value: string, index: var int): NimNode {.compiletime.} =

     ## Parses for/while

 

     # Detect indentation

@@ -252,7 +252,7 @@ proc parse_simple_statement(value: string, index: var int): PNimrodNode {.compil
     inc(index, value.parse_thru_eol(index))

 

 

-proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool {.compiletime.} =

+proc parse_until_symbol(node: NimNode, value: string, index: var int): bool {.compiletime.} =

     ## Parses a string until a $ symbol is encountered, if

     ## two $$'s are encountered in a row, a split will happen

     ## removing one of the $'s from the resulting output

@@ -311,7 +311,7 @@ proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool
         node.insert insertionPoint, newCall("add", ident("result"), newStrLitNode(splitValue))

 

 

-proc parse_template(node: PNimrodNode, value: string) =

+proc parse_template(node: NimNode, value: string) =

     ## Parses through entire template, outputing valid

     ## Nim code into the input `node` AST.

     var index = 0

diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim
index c293be7e8..cb3649a38 100644
--- a/tests/testament/categories.nim
+++ b/tests/testament/categories.nim
@@ -215,7 +215,7 @@ proc manyLoc(r: var TResults, cat: Category, options: string) =
   for kind, dir in os.walkDir("tests/manyloc"):
     if kind == pcDir:
       let mainfile = findMainFile(dir)
-      if mainfile != ".nim":
+      if mainfile != "":
         testNoSpec r, makeTest(mainfile, options, cat)
 
 proc compileExample(r: var TResults, pattern, options: string, cat: Category) =
diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim
index 7cf902704..4c1173fe3 100644
--- a/tests/testament/tester.nim
+++ b/tests/testament/tester.nim
@@ -146,7 +146,6 @@ proc codegenCheck(test: TTest, check: string, given: var TSpec) =
   try:
     let (path, name, ext2) = test.name.splitFile
     let genFile = generatedFile(path, name, test.target)
-    echo genFile
     let contents = readFile(genFile).string
     if check[0] == '\\':
       # little hack to get 'match' support:
diff --git a/tests/usingstmt/tusingstatement.nim b/tests/usingstmt/tusingstatement.nim
index b58478d74..0d76b2423 100644
--- a/tests/usingstmt/tusingstatement.nim
+++ b/tests/usingstmt/tusingstatement.nim
@@ -3,13 +3,13 @@ discard """
   output: "Using test.Closing test."
 """
 
-import 
+import
   macros
 
 # This macro mimics the using statement from C#
 #
 # It's kept only as a test for the macro system
-# Nim's destructors offer a mechanism for automatic 
+# Nim's destructors offer a mechanism for automatic
 # disposal of resources.
 #
 macro autoClose(e: expr): stmt {.immediate.} =
@@ -20,19 +20,19 @@ macro autoClose(e: expr): stmt {.immediate.} =
 
   var args = e
   var body = e[2]
-  
-  var 
-    variables : seq[PNimrodNode]
-    closingCalls : seq[PNimrodNode]
+
+  var
+    variables : seq[NimNode]
+    closingCalls : seq[NimNode]
 
   newSeq(variables, 0)
   newSeq(closingCalls, 0)
-  
+
   for i in countup(1, args.len-2):
     if args[i].kind == nnkExprEqExpr:
       var varName = args[i][0]
       var varValue = args[i][1]
- 
+
       var varAssignment = newNimNode(nnkIdentDefs)
       varAssignment.add(varName)
       varAssignment.add(newNimNode(nnkEmpty)) # empty means no type
@@ -43,7 +43,7 @@ macro autoClose(e: expr): stmt {.immediate.} =
     else:
       error "Using statement: Unexpected expression. Got " &
         $args[i].kind & " instead of assignment."
-  
+
   var varSection = newNimNode(nnkVarSection)
   varSection.add(variables)
 
@@ -67,10 +67,10 @@ macro autoClose(e: expr): stmt {.immediate.} =
   targetAst[0][1][0] = varSection
   targetAst[0][1][1][0] = body
   targetAst[0][1][1][1][0] = finallyBlock
-  
+
   result = targetAst
 
-type 
+type
   TResource* = object
     field*: string
 
diff --git a/tests/vm/tstringnil.nim b/tests/vm/tstringnil.nim
index 61ce60ee5..bb546b698 100644
--- a/tests/vm/tstringnil.nim
+++ b/tests/vm/tstringnil.nim
@@ -8,9 +8,9 @@ type
     suiteDesc: string
     testName: string
     testDesc: string
-    testBlock: PNimrodNode
+    testBlock: NimNode
 
-proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: PNimrodNode): tuple[tests: seq[SuiteTest]]  {.compileTime.} =
+proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: NimNode): tuple[tests: seq[SuiteTest]]  {.compileTime.} =
   var
     tests:seq[SuiteTest] = @[]
 
@@ -40,7 +40,7 @@ proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: PNimrodNode): tuple[tes
       discard
 
   return (tests: tests)
- 
+
 macro suite(suiteName, suiteDesc: expr, suiteBloc: stmt): stmt {.immediate.} =
   let contents = buildSuiteContents(suiteName, suiteDesc, suiteBloc)
 
diff --git a/todo.txt b/todo.txt
index b77c276b7..e8a393a47 100644
--- a/todo.txt
+++ b/todo.txt
@@ -5,6 +5,7 @@ version 0.10.4
 - make 'nil' work for 'add' and 'len'
 - disallow negative indexing
 - improve the parser; deal with  echo $foo  gotcha
+- add "all threads are blocked" detection to 'spawn'
 
 
 version 1.0
diff --git a/web/news.txt b/web/news.txt
index 7cf1ae28f..a76f0e8bc 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -11,8 +11,21 @@ News
   -----------------------------------------
 
   - Parameter names are finally properly ``gensym``'ed. This can break
-    templates though that used to rely on the fact that they are not. However
-    we found none such beast in the wild. (Bug #1915.)
+    templates though that used to rely on the fact that they are not.
+    (Bug #1915.) This means this doesn't compile anymore:
+
+  .. code-block:: nim
+
+    template doIt(body: stmt) {.immediate.} =
+      # this used to inject the 'str' parameter:
+      proc res(str: string) =
+        body
+
+    doIt:
+      echo str # Error: undeclared identifier: 'str'
+
+    Declare the ``doIt`` template as ``immediate, dirty`` to get the old
+    behaviour.
   - Tuple field names are not ignored anymore, this caused too many problems
     in practice so now the behaviour as it was for version 0.9.6: If field
     names exist for the tuple type, they are checked.