summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/astalgo.nim28
-rw-r--r--compiler/ccgexprs.nim89
-rw-r--r--compiler/ccgutils.nim58
-rw-r--r--compiler/filter_tmpl.nim18
-rw-r--r--compiler/jsgen.nim2
-rw-r--r--compiler/msgs.nim2
-rw-r--r--compiler/nimlexbase.nim2
-rw-r--r--compiler/renderer.nim6
-rw-r--r--compiler/sem.nim46
-rw-r--r--compiler/semcall.nim44
-rw-r--r--compiler/semtypes.nim264
-rw-r--r--compiler/vm.nim46
-rw-r--r--koch.nim2
-rw-r--r--lib/core/macros.nim24
-rw-r--r--lib/impure/re.nim6
-rw-r--r--lib/nimbase.h18
-rw-r--r--lib/packages/docutils/rst.nim4
-rw-r--r--lib/packages/docutils/rstast.nim10
-rw-r--r--lib/packages/docutils/rstgen.nim6
-rw-r--r--lib/pure/algorithm.nim28
-rw-r--r--lib/pure/json.nim2
-rw-r--r--lib/pure/lexbase.nim2
-rw-r--r--lib/pure/parseopt.nim9
-rw-r--r--lib/pure/streams.nim10
-rw-r--r--lib/pure/strutils.nim41
-rw-r--r--lib/pure/times.nim8
-rw-r--r--lib/pure/xmldom.nim12
-rw-r--r--tests/clearmsg/tconsttypemismatch.nim8
-rw-r--r--tests/generics/tgeneric3.nim2
-rw-r--r--tests/manyloc/argument_parser/argument_parser.nim2
-rw-r--r--tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim6
-rw-r--r--tests/manyloc/keineschweine/enet_server/enet_server.nim2
-rw-r--r--tests/manyloc/keineschweine/keineschweine.nim2
-rw-r--r--tests/manyloc/keineschweine/lib/map_filter.nim4
-rw-r--r--tests/manyloc/keineschweine/lib/zlib_helpers.nim10
-rw-r--r--tests/manyloc/keineschweine/server/old_sg_server.nim2
-rw-r--r--tests/stdlib/tstrutil.nim10
-rw-r--r--tests/vm/tconsteval.nim2
-rw-r--r--tools/nimgrep.nim2
-rw-r--r--tools/nimweb.nim4
40 files changed, 465 insertions, 378 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 8d132ab26..c53e53b88 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -203,9 +203,9 @@ proc mustRehash(length, counter: int): bool =
   assert(length > counter)
   result = (length * 2 < counter * 3) or (length - counter < 4)
 
-proc spaces(x: int): PRope = 
+proc rspaces(x: int): PRope = 
   # returns x spaces
-  result = toRope(repeatChar(x))
+  result = toRope(spaces(x))
 
 proc toYamlChar(c: char): string = 
   case c
@@ -253,7 +253,7 @@ proc typeToYamlAux(n: PType, marker: var IntSet,
                    indent, maxRecDepth: int): PRope
 proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int, 
                     maxRecDepth: int): PRope = 
-  var istr = spaces(indent + 2)
+  var istr = rspaces(indent + 2)
   result = toRope("[")
   var mycount = 0
   for i in countup(0, high(n.data)): 
@@ -262,20 +262,20 @@ proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int,
       appf(result, "$N$1$2", 
            [istr, symToYamlAux(n.data[i], marker, indent + 2, maxRecDepth - 1)])
       inc(mycount)
-  if mycount > 0: appf(result, "$N$1", [spaces(indent)])
+  if mycount > 0: appf(result, "$N$1", [rspaces(indent)])
   app(result, "]")
   assert(mycount == n.counter)
 
 proc ropeConstr(indent: int, c: openArray[PRope]): PRope = 
   # array of (name, value) pairs
-  var istr = spaces(indent + 2)
+  var istr = rspaces(indent + 2)
   result = toRope("{")
   var i = 0
   while i <= high(c): 
     if i > 0: app(result, ",")
     appf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]])
     inc(i, 2)
-  appf(result, "$N$1}", [spaces(indent)])
+  appf(result, "$N$1}", [rspaces(indent)])
 
 proc symToYamlAux(n: PSym, marker: var IntSet, indent: int, 
                   maxRecDepth: int): PRope = 
@@ -310,9 +310,9 @@ proc typeToYamlAux(n: PType, marker: var IntSet, indent: int,
       result = toRope("[")
       for i in countup(0, sonsLen(n) - 1): 
         if i > 0: app(result, ",")
-        appf(result, "$N$1$2", [spaces(indent + 4), typeToYamlAux(n.sons[i], 
+        appf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(n.sons[i], 
             marker, indent + 4, maxRecDepth - 1)])
-      appf(result, "$N$1]", [spaces(indent + 2)])
+      appf(result, "$N$1]", [rspaces(indent + 2)])
     else: 
       result = toRope("null")
     result = ropeConstr(indent, [toRope("kind"), 
@@ -331,7 +331,7 @@ proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int,
   if n == nil: 
     result = toRope("null")
   else: 
-    var istr = spaces(indent + 2)
+    var istr = rspaces(indent + 2)
     result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
     if maxRecDepth != 0: 
       appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
@@ -359,12 +359,12 @@ proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int,
           appf(result, ",$N$1\"sons\": [", [istr])
           for i in countup(0, sonsLen(n) - 1): 
             if i > 0: app(result, ",")
-            appf(result, "$N$1$2", [spaces(indent + 4), treeToYamlAux(n.sons[i], 
+            appf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(n.sons[i], 
                 marker, indent + 4, maxRecDepth - 1)])
           appf(result, "$N$1]", [istr])
       appf(result, ",$N$1\"typ\": $2", 
            [istr, typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth)])
-    appf(result, "$N$1}", [spaces(indent)])
+    appf(result, "$N$1}", [rspaces(indent)])
 
 proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope = 
   var marker = initIntSet()
@@ -408,7 +408,7 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int;
   if n == nil: 
     result = toRope("null")
   else: 
-    var istr = spaces(indent + 2)
+    var istr = rspaces(indent + 2)
     result = ropef("{$N$1\"kind\": $2", 
                    [istr, makeYamlString($n.kind)])
     if maxRecDepth != 0: 
@@ -440,11 +440,11 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int;
           appf(result, ",$N$1\"sons\": [", [istr])
           for i in countup(0, sonsLen(n) - 1): 
             if i > 0: app(result, ",")
-            appf(result, "$N$1$2", [spaces(indent + 4), debugTree(n.sons[i], 
+            appf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i], 
                 indent + 4, maxRecDepth - 1, renderType)])
           appf(result, "$N$1]", [istr])
     appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
-    appf(result, "$N$1}", [spaces(indent)])
+    appf(result, "$N$1}", [rspaces(indent)])
 
 proc debug(n: PSym) =
   if n == nil:
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 3bc0d8afb..564d1fd36 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -56,11 +56,6 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
     case skipTypes(ty, abstractVarRange).kind
     of tyChar, tyNil:
       result = intLiteral(n.intVal)
-    of tyInt:
-      if n.intVal >= low(int32) and n.intVal <= high(int32):
-        result = int32Literal(int32(n.intVal))
-      else:
-        result = intLiteral(n.intVal)
     of tyBool:
       if n.intVal != 0: result = ~"NIM_TRUE"
       else: result = ~"NIM_FALSE"
@@ -89,7 +84,7 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
       var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
       if id == gBackendId:
         # string literal not found in the cache:
-        result = ropecg(p.module, "((#NimStringDesc*) &$1)", 
+        result = ropecg(p.module, "((#NimStringDesc*) &$1)",
                         [getStrLit(p.module, n.strVal)])
       else:
         result = ropecg(p.module, "((#NimStringDesc*) &TMP$1)", [toRope(id)])
@@ -158,7 +153,7 @@ proc getStorageLoc(n: PNode): TStorageLoc =
     of skVar, skForVar, skResult, skLet:
       if sfGlobal in n.sym.flags: result = OnHeap
       else: result = OnStack
-    of skConst: 
+    of skConst:
       if sfGlobal in n.sym.flags: result = OnHeap
       else: result = OnUnknown
     else: result = OnUnknown
@@ -236,7 +231,7 @@ proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
   for i in 0 .. <t.len:
     let t = t.sons[i]
     let field = ropef("Field$1", i.toRope)
-    genAssignment(p, optAsgnLoc(dest, t, field), 
+    genAssignment(p, optAsgnLoc(dest, t, field),
                      optAsgnLoc(src, t, field), newflags)
 
 proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags,
@@ -252,20 +247,20 @@ proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags,
   case t.kind
   of nkSym:
     let field = t.sym
-    genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r), 
+    genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r),
                      optAsgnLoc(src, field.typ, field.loc.r), newflags)
   of nkRecList:
     for child in items(t): genOptAsgnObject(p, dest, src, newflags, child)
   else: discard
 
 proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
-  # Consider: 
+  # Consider:
   # type TMyFastString {.shallow.} = string
   # Due to the implementation of pragmas this would end up to set the
   # tfShallow flag for the built-in string type too! So we check only
   # here for this flag, where it is reasonably safe to do so
   # (for objects, etc.):
-  if needToCopy notin flags or 
+  if needToCopy notin flags or
       tfShallow in skipTypes(dest.t, abstractVarRange).flags:
     if dest.s == OnStack or not usesNativeGC():
       useStringh(p.module)
@@ -510,7 +505,7 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
     var storage: PRope
     var size = getSize(t)
     if size < platform.intSize:
-      storage = toRope("NI") 
+      storage = toRope("NI")
     else:
       storage = getTypeDesc(p.module, t)
     var tmp = getTempName()
@@ -547,7 +542,7 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       "(($4)($1) - ($4)($2))", # SubF64
       "(($4)($1) * ($4)($2))", # MulF64
       "(($4)($1) / ($4)($2))", # DivF64
-      
+
       "($4)((NU$3)($1) >> (NU$3)($2))", # ShrI
       "($4)((NU$3)($1) << (NU$3)($2))", # ShlI
       "($4)($1 & $2)",      # BitandI
@@ -617,7 +612,7 @@ proc genEqProc(p: BProc, e: PNode, d: var TLoc) =
   initLocExpr(p, e.sons[1], a)
   initLocExpr(p, e.sons[2], b)
   if a.t.callConv == ccClosure:
-    putIntoDest(p, d, e.typ, 
+    putIntoDest(p, d, e.typ,
       ropef("($1.ClPrc == $2.ClPrc && $1.ClEnv == $2.ClEnv)", [
       rdLoc(a), rdLoc(b)]))
   else:
@@ -721,7 +716,7 @@ template inheritLocation(d: var TLoc, a: TLoc) =
   if d.k == locNone: d.s = a.s
   if d.heapRoot == nil:
     d.heapRoot = if a.heapRoot != nil: a.heapRoot else: a.r
-  
+
 proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType =
   initLocExpr(p, e.sons[0], a)
   if e.sons[1].kind != nkSym: internalError(e.info, "genRecordFieldAux")
@@ -954,7 +949,7 @@ proc genEcho(p: BProc, n: PNode) =
     initLocExpr(p, n.sons[i], a)
     appf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)])
   linefmt(p, cpsStmts, "printf($1$2);$n",
-          makeCString(repeatStr(n.len, "%s") & tnl), args)
+          makeCString(repeat("%s", n.len) & tnl), args)
 
 proc gcUsage(n: PNode) =
   if gSelectedGC == gcNone: message(n.info, warnGcMem, n.renderTree)
@@ -1061,7 +1056,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
   genAssignment(p, dest, b, {needToCopy, afDestIsNil})
   gcUsage(e)
 
-proc genReset(p: BProc, n: PNode) = 
+proc genReset(p: BProc, n: PNode) =
   var a: TLoc
   initLocExpr(p, n.sons[1], a)
   linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
@@ -1120,14 +1115,14 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) =
   else:
     call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
     genAssignment(p, dest, call, {needToKeepAlive})
-  
+
 proc genNewSeq(p: BProc, e: PNode) =
   var a, b: TLoc
   initLocExpr(p, e.sons[1], a)
   initLocExpr(p, e.sons[2], b)
   genNewSeqAux(p, a, b.rdLoc)
   gcUsage(e)
-  
+
 proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
   var tmp: TLoc
   var t = e.typ.skipTypes(abstractInst)
@@ -1168,7 +1163,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
     d = tmp
   else:
     genAssignment(p, d, tmp, {})
-  
+
 proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) =
   var arr: TLoc
   if d.k == locNone:
@@ -1192,7 +1187,7 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
     getTemp(p, t.typ, d)
   # generate call to newSeq before adding the elements per hand:
   var L = int(lengthOrd(t.sons[1].typ))
-  
+
   genNewSeqAux(p, d, intLiteral(L))
   initLocExpr(p, t.sons[1], a)
   for i in countup(0, L - 1):
@@ -1202,7 +1197,7 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
     initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s)
     arr.r = rfmt(nil, "$1[$2]", rdLoc(a), intLiteral(i))
     genAssignment(p, elem, arr, {afDestIsNil, needToCopy})
-  
+
 proc genNewFinalize(p: BProc, e: PNode) =
   var
     a, b, f: TLoc
@@ -1258,7 +1253,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
       app(r, ~".Sup")
       t = skipTypes(t.sons[0], typedescInst)
   if isObjLackingTypeField(t):
-    globalError(x.info, errGenerated, 
+    globalError(x.info, errGenerated,
       "no 'of' operator available for pure objects")
   if nilCheck != nil:
     r = rfmt(p.module, "(($1) && ($2))", nilCheck, genOfHelper(p, dest, r))
@@ -1275,7 +1270,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
   var t = skipTypes(e.sons[1].typ, abstractVarRange)
   case t.kind
   of tyInt..tyInt64, tyUInt..tyUInt64:
-    putIntoDest(p, d, e.typ, 
+    putIntoDest(p, d, e.typ,
                 ropecg(p.module, "#reprInt((NI64)$1)", [rdLoc(a)]))
   of tyFloat..tyFloat128:
     putIntoDest(p, d, e.typ, ropecg(p.module, "#reprFloat($1)", [rdLoc(a)]))
@@ -1298,13 +1293,13 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
     of tyOpenArray, tyVarargs:
       putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
     of tyString, tySequence:
-      putIntoDest(p, b, e.typ, 
+      putIntoDest(p, b, e.typ,
                   ropef("$1->data, $1->$2", [rdLoc(a), lenField(p)]))
     of tyArray, tyArrayConstr:
       putIntoDest(p, b, e.typ,
                   ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
     else: internalError(e.sons[0].info, "genRepr()")
-    putIntoDest(p, d, e.typ, 
+    putIntoDest(p, d, e.typ,
         ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b),
         genTypeInfo(p.module, elemType(t))]))
   of tyCString, tyArray, tyArrayConstr, tyRef, tyPtr, tyPointer, tyNil,
@@ -1433,7 +1428,7 @@ proc genInOp(p: BProc, e: PNode, d: var TLoc) =
     # do not emit the set, but generate a bunch of comparisons; and if we do
     # so, we skip the unnecessary range check: This is a semantical extension
     # that code now relies on. :-/ XXX
-    let ea = if e.sons[2].kind in {nkChckRange, nkChckRange64}: 
+    let ea = if e.sons[2].kind in {nkChckRange, nkChckRange64}:
                e.sons[2].sons[0]
              else:
                e.sons[2]
@@ -1518,7 +1513,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       initLocExpr(p, e.sons[2], b)
       if d.k == locNone: getTemp(p, a.t, d)
       lineF(p, cpsStmts,
-           "for ($1 = 0; $1 < $2; $1++) $n" & 
+           "for ($1 = 0; $1 < $2; $1++) $n" &
            "  $3[$1] = $4[$1] $6 $5[$1];$n", [
           rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b),
           toRope(lookupOpr[op])])
@@ -1549,7 +1544,7 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) =
 
 proc genCast(p: BProc, e: PNode, d: var TLoc) =
   const floatTypes = {tyFloat..tyFloat128}
-  let 
+  let
     destt = skipTypes(e.typ, abstractRange)
     srct = skipTypes(e.sons[1].typ, abstractRange)
   if destt.kind in floatTypes or srct.kind in floatTypes:
@@ -1656,7 +1651,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mRepr: genRepr(p, e, d)
   of mGetTypeInfo: genGetTypeInfo(p, e, d)
   of mSwap: genSwap(p, e, d)
-  of mUnaryLt: 
+  of mUnaryLt:
     if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)")
     else: unaryExpr(p, e, d, "#subInt($1, 1)")
   of mPred:
@@ -1830,10 +1825,10 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
 proc isConstClosure(n: PNode): bool {.inline.} =
   result = n.sons[0].kind == nkSym and isRoutine(n.sons[0].sym) and
       n.sons[1].kind == nkNilLit
-      
+
 proc genClosure(p: BProc, n: PNode, d: var TLoc) =
   assert n.kind == nkClosure
-  
+
   if isConstClosure(n):
     inc(p.labels)
     var tmp = con("LOC", toRope(p.labels))
@@ -1920,7 +1915,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
     if isRef:
       # it can happen that we end up generating '&&x->Sup' here, so we pack
       # the '&x->Sup' into a temporary and then those address is taken
-      # (see bug #837). However sometimes using a temporary is not correct: 
+      # (see bug #837). However sometimes using a temporary is not correct:
       # init(TFigure(my)) # where it is passed to a 'var TFigure'. We test
       # this by ensuring the destination is also a pointer:
       if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}:
@@ -1937,13 +1932,13 @@ proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
   discard getTypeDesc(p.module, t) # so that any fields are initialized
   var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
   var tmp = con("TMP", toRope(id))
-  
+
   if id == gBackendId:
     # expression not found in the cache:
     inc(gBackendId)
     appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
          [getTypeDesc(p.module, t), tmp, genConstExpr(p, n)])
-  
+
   if d.k == locNone:
     fillLoc(d, locData, t, tmp, OnHeap)
   else:
@@ -1984,7 +1979,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
         internalError n.info, "expr: var not init " & sym.name.s & "_" & $sym.id
       if sfThread in sym.flags:
         accessThreadLocalVar(p, sym)
-        if emulatedThreadVars(): 
+        if emulatedThreadVars():
           putIntoDest(p, d, sym.loc.t, con("NimTV->", sym.loc.r))
         else:
           putLocIntoDest(p, d, sym.loc)
@@ -2001,7 +1996,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
         #echo "FAILED FOR PRCO ", p.prc.name.s
         #debug p.prc.typ.n
         #echo renderTree(p.prc.ast, {renderIds})
-        internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id)          
+        internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id)
       putLocIntoDest(p, d, sym.loc)
     else: internalError(n.info, "expr(" & $sym.kind & "); unknown symbol")
   of nkNilLit:
@@ -2101,9 +2096,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
     # we have to emit the type information for object types here to support
     # separate compilation:
     genTypeSection(p.module, n)
-  of nkCommentStmt, nkIteratorDef, nkIncludeStmt, 
-     nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt, 
-     nkFromStmt, nkTemplateDef, nkMacroDef: 
+  of nkCommentStmt, nkIteratorDef, nkIncludeStmt,
+     nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
+     nkFromStmt, nkTemplateDef, nkMacroDef:
     discard
   of nkPragma: genPragma(p, n)
   of nkPragmaBlock: expr(p, n.lastSon, d)
@@ -2118,8 +2113,8 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
             sfDeadCodeElim notin getModule(prc).flags) or
             ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
             (sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
-            (prc.kind == skMethod): 
-          # we have not only the header: 
+            (prc.kind == skMethod):
+          # we have not only the header:
           if prc.getBody.kind != nkEmpty or lfDynamicLib in prc.loc.flags:
             genProc(p.module, prc)
   of nkParForStmt: genParForStmt(p, n)
@@ -2142,7 +2137,7 @@ proc genConstSimpleList(p: BProc, n: PNode): PRope =
 
 proc genConstSeq(p: BProc, n: PNode, t: PType): PRope =
   var data = ropef("{{$1, $1}", n.len.toRope)
-  if n.len > 0: 
+  if n.len > 0:
     # array part needs extra curlies:
     data.app(", {")
     for i in countup(0, n.len - 1):
@@ -2150,14 +2145,14 @@ proc genConstSeq(p: BProc, n: PNode, t: PType): PRope =
       data.app genConstExpr(p, n.sons[i])
     data.app("}")
   data.app("}")
-  
+
   inc(gBackendId)
   result = con("CNSTSEQ", gBackendId.toRope)
-  
+
   appcg(p.module, cfsData,
-        "NIM_CONST struct {$n" & 
+        "NIM_CONST struct {$n" &
         "  #TGenericSeq Sup;$n" &
-        "  $1 data[$2];$n" & 
+        "  $1 data[$2];$n" &
         "} $3 = $4;$n", [
         getTypeDesc(p.module, t.sons[0]), n.len.toRope, result, data])
 
diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim
index 59b9611fc..25c1a12e5 100644
--- a/compiler/ccgutils.nim
+++ b/compiler/ccgutils.nim
@@ -9,31 +9,31 @@
 
 # This module declares some helpers for the C code generator.
 
-import 
-  ast, astalgo, ropes, lists, hashes, strutils, types, msgs, wordrecg, 
+import
+  ast, astalgo, ropes, lists, hashes, strutils, types, msgs, wordrecg,
   platform, trees
 
 proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
   case n.kind
-  of nkStmtList: 
-    for i in 0 .. < n.len: 
+  of nkStmtList:
+    for i in 0 .. < n.len:
       result = getPragmaStmt(n[i], w)
       if result != nil: break
   of nkPragma:
-    for i in 0 .. < n.len: 
+    for i in 0 .. < n.len:
       if whichPragma(n[i]) == w: return n[i]
   else: discard
 
 proc stmtsContainPragma*(n: PNode, w: TSpecialWord): bool =
   result = getPragmaStmt(n, w) != nil
 
-proc hashString*(s: string): BiggestInt = 
+proc hashString*(s: string): BiggestInt =
   # has to be the same algorithm as system.hashString!
-  if CPU[targetCPU].bit == 64: 
+  if CPU[targetCPU].bit == 64:
     # we have to use the same bitwidth
     # as the target CPU
     var b = 0'i64
-    for i in countup(0, len(s) - 1): 
+    for i in countup(0, len(s) - 1):
       b = b +% ord(s[i])
       b = b +% `shl`(b, 10)
       b = b xor `shr`(b, 6)
@@ -41,9 +41,9 @@ proc hashString*(s: string): BiggestInt =
     b = b xor `shr`(b, 11)
     b = b +% `shl`(b, 15)
     result = b
-  else: 
+  else:
     var a = 0'i32
-    for i in countup(0, len(s) - 1): 
+    for i in countup(0, len(s) - 1):
       a = a +% ord(s[i]).int32
       a = a +% `shl`(a, 10'i32)
       a = a xor `shr`(a, 6'i32)
@@ -52,11 +52,11 @@ proc hashString*(s: string): BiggestInt =
     a = a +% `shl`(a, 15'i32)
     result = a
 
-var 
+var
   gTypeTable: array[TTypeKind, TIdTable]
   gCanonicalTypes: array[TTypeKind, PType]
 
-proc initTypeTables() = 
+proc initTypeTables() =
   for i in countup(low(TTypeKind), high(TTypeKind)): initIdTable(gTypeTable[i])
 
 proc resetCaches* =
@@ -67,7 +67,7 @@ proc resetCaches* =
 
 when false:
   proc echoStats*() =
-    for i in countup(low(TTypeKind), high(TTypeKind)): 
+    for i in countup(low(TTypeKind), high(TTypeKind)):
       echo i, " ", gTypeTable[i].counter
 
 proc slowSearch(key: PType; k: TTypeKind): PType =
@@ -78,21 +78,21 @@ proc slowSearch(key: PType; k: TTypeKind): PType =
   if idTableHasObjectAsKey(gTypeTable[k], key): return key
   for h in countup(0, high(gTypeTable[k].data)):
     var t = PType(gTypeTable[k].data[h].key)
-    if t != nil and sameBackendType(t, key): 
+    if t != nil and sameBackendType(t, key):
       return t
   idTablePut(gTypeTable[k], key, key)
   result = key
 
-proc getUniqueType*(key: PType): PType = 
+proc getUniqueType*(key: PType): PType =
   # this is a hotspot in the compiler!
-  if key == nil: return 
+  if key == nil: return
   var k = key.kind
   case k
   of tyBool, tyChar, tyInt..tyUInt64:
     # no canonicalization for integral types, so that e.g. ``pid_t`` is
     # produced instead of ``NI``.
     result = key
-  of  tyEmpty, tyNil, tyExpr, tyStmt, tyPointer, tyString, 
+  of  tyEmpty, tyNil, tyExpr, tyStmt, tyPointer, tyString,
       tyCString, tyNone, tyBigNum:
     result = gCanonicalTypes[k]
     if result == nil:
@@ -127,7 +127,7 @@ proc getUniqueType*(key: PType): PType =
     if tfFromGeneric notin key.flags:
       # fast case; lookup per id suffices:
       result = PType(idTableGet(gTypeTable[k], key))
-      if result == nil: 
+      if result == nil:
         idTablePut(gTypeTable[k], key, key)
         result = key
     else:
@@ -138,10 +138,10 @@ proc getUniqueType*(key: PType): PType =
         if t != nil and sameBackendType(t, key):
           return t
       idTablePut(gTypeTable[k], key, key)
-      result = key    
+      result = key
   of tyEnum:
     result = PType(idTableGet(gTypeTable[k], key))
-    if result == nil: 
+    if result == nil:
       idTablePut(gTypeTable[k], key, key)
       result = key
   of tyProc:
@@ -151,16 +151,16 @@ proc getUniqueType*(key: PType): PType =
       # ugh, we need the canon here:
       result = slowSearch(key, k)
 
-proc tableGetType*(tab: TIdTable, key: PType): RootRef = 
+proc tableGetType*(tab: TIdTable, key: PType): RootRef =
   # returns nil if we need to declare this type
   result = idTableGet(tab, key)
-  if (result == nil) and (tab.counter > 0): 
+  if (result == nil) and (tab.counter > 0):
     # we have to do a slow linear search because types may need
     # to be compared by their structure:
-    for h in countup(0, high(tab.data)): 
+    for h in countup(0, high(tab.data)):
       var t = PType(tab.data[h].key)
-      if t != nil: 
-        if sameType(t, key): 
+      if t != nil:
+        if sameType(t, key):
           return tab.data[h].val
 
 proc makeSingleLineCString*(s: string): string =
@@ -193,16 +193,16 @@ proc mangle*(name: string): string =
     else:
       add(result, "HEX" & toHex(ord(c), 2))
 
-proc makeLLVMString*(s: string): PRope = 
+proc makeLLVMString*(s: string): PRope =
   const MaxLineLength = 64
   result = nil
   var res = "c\""
-  for i in countup(0, len(s) - 1): 
-    if (i + 1) mod MaxLineLength == 0: 
+  for i in countup(0, len(s) - 1):
+    if (i + 1) mod MaxLineLength == 0:
       app(result, toRope(res))
       setLen(res, 0)
     case s[i]
-    of '\0'..'\x1F', '\x80'..'\xFF', '\"', '\\': 
+    of '\0'..'\x1F', '\x80'..'\xFF', '\"', '\\':
       add(res, '\\')
       add(res, toHex(ord(s[i]), 2))
     else: add(res, s[i])
diff --git a/compiler/filter_tmpl.nim b/compiler/filter_tmpl.nim
index 7b975dbaa..5d1f73be4 100644
--- a/compiler/filter_tmpl.nim
+++ b/compiler/filter_tmpl.nim
@@ -37,11 +37,11 @@ const
   PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '.', '_'}
 
 proc newLine(p: var TTmplParser) = 
-  llStreamWrite(p.outp, repeatChar(p.emitPar, ')'))
+  llStreamWrite(p.outp, repeat(')', p.emitPar))
   p.emitPar = 0
   if p.info.line > int16(1): llStreamWrite(p.outp, "\n")
   if p.pendingExprLine:
-    llStreamWrite(p.outp, repeatChar(2))
+    llStreamWrite(p.outp, spaces(2))
     p.pendingExprLine = false
   
 proc scanPar(p: var TTmplParser, d: int) = 
@@ -88,24 +88,24 @@ proc parseLine(p: var TTmplParser) =
       else: 
         p.info.col = int16(j)
         localError(p.info, errXNotAllowedHere, "end")
-      llStreamWrite(p.outp, repeatChar(p.indent))
+      llStreamWrite(p.outp, spaces(p.indent))
       llStreamWrite(p.outp, "#end")
     of wIf, wWhen, wTry, wWhile, wFor, wBlock, wCase, wProc, wIterator, 
        wConverter, wMacro, wTemplate, wMethod: 
-      llStreamWrite(p.outp, repeatChar(p.indent))
+      llStreamWrite(p.outp, spaces(p.indent))
       llStreamWrite(p.outp, substr(p.x, d))
       inc(p.indent, 2)
     of wElif, wOf, wElse, wExcept, wFinally: 
-      llStreamWrite(p.outp, repeatChar(p.indent - 2))
+      llStreamWrite(p.outp, spaces(p.indent - 2))
       llStreamWrite(p.outp, substr(p.x, d))
     of wLet, wVar, wConst, wType:
-      llStreamWrite(p.outp, repeatChar(p.indent))
+      llStreamWrite(p.outp, spaces(p.indent))
       llStreamWrite(p.outp, substr(p.x, d))
       if not p.x.contains({':', '='}):
         # no inline element --> treat as block:
         inc(p.indent, 2)
     else:
-      llStreamWrite(p.outp, repeatChar(p.indent))
+      llStreamWrite(p.outp, spaces(p.indent))
       llStreamWrite(p.outp, substr(p.x, d))
     p.state = psDirective
   else: 
@@ -120,11 +120,11 @@ proc parseLine(p: var TTmplParser) =
       # next line of string literal:
       llStreamWrite(p.outp, p.conc)
       llStreamWrite(p.outp, "\n")
-      llStreamWrite(p.outp, repeatChar(p.indent + 2))
+      llStreamWrite(p.outp, spaces(p.indent + 2))
       llStreamWrite(p.outp, "\"")
     of psDirective: 
       newLine(p)
-      llStreamWrite(p.outp, repeatChar(p.indent))
+      llStreamWrite(p.outp, spaces(p.indent))
       llStreamWrite(p.outp, p.emit)
       llStreamWrite(p.outp, "(\"")
       inc(p.emitPar)
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 34f842d4a..87847204f 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -780,7 +780,7 @@ proc genIf(p: PProc, n: PNode, r: var TCompRes) =
     moveInto(p, stmt, r)
     appf(p.body, "}$n" | "end$n")
   if p.target == targetJS:
-    app(p.body, repeatChar(toClose, '}') & tnl)
+    app(p.body, repeat('}', toClose) & tnl)
   else:
     for i in 1..toClose: appf(p.body, "end$n")
 
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index a72dedf57..e15cdc86d 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -784,7 +784,7 @@ proc rawMessage*(msg: TMsgKind, arg: string) =
 proc writeSurroundingSrc(info: TLineInfo) =
   const indent = "  "
   msgWriteln(indent & info.sourceLine.ropeToStr)
-  msgWriteln(indent & repeatChar(info.col, ' ') & '^')
+  msgWriteln(indent & spaces(info.col) & '^')
 
 proc formatMsg*(info: TLineInfo, msg: TMsgKind, arg: string): string =
   let frmt = case msg
diff --git a/compiler/nimlexbase.nim b/compiler/nimlexbase.nim
index e18e1c22a..f5db5ca4f 100644
--- a/compiler/nimlexbase.nim
+++ b/compiler/nimlexbase.nim
@@ -166,4 +166,4 @@ proc getCurrentLine(L: TBaseLexer, marker: bool = true): string =
     inc(i)
   result.add("\n")
   if marker: 
-    result.add(repeatChar(getColNumber(L, L.bufpos)) & '^' & "\n")
+    result.add(spaces(getColNumber(L, L.bufpos)) & '^' & "\n")
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 204bfbf94..f5cabb4bc 100644
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -92,7 +92,7 @@ proc addTok(g: var TSrcGen, kind: TTokType, s: string) =
 
 proc addPendingNL(g: var TSrcGen) = 
   if g.pendingNL >= 0: 
-    addTok(g, tkSpaces, "\n" & repeatChar(g.pendingNL))
+    addTok(g, tkSpaces, "\n" & spaces(g.pendingNL))
     g.lineLen = g.pendingNL
     g.pendingNL = - 1
 
@@ -190,7 +190,7 @@ proc putComment(g: var TSrcGen, s: string) =
       if not isCode and (g.lineLen + (j - i) > MaxLineLen): 
         put(g, tkComment, com)
         optNL(g, ind)
-        com = '#' & repeatChar(comIndent)
+        com = '#' & spaces(comIndent)
       while s[i] > ' ': 
         add(com, s[i])
         inc(i)
@@ -280,7 +280,7 @@ proc gcom(g: var TSrcGen, n: PNode) =
         (g.lineLen < LineCommentColumn): 
       var ml = maxLineLength(n.comment)
       if ml + LineCommentColumn <= MaxLineLen: 
-        put(g, tkSpaces, repeatChar(LineCommentColumn - g.lineLen))
+        put(g, tkSpaces, spaces(LineCommentColumn - g.lineLen))
     putComment(g, n.comment)  #assert(g.comStack[high(g.comStack)] = n);
   
 proc gcoms(g: var TSrcGen) = 
diff --git a/compiler/sem.nim b/compiler/sem.nim
index a90948245..36c0342cd 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -65,8 +65,8 @@ template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
         echo "passing to safeSemExpr: ", renderTree(n)
       discard safeSemExpr(c, n)
 
-proc typeMismatch(n: PNode, formal, actual: PType) = 
-  if formal.kind != tyError and actual.kind != tyError: 
+proc typeMismatch(n: PNode, formal, actual: PType) =
+  if formal.kind != tyError and actual.kind != tyError:
     localError(n.info, errGenerated, msgKindToString(errTypeMismatch) &
         typeToString(actual) & ") " &
         `%`(msgKindToString(errButExpectedX), [typeToString(formal)]))
@@ -113,7 +113,7 @@ proc commonType*(x, y: PType): PType =
     else:
       result = newType(tyTypeDesc, a.owner)
       rawAddSon(result, newType(tyNone, a.owner))
-  elif b.kind in {tyArray, tyArrayConstr, tySet, tySequence} and 
+  elif b.kind in {tyArray, tyArrayConstr, tySet, tySequence} and
       a.kind == b.kind:
     # check for seq[empty] vs. seq[int]
     let idx = ord(b.kind in {tyArray, tyArrayConstr})
@@ -163,7 +163,7 @@ proc commonType*(x, y: PType): PType =
         result = newType(k, r.owner)
         result.addSonSkipIntLit(r)
 
-proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = 
+proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
   result = newSym(kind, considerQuotedIdent(n), getCurrOwner(), n.info)
 
 proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
@@ -182,7 +182,7 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
 proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
                  allowed: TSymFlags): PSym
   # identifier with visability
-proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, 
+proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
                         allowed: TSymFlags): PSym
 proc semStmtScope(c: PContext, n: PNode): PNode
 
@@ -190,7 +190,7 @@ proc typeAllowedCheck(info: TLineInfo; typ: PType; kind: TSymKind) =
   let t = typeAllowed(typ, kind)
   if t != nil:
     if t == typ: localError(info, "invalid type: '" & typeToString(typ) & "'")
-    else: localError(info, "invalid type: '" & typeToString(t) & 
+    else: localError(info, "invalid type: '" & typeToString(t) &
                            "' in this context: '" & typeToString(typ) & "'")
 
 proc paramsTypeCheck(c: PContext, typ: PType) {.inline.} =
@@ -226,7 +226,7 @@ when false:
         result = newSymNode(getSysSym"void")
       else:
         result.typ = makeTypeDesc(c, result.typ)
-    
+
     result.handleIsOperator = proc (n: PNode): PNode =
       result = isOpImpl(c, n)
 
@@ -248,7 +248,7 @@ proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode =
     if result == nil:
       result = arg
       # for 'tcnstseq' we support [] to become 'seq'
-      if eOrig.typ.skipTypes(abstractInst).kind == tySequence and 
+      if eOrig.typ.skipTypes(abstractInst).kind == tySequence and
          arg.typ.skipTypes(abstractInst).kind == tyArrayConstr:
         arg.typ = eOrig.typ
 
@@ -320,7 +320,7 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym,
   else:
     case s.typ.sons[0].kind
     of tyExpr:
-      # BUGFIX: we cannot expect a type here, because module aliases would not 
+      # BUGFIX: we cannot expect a type here, because module aliases would not
       # work then (see the ``tmodulealias`` test)
       # semExprWithType(c, result)
       result = semExpr(c, result, flags)
@@ -355,18 +355,18 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
     result = semAfterMacroCall(c, result, sym, flags)
   popInfoContext()
 
-proc forceBool(c: PContext, n: PNode): PNode = 
+proc forceBool(c: PContext, n: PNode): PNode =
   result = fitNode(c, getSysType(tyBool), n)
   if result == nil: result = n
 
-proc semConstBoolExpr(c: PContext, n: PNode): PNode = 
+proc semConstBoolExpr(c: PContext, n: PNode): PNode =
   let nn = semExprWithType(c, n)
   result = fitNode(c, getSysType(tyBool), nn)
   if result == nil:
     localError(n.info, errConstExprExpected)
     return nn
   result = getConstExpr(c.module, result)
-  if result == nil: 
+  if result == nil:
     localError(n.info, errConstExprExpected)
     result = nn
 
@@ -403,9 +403,9 @@ proc myOpen(module: PSym): PPassContext =
   pushOwner(c.module)
   c.importTable = openScope(c)
   c.importTable.addSym(module) # a module knows itself
-  if sfSystemModule in module.flags: 
+  if sfSystemModule in module.flags:
     magicsys.systemModule = module # set global variable!
-  else: 
+  else:
     c.importTable.addSym magicsys.systemModule # import the "System" identifier
     importAllSymbols(c, magicsys.systemModule)
   c.topLevelScope = openScope(c)
@@ -415,13 +415,13 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
   result = myOpen(module)
   for m in items(rd.methods): methodDef(m, true)
 
-proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = 
+proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
   result = semStmt(c, n)
   # BUGFIX: process newly generated generics here, not at the end!
   if c.lastGenericIdx < c.generics.len:
     var a = newNodeI(nkStmtList, n.info)
     addCodeForGenerics(c, a)
-    if sonsLen(a) > 0: 
+    if sonsLen(a) > 0:
       # a generic has been added to `a`:
       if result.kind != nkEmpty: addSon(a, result)
       result = a
@@ -429,17 +429,17 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
   if gCmd == cmdInteractive and not isEmptyType(result.typ):
     result = buildEchoStmt(c, result)
   result = transformStmt(c.module, result)
-    
-proc recoverContext(c: PContext) = 
+
+proc recoverContext(c: PContext) =
   # clean up in case of a semantic error: We clean up the stacks, etc. This is
-  # faster than wrapping every stack operation in a 'try finally' block and 
+  # faster than wrapping every stack operation in a 'try finally' block and
   # requires far less code.
   c.currentScope = c.topLevelScope
   while getCurrOwner().kind != skModule: popOwner()
   while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next
 
-proc myProcess(context: PPassContext, n: PNode): PNode = 
-  var c = PContext(context)    
+proc myProcess(context: PPassContext, n: PNode): PNode =
+  var c = PContext(context)
   # no need for an expensive 'try' if we stop after the first error anyway:
   if msgs.gErrorMax <= 1:
     result = semStmtAndGenerateGenerics(c, n)
@@ -455,8 +455,8 @@ proc myProcess(context: PPassContext, n: PNode): PNode =
       if getCurrentException() of ESuggestDone: result = nil
       else: result = ast.emptyNode
       #if gCmd == cmdIdeTools: findSuggest(c, n)
-    
-proc myClose(context: PPassContext, n: PNode): PNode = 
+
+proc myClose(context: PPassContext, n: PNode): PNode =
   var c = PContext(context)
   closeScope(c)         # close module's scope
   rawCloseScope(c)      # imported symbols; don't check for unused ones!
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index d92e1ab20..718a87232 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -7,16 +7,16 @@
 #    distribution, for details about the copyright.
 #
 
-## This module implements semantic checking for calls. 
+## This module implements semantic checking for calls.
 # included from sem.nim
 
 proc sameMethodDispatcher(a, b: PSym): bool =
   result = false
-  if a.kind == skMethod and b.kind == skMethod: 
+  if a.kind == skMethod and b.kind == skMethod:
     var aa = lastSon(a.ast)
     var bb = lastSon(b.ast)
     if aa.kind == nkSym and bb.kind == nkSym:
-      if aa.sym == bb.sym: 
+      if aa.sym == bb.sym:
         result = true
     else:
       discard
@@ -31,7 +31,7 @@ proc sameMethodDispatcher(a, b: PSym): bool =
       # to avoid subtle problems, the call remains ambiguous and needs to
       # be disambiguated by the programmer; this way the right generic is
       # instantiated.
-  
+
 proc determineType(c: PContext, s: PSym)
 
 proc pickBestCandidate(c: PContext, headSymbol: PNode,
@@ -45,12 +45,12 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
   let symScope = o.lastOverloadScope
 
   var z: TCandidate
-  
+
   if sym == nil: return
   initCandidate(c, best, sym, initialBinding, symScope)
   initCandidate(c, alt, sym, initialBinding, symScope)
   best.state = csNoMatch
-  
+
   while sym != nil:
     if sym.kind in filter:
       determineType(c, sym)
@@ -88,26 +88,26 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
   # Gives a detailed error message; this is separated from semOverloadedCall,
   # as semOverlodedCall is already pretty slow (and we need this information
   # only in case of an error).
-  if c.inCompilesContext > 0: 
+  if c.inCompilesContext > 0:
     # fail fast:
     globalError(n.info, errTypeMismatch, "")
   if errors.isNil or errors.len == 0:
     localError(n.info, errExprXCannotBeCalled, n[0].renderTree)
     return
 
-  # to avoid confusing errors like: 
+  # to avoid confusing errors like:
   #   got (SslPtr, SocketHandle)
-  #   but expected one of: 
+  #   but expected one of:
   #   openssl.SSL_set_fd(ssl: SslPtr, fd: SocketHandle): cint
   # we do a pre-analysis. If all types produce the same string, we will add
   # module information.
   let proto = describeArgs(c, n, 1, preferName)
-  
+
   var prefer = preferName
   for err in errors:
     var errProto = ""
     let n = err.typ.n
-    for i in countup(1, n.len - 1): 
+    for i in countup(1, n.len - 1):
       var p = n.sons[i]
       if p.kind == nkSym:
         add(errProto, typeToString(p.sym.typ, preferName))
@@ -159,9 +159,9 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
 
     n.sons.insert(hiddenArg, 1)
     orig.sons.insert(hiddenArg, 1)
-    
+
     pickBest(f)
- 
+
     if result.state != csMatch:
       n.sons.delete(1)
       orig.sons.delete(1)
@@ -179,7 +179,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
       # we are going to try multiple variants
       n.sons[0..1] = [nil, n[1], calleeName]
       orig.sons[0..1] = [nil, orig[1], calleeName]
-      
+
       template tryOp(x) =
         let op = newIdentNode(getIdent(x), n.info)
         n.sons[0] = op
@@ -188,7 +188,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
 
       if nfExplicitCall in n.flags:
         tryOp ".()"
-   
+
       if result.state in {csEmpty, csNoMatch}:
         tryOp "."
 
@@ -199,7 +199,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
       n.sons[0..1] = [callOp, n[1], calleeName]
       orig.sons[0..1] = [callOp, orig[1], calleeName]
       pickBest(callOp)
-   
+
     if overloadsState == csEmpty and result.state == csEmpty:
       localError(n.info, errUndeclaredIdentifier, considerQuotedIdent(f).s)
       return
@@ -224,7 +224,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
     internalAssert result.state == csMatch
     #writeMatches(result)
     #writeMatches(alt)
-    if c.inCompilesContext > 0: 
+    if c.inCompilesContext > 0:
       # quick error message for performance of 'compiles' built-in:
       globalError(n.info, errGenerated, "ambiguous call")
     elif gErrorCounter == 0:
@@ -254,7 +254,7 @@ proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
     for i in 1 .. <n.len:
       instGenericConvertersArg(c, n.sons[i], x)
 
-proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = 
+proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode =
   var m: TCandidate
   initCandidate(c, m, f)
   result = paramTypesMatch(m, f, a, arg, nil)
@@ -325,7 +325,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
       # get rid of the deref again for a better error message:
       n.sons[1] = n.sons[1].sons[0]
       notFoundError(c, n, errors)
-  else: 
+  else:
     notFoundError(c, n, errors)
   # else: result = errorNode(c, n)
 
@@ -341,7 +341,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
   styleCheckUse(n.info, s)
   result = newSymNode(newInst, n.info)
 
-proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = 
+proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
   assert n.kind == nkBracketExpr
   for i in 1..sonsLen(n)-1:
     n.sons[i].typ = semTypeNode(c, n.sons[i], nil)
@@ -361,11 +361,11 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
     # XXX I think this could be improved by reusing sigmatch.paramTypesMatch.
     # It's good enough for now.
     result = newNodeI(a.kind, n.info)
-    for i in countup(0, len(a)-1): 
+    for i in countup(0, len(a)-1):
       var candidate = a.sons[i].sym
       if candidate.kind in {skProc, skMethod, skConverter,
                             skIterator, skClosureIterator}:
-        # it suffices that the candidate has the proper number of generic 
+        # it suffices that the candidate has the proper number of generic
         # type parameters:
         if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1:
           result.add(explicitGenericSym(c, n, candidate))
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 9f2f755a0..0735b76ce 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -10,14 +10,14 @@
 # this module does the semantic checking of type declarations
 # included from sem.nim
 
-proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType = 
-  if prev == nil: 
+proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
+  if prev == nil:
     result = newTypeS(kind, c)
-  else: 
+  else:
     result = prev
     if result.kind == tyForward: result.kind = kind
 
-proc newConstraint(c: PContext, k: TTypeKind): PType = 
+proc newConstraint(c: PContext, k: TTypeKind): PType =
   result = newTypeS(tyBuiltInTypeClass, c)
   result.addSonSkipIntLit(newTypeS(k, c))
 
@@ -32,22 +32,22 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
   result = newOrPrevType(tyEnum, prev, c)
   result.n = newNodeI(nkEnumTy, n.info)
   checkMinSonsLen(n, 1)
-  if n.sons[0].kind != nkEmpty: 
+  if n.sons[0].kind != nkEmpty:
     base = semTypeNode(c, n.sons[0].sons[0], nil)
-    if base.kind != tyEnum: 
+    if base.kind != tyEnum:
       localError(n.sons[0].info, errInheritanceOnlyWithEnums)
     counter = lastOrd(base) + 1
   rawAddSon(result, base)
   let isPure = result.sym != nil and sfPure in result.sym.flags
   var hasNull = false
-  for i in countup(1, sonsLen(n) - 1): 
+  for i in countup(1, sonsLen(n) - 1):
     case n.sons[i].kind
-    of nkEnumFieldDef: 
+    of nkEnumFieldDef:
       e = newSymS(skEnumField, n.sons[i].sons[0], c)
       var v = semConstExpr(c, n.sons[i].sons[1])
       var strVal: PNode = nil
-      case skipTypes(v.typ, abstractInst-{tyTypeDesc}).kind 
-      of tyTuple: 
+      case skipTypes(v.typ, abstractInst-{tyTypeDesc}).kind
+      of tyTuple:
         if sonsLen(v) == 2:
           strVal = v.sons[1] # second tuple part is the string value
           if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}:
@@ -63,14 +63,14 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
         x = getOrdValue(v)
       if i != 1:
         if x != counter: incl(result.flags, tfEnumHasHoles)
-        if x < counter: 
+        if x < counter:
           localError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s)
           x = counter
       e.ast = strVal # might be nil
       counter = x
-    of nkSym: 
+    of nkSym:
       e = n.sons[i].sym
-    of nkIdent, nkAccQuoted: 
+    of nkIdent, nkAccQuoted:
       e = newSymS(skEnumField, n.sons[i], c)
     else:
       illFormedAst(n[i])
@@ -87,28 +87,28 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
     inc(counter)
   if not hasNull: incl(result.flags, tfNeedsInit)
 
-proc semSet(c: PContext, n: PNode, prev: PType): PType = 
+proc semSet(c: PContext, n: PNode, prev: PType): PType =
   result = newOrPrevType(tySet, prev, c)
-  if sonsLen(n) == 2: 
+  if sonsLen(n) == 2:
     var base = semTypeNode(c, n.sons[1], nil)
     addSonSkipIntLit(result, base)
     if base.kind == tyGenericInst: base = lastSon(base)
     if base.kind != tyGenericParam:
-      if not isOrdinalType(base): 
+      if not isOrdinalType(base):
         localError(n.info, errOrdinalTypeExpected)
-      elif lengthOrd(base) > MaxSetElements: 
+      elif lengthOrd(base) > MaxSetElements:
         localError(n.info, errSetTooBig)
   else:
     localError(n.info, errXExpectsOneTypeParam, "set")
     addSonSkipIntLit(result, errorType(c))
-  
-proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, 
-                  prev: PType): PType = 
+
+proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string,
+                  prev: PType): PType =
   result = newOrPrevType(kind, prev, c)
-  if sonsLen(n) == 2: 
+  if sonsLen(n) == 2:
     var base = semTypeNode(c, n.sons[1], nil)
     addSonSkipIntLit(result, base)
-  else: 
+  else:
     localError(n.info, errXExpectsOneTypeParam, kindStr)
     addSonSkipIntLit(result, errorType(c))
 
@@ -140,23 +140,23 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
     var base = semTypeNode(c, n.lastSon, nil)
     addSonSkipIntLit(result, base)
 
-proc semVarType(c: PContext, n: PNode, prev: PType): PType = 
-  if sonsLen(n) == 1: 
+proc semVarType(c: PContext, n: PNode, prev: PType): PType =
+  if sonsLen(n) == 1:
     result = newOrPrevType(tyVar, prev, c)
     var base = semTypeNode(c, n.sons[0], nil)
-    if base.kind == tyVar: 
+    if base.kind == tyVar:
       localError(n.info, errVarVarTypeNotAllowed)
       base = base.sons[0]
     addSonSkipIntLit(result, base)
   else:
     result = newConstraint(c, tyVar)
 
-proc semDistinct(c: PContext, n: PNode, prev: PType): PType = 
+proc semDistinct(c: PContext, n: PNode, prev: PType): PType =
   if n.len == 0: return newConstraint(c, tyDistinct)
   result = newOrPrevType(tyDistinct, prev, c)
   addSonSkipIntLit(result, semTypeNode(c, n.sons[0], nil))
   if n.len > 1: result.n = n[1]
-  
+
 proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
   assert isRange(n)
   checkSonsLen(n, 3)
@@ -164,11 +164,11 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
   result.n = newNodeI(nkRange, n.info)
   if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty):
     localError(n.info, errRangeIsEmpty)
-  
+
   var range: array[2, PNode]
   range[0] = semExprWithType(c, n[1], {efDetermineType})
   range[1] = semExprWithType(c, n[2], {efDetermineType})
-  
+
   var rangeT: array[2, PType]
   for i in 0..1:
     rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit
@@ -179,13 +179,13 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
     localError(n.info, errOrdinalTypeExpected)
   elif enumHasHoles(rangeT[0]):
     localError(n.info, errEnumXHasHoles, rangeT[0].sym.name.s)
-  
+
   for i in 0..1:
     if hasGenericArguments(range[i]):
       result.n.addSon makeStaticExpr(c, range[i])
     else:
       result.n.addSon semConstExpr(c, range[i])
- 
+
   if weakLeValue(result.n[0], result.n[1]) == impNo:
     localError(n.info, errRangeIsEmpty)
 
@@ -201,10 +201,10 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType =
         incl(result.flags, tfNeedsInit)
       elif n.sons[1].kind in {nkCharLit..nkUInt64Lit} and n.sons[1].intVal < 0:
         incl(result.flags, tfNeedsInit)
-      elif n.sons[0].kind in {nkFloatLit..nkFloat64Lit} and 
+      elif n.sons[0].kind in {nkFloatLit..nkFloat64Lit} and
           n.sons[0].floatVal > 0.0:
         incl(result.flags, tfNeedsInit)
-      elif n.sons[1].kind in {nkFloatLit..nkFloat64Lit} and 
+      elif n.sons[1].kind in {nkFloatLit..nkFloat64Lit} and
           n.sons[1].floatVal < 0.0:
         incl(result.flags, tfNeedsInit)
     else:
@@ -243,13 +243,13 @@ proc semArrayIndex(c: PContext, n: PNode): PType =
     else:
       let x = semConstExpr(c, e)
       if x.kind in {nkIntLit..nkUInt64Lit}:
-        result = makeRangeType(c, 0, x.intVal-1, n.info, 
+        result = makeRangeType(c, 0, x.intVal-1, n.info,
                              x.typ.skipTypes({tyTypeDesc}))
       else:
         result = x.typ.skipTypes({tyTypeDesc})
         #localError(n[1].info, errConstExprExpected)
 
-proc semArray(c: PContext, n: PNode, prev: PType): PType = 
+proc semArray(c: PContext, n: PNode, prev: PType): PType =
   var base: PType
   result = newOrPrevType(tyArray, prev, c)
   if sonsLen(n) == 3:
@@ -260,20 +260,20 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
     if indx.kind notin {tyGenericParam, tyStatic, tyFromExpr}:
       if not isOrdinalType(indx):
         localError(n.sons[1].info, errOrdinalTypeExpected)
-      elif enumHasHoles(indx): 
+      elif enumHasHoles(indx):
         localError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s)
     base = semTypeNode(c, n.sons[2], nil)
     addSonSkipIntLit(result, base)
-  else: 
+  else:
     localError(n.info, errArrayExpectsTwoTypeParams)
     result = newOrPrevType(tyError, prev, c)
-  
-proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = 
+
+proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
   result = newOrPrevType(tyOrdinal, prev, c)
-  if sonsLen(n) == 2: 
+  if sonsLen(n) == 2:
     var base = semTypeNode(c, n.sons[1], nil)
-    if base.kind != tyGenericParam: 
-      if not isOrdinalType(base): 
+    if base.kind != tyGenericParam:
+      if not isOrdinalType(base):
         localError(n.sons[1].info, errOrdinalTypeExpected)
     addSonSkipIntLit(result, base)
   else:
@@ -281,7 +281,7 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
     result = newOrPrevType(tyError, prev, c)
 
 proc semTypeIdent(c: PContext, n: PNode): PSym =
-  if n.kind == nkSym: 
+  if n.kind == nkSym:
     result = n.sym
   else:
     when defined(nimfix):
@@ -307,7 +307,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
         result = result.typ.sym.copySym
         result.typ = copyType(result.typ, result.typ.owner, true)
         result.typ.flags.incl tfUnresolved
-      
+
       if result.kind == skGenericParam:
         if result.typ.kind == tyGenericParam and result.typ.len == 0 and
            tfWildcard in result.typ.flags:
@@ -319,7 +319,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
           localError(n.info, errTypeExpected)
           return errorSym(c, n)
 
-      if result.kind != skType: 
+      if result.kind != skType:
         # this implements the wanted ``var v: V, x: V`` feature ...
         var ov: TOverloadIter
         var amb = initOverloadIter(ov, c, n)
@@ -344,48 +344,48 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
     else:
       localError(n.info, errIdentifierExpected)
       result = errorSym(c, n)
-  
-proc semTuple(c: PContext, n: PNode, prev: PType): PType = 
+
+proc semTuple(c: PContext, n: PNode, prev: PType): PType =
   if n.sonsLen == 0: return newConstraint(c, tyTuple)
   var typ: PType
   result = newOrPrevType(tyTuple, prev, c)
   result.n = newNodeI(nkRecList, n.info)
   var check = initIntSet()
   var counter = 0
-  for i in countup(0, sonsLen(n) - 1): 
+  for i in countup(0, sonsLen(n) - 1):
     var a = n.sons[i]
     if (a.kind != nkIdentDefs): illFormedAst(a)
     checkMinSonsLen(a, 3)
     var length = sonsLen(a)
-    if a.sons[length - 2].kind != nkEmpty: 
+    if a.sons[length - 2].kind != nkEmpty:
       typ = semTypeNode(c, a.sons[length - 2], nil)
     else:
       localError(a.info, errTypeExpected)
       typ = errorType(c)
-    if a.sons[length - 1].kind != nkEmpty: 
+    if a.sons[length - 1].kind != nkEmpty:
       localError(a.sons[length - 1].info, errInitHereNotAllowed)
-    for j in countup(0, length - 3): 
+    for j in countup(0, length - 3):
       var field = newSymG(skField, a.sons[j], c)
       field.typ = typ
       field.position = counter
       inc(counter)
-      if containsOrIncl(check, field.name.id): 
+      if containsOrIncl(check, field.name.id):
         localError(a.sons[j].info, errAttemptToRedefine, field.name.s)
       else:
         addSon(result.n, newSymNode(field))
         addSonSkipIntLit(result, typ)
       if gCmd == cmdPretty: styleCheckDef(a.sons[j].info, field)
 
-proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, 
-                 allowed: TSymFlags): PSym = 
+proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
+                 allowed: TSymFlags): PSym =
   # identifier with visibility
-  if n.kind == nkPostfix: 
-    if sonsLen(n) == 2 and n.sons[0].kind == nkIdent: 
+  if n.kind == nkPostfix:
+    if sonsLen(n) == 2 and n.sons[0].kind == nkIdent:
       # for gensym'ed identifiers the identifier may already have been
       # transformed to a symbol and we need to use that here:
       result = newSymG(kind, n.sons[1], c)
       var v = n.sons[0].ident
-      if sfExported in allowed and v.id == ord(wStar): 
+      if sfExported in allowed and v.id == ord(wStar):
         incl(result.flags, sfExported)
       else:
         localError(n.sons[0].info, errInvalidVisibilityX, v.s)
@@ -393,7 +393,7 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
       illFormedAst(n)
   else:
     result = newSymG(kind, n, c)
-  
+
 proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
                         allowed: TSymFlags): PSym =
   if n.kind == nkPragmaExpr:
@@ -415,31 +415,31 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
 proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) =
   let ex = t[branchIndex][currentEx].skipConv
   for i in countup(1, branchIndex):
-    for j in countup(0, sonsLen(t.sons[i]) - 2): 
+    for j in countup(0, sonsLen(t.sons[i]) - 2):
       if i == branchIndex and j == currentEx: break
       if overlap(t.sons[i].sons[j].skipConv, ex):
         localError(ex.info, errDuplicateCaseLabel)
-  
+
 proc semBranchRange(c: PContext, t, a, b: PNode, covered: var BiggestInt): PNode =
   checkMinSonsLen(t, 1)
   let ac = semConstExpr(c, a)
   let bc = semConstExpr(c, b)
   let at = fitNode(c, t.sons[0].typ, ac).skipConvTakeType
   let bt = fitNode(c, t.sons[0].typ, bc).skipConvTakeType
-  
+
   result = newNodeI(nkRange, a.info)
   result.add(at)
   result.add(bt)
   if emptyRange(ac, bc): localError(b.info, errRangeIsEmpty)
   else: covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1
 
-proc semCaseBranchRange(c: PContext, t, b: PNode, 
-                        covered: var BiggestInt): PNode = 
+proc semCaseBranchRange(c: PContext, t, b: PNode,
+                        covered: var BiggestInt): PNode =
   checkSonsLen(b, 3)
   result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
 
-proc semCaseBranchSetElem(c: PContext, t, b: PNode, 
-                          covered: var BiggestInt): PNode = 
+proc semCaseBranchSetElem(c: PContext, t, b: PNode,
+                          covered: var BiggestInt): PNode =
   if isRange(b):
     checkSonsLen(b, 3)
     result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
@@ -450,10 +450,10 @@ proc semCaseBranchSetElem(c: PContext, t, b: PNode,
     result = fitNode(c, t.sons[0].typ, b)
     inc(covered)
 
-proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, 
-                   covered: var BiggestInt) = 
-  
-  for i in countup(0, sonsLen(branch) - 2): 
+proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
+                   covered: var BiggestInt) =
+
+  for i in countup(0, sonsLen(branch) - 2):
     var b = branch.sons[i]
     if b.kind == nkRange:
       branch.sons[i] = b
@@ -480,7 +480,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
           var L = branch.len
           swap(branch.sons[L-2], branch.sons[L-1])
     checkForOverlap(c, t, i, branchIndex)
-    
+
 proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
                       father: PNode, rectype: PType)
 proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
@@ -514,11 +514,11 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
     else: illFormedAst(n)
     delSon(b, sonsLen(b) - 1)
     semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype)
-  if chckCovered and (covered != lengthOrd(a.sons[0].typ)): 
+  if chckCovered and (covered != lengthOrd(a.sons[0].typ)):
     localError(a.info, errNotAllCasesCovered)
   addSon(father, a)
 
-proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, 
+proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
                       father: PNode, rectype: PType) =
   if n == nil: return
   case n.kind
@@ -556,12 +556,12 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
       semRecordNodeAux(c, branch, check, pos, father, rectype)
   of nkRecCase:
     semRecordCase(c, n, check, pos, father, rectype)
-  of nkNilLit: 
+  of nkNilLit:
     if father.kind != nkRecList: addSon(father, newNodeI(nkRecList, n.info))
   of nkRecList:
     # attempt to keep the nesting at a sane level:
     var a = if father.kind == nkRecList: father else: copyNode(n)
-    for i in countup(0, sonsLen(n) - 1): 
+    for i in countup(0, sonsLen(n) - 1):
       semRecordNodeAux(c, n.sons[i], check, pos, a, rectype)
     if a != father: addSon(father, a)
   of nkIdentDefs:
@@ -570,10 +570,10 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
     var a: PNode
     if father.kind != nkRecList and length>=4: a = newNodeI(nkRecList, n.info)
     else: a = ast.emptyNode
-    if n.sons[length-1].kind != nkEmpty: 
+    if n.sons[length-1].kind != nkEmpty:
       localError(n.sons[length-1].info, errInitHereNotAllowed)
     var typ: PType
-    if n.sons[length-2].kind == nkEmpty: 
+    if n.sons[length-2].kind == nkEmpty:
       localError(n.info, errTypeExpected)
       typ = errorType(c)
     else:
@@ -586,7 +586,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
       f.typ = typ
       f.position = pos
       if (rec != nil) and ({sfImportc, sfExportc} * rec.flags != {}) and
-          (f.loc.r == nil): 
+          (f.loc.r == nil):
         f.loc.r = toRope(f.name.s)
         f.flags = f.flags + ({sfImportc, sfExportc} * rec.flags)
       inc(pos)
@@ -598,8 +598,8 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
     if a.kind != nkEmpty: addSon(father, a)
   of nkEmpty: discard
   else: illFormedAst(n)
-  
-proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int, 
+
+proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int,
                            n: PNode) =
   case n.kind
   of nkRecCase:
@@ -618,31 +618,31 @@ proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int,
     inc(pos)
   else: internalError(n.info, "addInheritedFieldsAux()")
 
-proc skipGenericInvocation(t: PType): PType {.inline.} = 
+proc skipGenericInvocation(t: PType): PType {.inline.} =
   result = t
   if result.kind == tyGenericInvocation:
     result = result.sons[0]
   if result.kind == tyGenericBody:
     result = lastSon(result)
 
-proc addInheritedFields(c: PContext, check: var IntSet, pos: var int, 
+proc addInheritedFields(c: PContext, check: var IntSet, pos: var int,
                         obj: PType) =
   assert obj.kind == tyObject
-  if (sonsLen(obj) > 0) and (obj.sons[0] != nil): 
+  if (sonsLen(obj) > 0) and (obj.sons[0] != nil):
     addInheritedFields(c, check, pos, obj.sons[0].skipGenericInvocation)
   addInheritedFieldsAux(c, check, pos, obj.n)
 
 proc semObjectNode(c: PContext, n: PNode, prev: PType): PType =
   if n.sonsLen == 0: return newConstraint(c, tyObject)
   var check = initIntSet()
-  var pos = 0 
+  var pos = 0
   var base: PType = nil
   # n.sons[0] contains the pragmas (if any). We process these later...
   checkSonsLen(n, 3)
-  if n.sons[1].kind != nkEmpty: 
+  if n.sons[1].kind != nkEmpty:
     base = skipTypes(semTypeNode(c, n.sons[1].sons[0], nil), skipPtrs)
     var concreteBase = skipGenericInvocation(base).skipTypes(skipPtrs)
-    if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags: 
+    if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags:
       addInheritedFields(c, check, pos, concreteBase)
     else:
       if concreteBase.kind != tyError:
@@ -723,7 +723,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
     genericParams.addSon(newSymNode(s))
     result = typeClass
     addDecl(c, s)
- 
+
   # XXX: There are codegen errors if this is turned into a nested proc
   template liftingWalk(typ: PType, anonFlag = false): expr =
     liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag)
@@ -742,7 +742,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
   case paramType.kind:
   of tyAnything:
     result = addImplicitGeneric(newTypeS(tyGenericParam, c))
-  
+
   of tyStatic:
     # proc(a: expr{string}, b: expr{nkLambda})
     # overload on compile time values and AST trees
@@ -753,7 +753,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
       localError(info, errMacroBodyDependsOnGenericTypes, paramName)
     result = addImplicitGeneric(c.newTypeWithSons(tyStatic, @[base]))
     result.flags.incl({tfHasStatic, tfUnresolved})
-  
+
   of tyTypeDesc:
     if tfUnresolved notin paramType.flags:
       # naked typedescs are not bindOnce types
@@ -761,12 +761,12 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
          paramTypId.id == typedescId.id: paramTypId = nil
       result = addImplicitGeneric(
         c.newTypeWithSons(tyTypeDesc, @[paramType.base]))
-  
+
   of tyDistinct:
     if paramType.sonsLen == 1:
       # disable the bindOnce behavior for the type class
       result = liftingWalk(paramType.sons[0], true)
-  
+
   of tySequence, tySet, tyArray, tyOpenArray,
      tyVar, tyPtr, tyRef, tyProc:
     # XXX: this is a bit strange, but proc(s: seq)
@@ -785,22 +785,22 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
         if lifted != nil:
           paramType.sons[i] = lifted
           result = paramType
-  
+
   of tyGenericBody:
     result = newTypeS(tyGenericInvocation, c)
     result.rawAddSon(paramType)
-      
+
     for i in 0 .. paramType.sonsLen - 2:
       if paramType.sons[i].kind == tyStatic:
         result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnknown'
       else:
         result.rawAddSon newTypeS(tyAnything, c)
-      
+
     if paramType.lastSon.kind == tyUserTypeClass:
       result.kind = tyUserTypeClassInst
       result.rawAddSon paramType.lastSon
       return addImplicitGeneric(result)
-   
+
     result = instGenericContainer(c, paramType.sym.info, result,
                                   allowMetaTypes = true)
     result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result])
@@ -832,7 +832,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
     if liftBody != nil:
       result = liftBody
       result.shouldHaveMeta
- 
+
   of tyGenericInvocation:
     for i in 1 .. <paramType.sonsLen:
       let lifted = liftingWalk(paramType.sons[i])
@@ -844,18 +844,18 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
 
   of tyUserTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
     result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true))
-  
+
   of tyExpr:
     if procKind notin {skMacro, skTemplate}:
       result = addImplicitGeneric(newTypeS(tyAnything, c))
-  
+
   of tyGenericParam:
     markUsed(info, paramType.sym)
     styleCheckUse(info, paramType.sym)
     if tfWildcard in paramType.flags:
       paramType.flags.excl tfWildcard
       paramType.sym.kind = skType
-    
+
   else: discard
 
   # result = liftingWalk(paramType)
@@ -872,7 +872,7 @@ proc newProcType(c: PContext; info: TLineInfo; prev: PType = nil): PType =
   result.callConv = lastOptionEntry(c).defaultCC
   result.n = newNodeI(nkFormalParams, info)
   rawAddSon(result, nil) # return type
-  # result.n[0] used to be `nkType`, but now it's `nkEffectList` because 
+  # result.n[0] used to be `nkType`, but now it's `nkEffectList` because
   # the effects are now stored in there too ... this is a bit hacky, but as
   # usual we desperately try to save memory:
   addSon(result.n, newNodeI(nkEffectList, info))
@@ -909,7 +909,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
       typ = semParamType(c, a.sons[length-2], constraint)
 
     if hasDefault:
-      def = semExprWithType(c, a.sons[length-1]) 
+      def = semExprWithType(c, a.sons[length-1])
       # check type compatibility between def.typ and typ:
       if typ == nil:
         typ = def.typ
@@ -927,7 +927,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
       typ = newTypeS(tdef, c)
 
     if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
-    for j in countup(0, length-3): 
+    for j in countup(0, length-3):
       var arg = newSymG(skParam, a.sons[j], c)
       let lifted = liftParamType(c, kind, genericParams, typ,
                                  arg.name.s, arg.info)
@@ -937,7 +937,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
       arg.constraint = constraint
       inc(counter)
       if def != nil and def.kind != nkEmpty: arg.ast = copyTree(def)
-      if containsOrIncl(check, arg.name.id): 
+      if containsOrIncl(check, arg.name.id):
         localError(a.sons[j].info, errAttemptToRedefine, arg.name.s)
       addSon(result.n, newSymNode(arg))
       rawAddSon(result, finalType)
@@ -950,9 +950,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
   elif kind == skIterator:
     # XXX This is special magic we should likely get rid of
     r = newTypeS(tyExpr, c)
-  
+
   if r != nil:
-    # turn explicit 'void' return type into 'nil' because the rest of the 
+    # turn explicit 'void' return type into 'nil' because the rest of the
     # compiler only checks for 'nil':
     if skipTypes(r, {tyGenericInst}).kind != tyEmpty:
       # 'auto' as a return type does not imply a generic:
@@ -988,8 +988,8 @@ proc semStmtListType(c: PContext, n: PNode, prev: PType): PType =
     n.sons[length - 1].typ = result
   else:
     result = nil
-  
-proc semBlockType(c: PContext, n: PNode, prev: PType): PType = 
+
+proc semBlockType(c: PContext, n: PNode, prev: PType): PType =
   inc(c.p.nestedBlockCounter)
   checkSonsLen(n, 2)
   openScope(c)
@@ -1009,7 +1009,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
     localError(n.info, "cannot instantiate the '$1' $2" %
                        [s.name.s, ($s.kind).substr(2).toLower])
     return newOrPrevType(tyError, prev, c)
-  
+
   var t = s.typ
   if t.kind == tyCompositeTypeClass and t.base.kind == tyGenericBody:
     t = t.base
@@ -1036,7 +1036,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
   else:
     var m = newCandidate(c, t)
     matches(c, n, copyTree(n), m)
-    
+
     if m.state != csMatch:
       var err = "cannot instantiate " & typeToString(t) & "\n" &
                 "got: (" & describeArgs(c, n) & ")\n" &
@@ -1045,12 +1045,12 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
       return newOrPrevType(tyError, prev, c)
 
     var isConcrete = true
- 
+
     for i in 1 .. <m.call.len:
       let typ = m.call[i].typ.skipTypes({tyTypeDesc})
       if containsGenericType(typ): isConcrete = false
       addToResult(typ)
-   
+
     if isConcrete:
       if s.ast == nil and s.typ.kind != tyCompositeTypeClass:
         # XXX: What kind of error is this? is it still relevant?
@@ -1081,7 +1081,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
   let
     pragmas = n[1]
     inherited = n[2]
-    
+
   if inherited.kind != nkEmpty:
     for n in inherited.sons:
       let typ = semTypeNode(c, n, nil)
@@ -1114,7 +1114,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
     checkSonsLen(n, 1)
     let typExpr = semExprWithType(c, n.sons[0], {efInTypeof})
     result = typExpr.typ.skipTypes({tyIter})
-  of nkPar: 
+  of nkPar:
     if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
     else:
       # XXX support anon tuple here
@@ -1197,7 +1197,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
         result = makeTypeFromExpr(c, preprocessed.copyTree)
   of nkIdent, nkAccQuoted:
     var s = semTypeIdent(c, n)
-    if s.typ == nil: 
+    if s.typ == nil:
       if s.kind != skError: localError(n.info, errTypeExpected)
       result = newOrPrevType(tyError, prev, c)
     elif s.kind == skParam and s.typ.kind == tyTypeDesc:
@@ -1205,19 +1205,19 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
       result = s.typ.base
     elif prev == nil:
       result = s.typ
-    else: 
+    else:
       assignType(prev, s.typ)
       # bugfix: keep the fresh id for aliases to integral types:
       if s.typ.kind notin {tyBool, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
-                           tyUInt..tyUInt64}: 
+                           tyUInt..tyUInt64}:
         prev.id = s.typ.id
       result = prev
   of nkSym:
     if n.sym.kind == skType and n.sym.typ != nil:
       var t = n.sym.typ
-      if prev == nil: 
+      if prev == nil:
         result = t
-      else: 
+      else:
         assignType(prev, t)
         result = prev
       markUsed(n.info, n.sym)
@@ -1267,12 +1267,12 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
     result = newOrPrevType(tyError, prev, c)
   n.typ = result
 
-proc setMagicType(m: PSym, kind: TTypeKind, size: int) = 
+proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
   m.typ.kind = kind
   m.typ.align = size.int16
   m.typ.size = size
-  
-proc processMagicType(c: PContext, m: PSym) = 
+
+proc processMagicType(c: PContext, m: PSym) =
   case m.magic
   of mInt: setMagicType(m, tyInt, intSize)
   of mInt8: setMagicType(m, tyInt8, 1)
@@ -1290,21 +1290,21 @@ proc processMagicType(c: PContext, m: PSym) =
   of mFloat128: setMagicType(m, tyFloat128, 16)
   of mBool: setMagicType(m, tyBool, 1)
   of mChar: setMagicType(m, tyChar, 1)
-  of mString: 
+  of mString:
     setMagicType(m, tyString, ptrSize)
     rawAddSon(m.typ, getSysType(tyChar))
-  of mCstring: 
+  of mCstring:
     setMagicType(m, tyCString, ptrSize)
     rawAddSon(m.typ, getSysType(tyChar))
   of mPointer: setMagicType(m, tyPointer, ptrSize)
-  of mEmptySet: 
+  of mEmptySet:
     setMagicType(m, tySet, 1)
     rawAddSon(m.typ, newTypeS(tyEmpty, c))
   of mIntSetBaseType: setMagicType(m, tyRange, intSize)
   of mNil: setMagicType(m, tyNil, ptrSize)
   of mExpr: setMagicType(m, tyExpr, 0)
   of mStmt: setMagicType(m, tyStmt, 0)
-  of mTypeDesc: 
+  of mTypeDesc:
     setMagicType(m, tyTypeDesc, 0)
     rawAddSon(m.typ, newTypeS(tyNone, c))
   of mVoidType: setMagicType(m, tyEmpty, 0)
@@ -1318,8 +1318,8 @@ proc processMagicType(c: PContext, m: PSym) =
     setMagicType(m, tyRange, 0)
     rawAddSon(m.typ, newTypeS(tyNone, c))
   of mSet:
-    setMagicType(m, tySet, 0) 
-  of mSeq: 
+    setMagicType(m, tySet, 0)
+  of mSeq:
     setMagicType(m, tySequence, 0)
   of mOrdinal:
     setMagicType(m, tyOrdinal, 0)
@@ -1335,13 +1335,13 @@ proc processMagicType(c: PContext, m: PSym) =
     incl m.typ.flags, tfShared
     rawAddSon(m.typ, sysTypeFromName"shared")
   else: localError(m.info, errTypeExpected)
-  
+
 proc semGenericConstraints(c: PContext, x: PType): PType =
   result = newTypeWithSons(c, tyGenericParam, @[x])
 
-proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = 
+proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
   result = copyNode(n)
-  if n.kind != nkGenericParams: 
+  if n.kind != nkGenericParams:
     illFormedAst(n)
     return
   for i in countup(0, sonsLen(n)-1):
@@ -1351,7 +1351,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
     var def = a{-1}
     let constraint = a{-2}
     var typ: PType
-    
+
     if constraint.kind != nkEmpty:
       typ = semTypeNode(c, constraint, nil)
       if typ.kind != tyStatic or typ.len == 0:
@@ -1360,7 +1360,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
             typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
         else:
           typ = semGenericConstraints(c, typ)
-    
+
     if def.kind != nkEmpty:
       def = semConstExpr(c, def)
       if typ == nil:
@@ -1372,7 +1372,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
         def.typ = def.typ.skipTypes({tyTypeDesc})
         if not containsGenericType(def.typ):
           def = fitNode(c, typ, def)
-    
+
     if typ == nil:
       typ = newTypeS(tyGenericParam, c)
       if father == nil: typ.flags.incl tfWildcard
diff --git a/compiler/vm.nim b/compiler/vm.nim
index a36de1c20..f0a0135e8 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -239,7 +239,7 @@ proc pushSafePoint(f: PStackFrame; pc: int) =
 
 proc popSafePoint(f: PStackFrame) = discard f.safePoints.pop()
 
-proc cleanUpOnException(c: PCtx; tos: PStackFrame): 
+proc cleanUpOnException(c: PCtx; tos: PStackFrame):
                                               tuple[pc: int, f: PStackFrame] =
   let raisedType = c.currentExceptionA.typ.skipTypes(abstractPtrs)
   var f = tos
@@ -257,7 +257,7 @@ proc cleanUpOnException(c: PCtx; tos: PStackFrame):
       let exceptType = c.types[c.code[pc2].regBx-wordExcess].skipTypes(
                           abstractPtrs)
       if inheritanceDiff(exceptType, raisedType) <= 0:
-        # mark exception as handled but keep it in B for 
+        # mark exception as handled but keep it in B for
         # the getCurrentException() builtin:
         c.currentExceptionB = c.currentExceptionA
         c.currentExceptionA = nil
@@ -349,14 +349,14 @@ proc opConv*(dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool =
       if dest.kind != rkFloat:
         myreset(dest); dest.kind = rkFloat
       case skipTypes(srctyp, abstractRange).kind
-      of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyBool, tyChar: 
+      of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyBool, tyChar:
         dest.floatVal = toFloat(src.intVal.int)
       else:
         dest.floatVal = src.floatVal
     else:
       asgnComplex(dest, src)
 
-proc compile(c: PCtx, s: PSym): int = 
+proc compile(c: PCtx, s: PSym): int =
   result = vmgen.genProc(c, s)
   when debugEchoCode: c.echoCode result
   #c.echoCode
@@ -396,10 +396,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       pc = tos.comesFrom
       tos = tos.next
       let retVal = regs[0]
-      if tos.isNil: 
+      if tos.isNil:
         #echo "RET ", retVal.rendertree
         return retVal
-      
+
       move(regs, tos.slots)
       assert c.code[pc].opcode in {opcIndCall, opcIndCallAsgn}
       if c.code[pc].opcode == opcIndCallAsgn:
@@ -653,7 +653,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcSubu:
       decodeBC(rkInt)
       regs[ra].intVal = regs[rb].intVal -% regs[rc].intVal
-    of opcMulu: 
+    of opcMulu:
       decodeBC(rkInt)
       regs[ra].intVal = regs[rb].intVal *% regs[rc].intVal
     of opcDivu:
@@ -726,7 +726,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcLeSet:
       decodeBC(rkInt)
       regs[ra].intVal = ord(containsSets(regs[rb].node, regs[rc].node))
-    of opcEqSet: 
+    of opcEqSet:
       decodeBC(rkInt)
       regs[ra].intVal = ord(equalSets(regs[rb].node, regs[rc].node))
     of opcLtSet:
@@ -737,9 +737,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcMulSet:
       decodeBC(rkNode)
       createSet(regs[ra])
-      move(regs[ra].node.sons, 
+      move(regs[ra].node.sons,
             nimsets.intersectSets(regs[rb].node, regs[rc].node).sons)
-    of opcPlusSet: 
+    of opcPlusSet:
       decodeBC(rkNode)
       createSet(regs[ra])
       move(regs[ra].node.sons,
@@ -753,7 +753,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       decodeBC(rkNode)
       createSet(regs[ra])
       move(regs[ra].node.sons,
-           nimsets.symdiffSets(regs[rb].node, regs[rc].node).sons)    
+           nimsets.symdiffSets(regs[rb].node, regs[rc].node).sons)
     of opcConcatStr:
       decodeBC(rkNode)
       createStr regs[ra]
@@ -793,7 +793,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       assert c.code[pc].opcode == opcSubStr
       let rd = c.code[pc].regA
       createStr regs[ra]
-      regs[ra].node.strVal = substr(regs[rb].node.strVal, 
+      regs[ra].node.strVal = substr(regs[rb].node.strVal,
                                     regs[rc].intVal.int, regs[rd].intVal.int)
     of opcParseFloat:
       decodeBC(rkInt)
@@ -896,12 +896,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       # we know the next instruction is a 'fjmp':
       let branch = c.constants[instr.regBx-wordExcess]
       var cond = false
-      for j in countup(0, sonsLen(branch) - 2): 
-        if overlap(regs[ra].regToNode, branch.sons[j]): 
+      for j in countup(0, sonsLen(branch) - 2):
+        if overlap(regs[ra].regToNode, branch.sons[j]):
           cond = true
           break
       assert c.code[pc+1].opcode == opcFJmp
-      inc pc 
+      inc pc
       # we skip this instruction so that the final 'inc(pc)' skips
       # the following jump
       if not cond:
@@ -1273,7 +1273,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcNSetIntVal:
       decodeB(rkNode)
       var dest = regs[ra].node
-      if dest.kind in {nkCharLit..nkInt64Lit} and 
+      if dest.kind in {nkCharLit..nkInt64Lit} and
          regs[rb].kind in {rkInt}:
         dest.intVal = regs[rb].intVal
       else:
@@ -1281,24 +1281,24 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcNSetFloatVal:
       decodeB(rkNode)
       var dest = regs[ra].node
-      if dest.kind in {nkFloatLit..nkFloat64Lit} and 
+      if dest.kind in {nkFloatLit..nkFloat64Lit} and
          regs[rb].kind in {rkFloat}:
         dest.floatVal = regs[rb].floatVal
-      else: 
+      else:
         stackTrace(c, tos, pc, errFieldXNotFound, "floatVal")
     of opcNSetSymbol:
       decodeB(rkNode)
       var dest = regs[ra].node
       if dest.kind == nkSym and regs[rb].node.kind == nkSym:
         dest.sym = regs[rb].node.sym
-      else: 
+      else:
         stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
     of opcNSetIdent:
       decodeB(rkNode)
       var dest = regs[ra].node
       if dest.kind == nkIdent and regs[rb].node.kind == nkIdent:
         dest.ident = regs[rb].node.ident
-      else: 
+      else:
         stackTrace(c, tos, pc, errFieldXNotFound, "ident")
     of opcNSetType:
       decodeB(rkNode)
@@ -1309,7 +1309,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcNSetStrVal:
       decodeB(rkNode)
       var dest = regs[ra].node
-      if dest.kind in {nkStrLit..nkTripleStrLit} and 
+      if dest.kind in {nkStrLit..nkTripleStrLit} and
          regs[rb].kind in {rkNode}:
         dest.strVal = regs[rb].node.strVal
       else:
@@ -1435,8 +1435,9 @@ proc evalConstExprAux(module, prc: PSym, n: PNode, mode: TEvalMode): PNode =
   newSeq(tos.slots, c.prc.maxSlots)
   #for i in 0 .. <c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty)
   result = rawExecute(c, start, tos).regToNode
+  if result.info.line < 0: result.info = n.info
 
-proc evalConstExpr*(module: PSym, e: PNode): PNode = 
+proc evalConstExpr*(module: PSym, e: PNode): PNode =
   result = evalConstExprAux(module, nil, e, emConst)
 
 proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode =
@@ -1496,6 +1497,7 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode =
   # temporary storage:
   #for i in L .. <maxSlots: tos.slots[i] = newNode(nkEmpty)
   result = rawExecute(c, start, tos).regToNode
+  if result.info.line < 0: result.info = n.info
   if cyclicTree(result): globalError(n.info, errCyclicTree)
   dec(evalMacroCounter)
   c.callsite = nil
diff --git a/koch.nim b/koch.nim
index d365262c1..34cb1317d 100644
--- a/koch.nim
+++ b/koch.nim
@@ -347,7 +347,7 @@ proc temp(args: string) =
   if args.len > 0: exec(finalDest & " " & args)
 
 proc showHelp() = 
-  quit(HelpText % [VersionAsString & repeatChar(44-len(VersionAsString)), 
+  quit(HelpText % [VersionAsString & spaces(44-len(VersionAsString)), 
                    CompileDate, CompileTime], QuitSuccess)
 
 var op = initOptParser()
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 4758dc0c1..0888a8767 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -343,7 +343,7 @@ proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.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("macro expects a node of kind: " & $k)
+  if n.kind != k: error("Expected a node of kind " & $k & ", got " & $n.kind)
 
 proc expectMinLen*(n: PNimrodNode, min: int) {.compileTime.} =
   ## checks that `n` has at least `min` children. If this is not the case,
@@ -581,10 +581,8 @@ const
   CallNodes* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
     nnkCallStrLit, nnkHiddenCallConv}
 
-from strutils import cmpIgnoreStyle, format
-
 proc expectKind*(n: PNimrodNode; k: set[TNimrodNodeKind]) {.compileTime.} =
-  assert n.kind in k, "Expected one of $1, got $2".format(k, n.kind)
+  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.} =
@@ -654,7 +652,7 @@ proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}=
 
 
 template badNodeKind(k; f): stmt{.immediate.} =
-  assert false, "Invalid node kind $# for macros.`$2`".format(k, f)
+  assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`"
 
 proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
   case someProc.kind:
@@ -776,6 +774,22 @@ proc copy*(node: PNimrodNode): PNimrodNode {.compileTime.} =
   ## An alias for copyNimTree().
   return node.copyNimTree()
 
+proc cmpIgnoreStyle(a, b: cstring): int {.noSideEffect.} =
+  proc toLower(c: char): char {.inline.} =
+    if c in {'A'..'Z'}: result = chr(ord(c) + (ord('a') - ord('A')))
+    else: result = c
+  var i = 0
+  var j = 0
+  while true:
+    while a[i] == '_': inc(i)
+    while b[j] == '_': inc(j) # BUGFIX: typo
+    var aa = toLower(a[i])
+    var bb = toLower(b[j])
+    result = ord(aa) - ord(bb)
+    if result != 0 or aa == '\0': break
+    inc(i)
+    inc(j)
+
 proc eqIdent* (a, b: string): bool = cmpIgnoreStyle(a, b) == 0
   ## Check if two idents are identical.
 
diff --git a/lib/impure/re.nim b/lib/impure/re.nim
index 7d5ff8948..921a24fd1 100644
--- a/lib/impure/re.nim
+++ b/lib/impure/re.nim
@@ -66,7 +66,7 @@ proc rawCompile(pattern: string, flags: cint): PPcre =
     offset: cint
   result = pcre.compile(pattern, flags, addr(msg), addr(offset), nil)
   if result == nil:
-    raiseInvalidRegex($msg & "\n" & pattern & "\n" & repeatChar(offset) & "^\n")
+    raiseInvalidRegex($msg & "\n" & pattern & "\n" & spaces(offset) & "^\n")
 
 proc finalizeRegEx(x: Regex) = 
   # XXX This is a hack, but PCRE does not export its "free" function properly.
@@ -291,7 +291,7 @@ proc replace*(s: string, sub: Regex, by = ""): string =
   ## accessed in `by`. Examples:
   ##
   ## .. code-block:: nim
-  ##   "var1=key; var2=key2".replace(re"(\w+)'='(\w+)")
+  ##   "var1=key; var2=key2".replace(re"(\w+)=(\w+)")
   ##
   ## Results in:
   ##
@@ -313,7 +313,7 @@ proc replacef*(s: string, sub: Regex, by: string): string =
   ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples:
   ##
   ## .. code-block:: nim
-  ## "var1=key; var2=key2".replacef(re"(\w+)'='(\w+)", "$1<-$2$2")
+  ##   "var1=key; var2=key2".replacef(re"(\w+)=(\w+)", "$1<-$2$2")
   ##
   ## Results in:
   ##
diff --git a/lib/nimbase.h b/lib/nimbase.h
index 50c7968ac..a1d4d1e27 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -67,7 +67,7 @@ __clang__
 #endif
 
 #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
-#  define NIM_THREADVAR __declspec(thread) 
+#  define NIM_THREADVAR __declspec(thread)
 #else
 #  define NIM_THREADVAR __thread
 #endif
@@ -103,7 +103,11 @@ __clang__
 #  define N_FASTCALL_PTR(rettype, name) rettype (__fastcall *name)
 #  define N_SAFECALL_PTR(rettype, name) rettype (__safecall *name)
 
-#  define N_LIB_EXPORT  extern __declspec(dllexport)
+#  ifdef __cplusplus
+#    define N_LIB_EXPORT  extern "C" __declspec(dllexport)
+#  else
+#    define N_LIB_EXPORT  extern __declspec(dllexport)
+#  endif
 #  define N_LIB_IMPORT  extern __declspec(dllimport)
 #else
 #  define N_CDECL(rettype, name) rettype name
@@ -118,7 +122,11 @@ __clang__
 #  define N_FASTCALL_PTR(rettype, name) rettype (*name)
 #  define N_SAFECALL_PTR(rettype, name) rettype (*name)
 
-#  define N_LIB_EXPORT  extern
+#  ifdef __cplusplus
+#    define N_LIB_EXPORT  extern "C"
+#  else
+#    define N_LIB_EXPORT  extern
+#  endif
 #  define N_LIB_IMPORT  extern
 #endif
 
@@ -345,7 +353,7 @@ struct TFrame {
 #define nimln(n, file) \
   F.line = n; F.filename = file;
 
-#define NIM_POSIX_INIT  __attribute__((constructor)) 
+#define NIM_POSIX_INIT  __attribute__((constructor))
 
 #if defined(_MSCVER) && defined(__i386__)
 __declspec(naked) int __fastcall NimXadd(volatile int* pNum, int val) {
@@ -380,7 +388,7 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
 #endif
 
 /* Test to see if Nim and the C compiler agree on the size of a pointer.
-   On disagreement, your C compiler will say something like: 
+   On disagreement, your C compiler will say something like:
    "error: 'assert_numbits' declared as an array with a negative size" */
 typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
 #endif
diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim
index 95d49bad7..97784898e 100644
--- a/lib/packages/docutils/rst.nim
+++ b/lib/packages/docutils/rst.nim
@@ -189,7 +189,7 @@ proc getIndent(L: var TLexer, tok: var TToken) =
   tok.line = L.line
   L.col = tok.ival
   tok.ival = max(tok.ival - L.baseIndent, 0)
-  tok.symbol = "\n" & repeatChar(tok.ival)
+  tok.symbol = "\n" & spaces(tok.ival)
 
 proc rawGetTok(L: var TLexer, tok: var TToken) = 
   tok.symbol = ""
@@ -963,7 +963,7 @@ proc parseLiteralBlock(p: var TRstParser): PRstNode =
           break 
         else: 
           add(n.text, "\n")
-          add(n.text, repeatChar(p.tok[p.idx].ival - indent))
+          add(n.text, spaces(p.tok[p.idx].ival - indent))
           inc(p.idx)
       else: 
         add(n.text, p.tok[p.idx].symbol)
diff --git a/lib/packages/docutils/rstast.nim b/lib/packages/docutils/rstast.nim
index 52af672df..614001d76 100644
--- a/lib/packages/docutils/rstast.nim
+++ b/lib/packages/docutils/rstast.nim
@@ -110,7 +110,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) =
   const 
     lvlToChar: array[0..8, char] = ['!', '=', '-', '~', '`', '<', '*', '|', '+']
   if n == nil: return
-  var ind = repeatChar(d.indent)
+  var ind = spaces(d.indent)
   case n.kind
   of rnInner: 
     renderRstSons(d, n, result)
@@ -124,7 +124,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) =
 
     result.add("\n")
     result.add(ind)
-    result.add repeatChar(headlineLen, lvlToChar[n.level])
+    result.add repeat(lvlToChar[n.level], headlineLen)
   of rnOverline:
     result.add("\n")
     result.add(ind)
@@ -132,7 +132,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) =
     var headline = ""
     renderRstSons(d, n, headline)
     
-    let lvl = repeatChar(headline.len - d.indent, lvlToChar[n.level])
+    let lvl = repeat(lvlToChar[n.level], headline.len - d.indent)
     result.add(lvl)
     result.add("\n")
     result.add(headline)
@@ -143,7 +143,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) =
   of rnTransition: 
     result.add("\n\n")
     result.add(ind)
-    result.add repeatChar(78-d.indent, '-')
+    result.add repeat('-', 78-d.indent)
     result.add("\n\n")
   of rnParagraph:
     result.add("\n\n")
@@ -196,7 +196,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) =
     result.add ':'
     result.add tmp
     result.add ':'
-    result.add repeatChar(L - tmp.len - 2)
+    result.add spaces(L - tmp.len - 2)
     renderRstToRst(d, n.sons[1], result)
     
     dec(d.indent, L)
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim
index e1e590877..a385336d6 100644
--- a/lib/packages/docutils/rstgen.nim
+++ b/lib/packages/docutils/rstgen.nim
@@ -461,9 +461,9 @@ proc indentToLevel(level: var int, newLevel: int): string =
   if level == newLevel:
     return
   if newLevel > level:
-    result = repeatStr(newLevel - level, "<ul>")
+    result = repeat("<ul>", newLevel - level)
   else:
-    result = repeatStr(level - newLevel, "</ul>")
+    result = repeat("</ul>", level - newLevel)
   level = newLevel
 
 proc generateDocumentationTOC(entries: seq[TIndexEntry]): string =
@@ -701,7 +701,7 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) =
   # Generate index entry using spaces to indicate TOC level for the output HTML.
   assert n.level >= 0
   setIndexTerm(d, refname, tmp.stripTOCHTML,
-    repeatChar(max(0, n.level), ' ') & tmp)
+    spaces(max(0, n.level)) & tmp)
 
 proc renderOverline(d: PDoc, n: PRstNode, result: var string) = 
   if d.meta[metaTitle].len == 0:
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index 20bfc5c7c..20976e788 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -187,6 +187,34 @@ proc sort*[T](a: var openArray[T],
       dec(m, s*2)
     s = s*2
 
+proc sorted*[T](a: openArray[T], cmp: proc(x, y: T): int {.closure.}, order = SortOrder.Ascending): seq[T] =
+  ## returns `a` sorted by `cmp` in the specified `order`.
+  result = newSeq[T](a.len)
+  for i in 0 .. a.high:
+    result[i] = a[i]
+  sort(result, cmp, order)
+
+template sortByIt*(seq1, op: expr): expr =
+  ## Convenience template around the ``sorted`` proc to reduce typing.
+  ##
+  ## The template injects the ``it`` variable which you can use directly in an
+  ## expression. Example:
+  ##
+  ## .. code-block:: nim
+  ##
+  ##     var users: seq[tuple[id: int, name: string]] =
+  ##       @[(0, "Smith"), (1, "Pratt"), (2, "Sparrow")]
+  ##
+  ##     echo users.sortByIt(it.name)
+  ##
+  var result {.gensym.} = sorted(seq1, proc(x, y: type(seq1[0])): int =
+    var it {.inject.} = x
+    let a = op
+    it = y
+    let b = op
+    result = cmp(a, b))
+  result
+
 proc product*[T](x: openArray[seq[T]]): seq[seq[T]] =
   ## produces the Cartesian product of the array. Warning: complexity
   ## may explode.
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 2038b246d..5041fe2f6 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -816,7 +816,7 @@ proc copy*(p: JsonNode): JsonNode =
 # ------------- pretty printing ----------------------------------------------
 
 proc indent(s: var string, i: int) = 
-  s.add(repeatChar(i))
+  s.add(spaces(i))
 
 proc newIndent(curr, indent: int, ml: bool): int =
   if ml: return curr + indent
diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim
index a3a3d7b5c..23a87d9f8 100644
--- a/lib/pure/lexbase.nim
+++ b/lib/pure/lexbase.nim
@@ -165,5 +165,5 @@ proc getCurrentLine(L: BaseLexer, marker: bool = true): string =
     inc(i)
   add(result, "\n")
   if marker:
-    add(result, repeatChar(getColNumber(L, L.bufpos)) & "^\n")
+    add(result, spaces(getColNumber(L, L.bufpos)) & "^\n")
 
diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim
index b1e2444c3..4c92a7cdf 100644
--- a/lib/pure/parseopt.nim
+++ b/lib/pure/parseopt.nim
@@ -11,9 +11,12 @@
 ## It supports one convenience iterator over all command line options and some
 ## lower-level features.
 ##
-## **Deprecated since version 0.9.3:** Use the `parseopt2 <parseopt2.html>`_
-## module instead as this version has issues with spaces in arguments.
-{.deprecated.}
+## Supported syntax:
+##
+## 1. short options - ``-abcd``, where a, b, c, d are names
+## 2. long option - ``--foo:bar``, ``--foo=bar`` or ``--foo``
+## 3. argument - everything else
+
 {.push debugger: off.}
 
 include "system/inclrtl"
diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim
index 67c80e592..e706f2016 100644
--- a/lib/pure/streams.nim
+++ b/lib/pure/streams.nim
@@ -224,10 +224,12 @@ proc ssReadData(s: Stream, buffer: pointer, bufLen: int): int =
 
 proc ssWriteData(s: Stream, buffer: pointer, bufLen: int) = 
   var s = StringStream(s)
-  if bufLen > 0: 
-    setLen(s.data, s.data.len + bufLen)
-    copyMem(addr(s.data[s.pos]), buffer, bufLen)
-    inc(s.pos, bufLen)
+  if bufLen <= 0:
+    return
+  if s.pos + bufLen > s.data.len:
+    setLen(s.data, s.pos + bufLen)
+  copyMem(addr(s.data[s.pos]), buffer, bufLen)
+  inc(s.pos, bufLen)
 
 proc ssClose(s: Stream) =
   var s = StringStream(s)
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index 39f468ee3..655203cda 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -499,26 +499,47 @@ proc parseEnum*[T: enum](s: string, default: T): T =
       return e
   result = default
 
-proc repeatChar*(count: int, c: char = ' '): string {.noSideEffect,
+proc repeat*(c: char, count: int): string {.noSideEffect,
   rtl, extern: "nsuRepeatChar".} =
   ## Returns a string of length `count` consisting only of
   ## the character `c`. You can use this proc to left align strings. Example:
   ##
   ## .. code-block:: nim
+  ##   proc tabexpand(indent: int, text: string, tabsize: int = 4) =
+  ##     echo '\t'.repeat(indent div tabsize), ' '.repeat(indent mod tabsize), text
+  ##
+  ##   tabexpand(4, "At four")
+  ##   tabexpand(5, "At five")
+  ##   tabexpand(6, "At six")
+  result = newString(count)
+  for i in 0..count-1: result[i] = c
+
+proc repeat*(s: string, n: int): string {.noSideEffect,
+  rtl, extern: "nsuRepeatStr".} =
+  ## Returns String `s` concatenated `n` times.  Example:
+  ##
+  ## .. code-block:: nim
+  ##   echo "+++ STOP ".repeat(4), "+++"
+  result = newStringOfCap(n * s.len)
+  for i in 1..n: result.add(s)
+
+template spaces*(n: int): string =  repeat(' ',n)
+  ## Returns a String with `n` space characters. You can use this proc
+  ## to left align strings. Example:
+  ##
+  ## .. code-block:: nim
   ##   let
   ##     width = 15
   ##     text1 = "Hello user!"
   ##     text2 = "This is a very long string"
-  ##   echo text1 & repeatChar(max(0, width - text1.len)) & "|"
-  ##   echo text2 & repeatChar(max(0, width - text2.len)) & "|"
-  result = newString(count)
-  for i in 0..count-1: result[i] = c
+  ##   echo text1 & spaces(max(0, width - text1.len)) & "|"
+  ##   echo text2 & spaces(max(0, width - text2.len)) & "|"
 
-proc repeatStr*(count: int, s: string): string {.noSideEffect,
-  rtl, extern: "nsuRepeatStr".} =
-  ## Returns `s` concatenated `count` times.
-  result = newStringOfCap(count*s.len)
-  for i in 0..count-1: result.add(s)
+proc repeatChar*(count: int, c: char = ' '): string {.deprecated.} = repeat(c, count)
+  ## deprecated: use repeat() or spaces()
+
+proc repeatStr*(count: int, s: string): string {.deprecated.} = repeat(s, count)
+  ## deprecated: use repeat(string, count) or string.repeat(count)
 
 proc align*(s: string, count: int, padding = ' '): string {.
   noSideEffect, rtl, extern: "nsuAlignString".} =
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index e32ea786a..c39667611 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -628,25 +628,25 @@ proc formatToken(info: TimeInfo, token: string, buf: var string) =
     var fr = ($info.year).len()-2
     if fr < 0: fr = 0
     var fyear = ($info.year)[fr .. ($info.year).len()-1]
-    if fyear.len != 2: fyear = repeatChar(2-fyear.len(), '0') & fyear
+    if fyear.len != 2: fyear = repeat('0', 2-fyear.len()) & fyear
     buf.add(fyear)
   of "yyy":
     var fr = ($info.year).len()-3
     if fr < 0: fr = 0
     var fyear = ($info.year)[fr .. ($info.year).len()-1]
-    if fyear.len != 3: fyear = repeatChar(3-fyear.len(), '0') & fyear
+    if fyear.len != 3: fyear = repeat('0', 3-fyear.len()) & fyear
     buf.add(fyear)
   of "yyyy":
     var fr = ($info.year).len()-4
     if fr < 0: fr = 0
     var fyear = ($info.year)[fr .. ($info.year).len()-1]
-    if fyear.len != 4: fyear = repeatChar(4-fyear.len(), '0') & fyear
+    if fyear.len != 4: fyear = repeat('0', 4-fyear.len()) & fyear
     buf.add(fyear)
   of "yyyyy":
     var fr = ($info.year).len()-5
     if fr < 0: fr = 0
     var fyear = ($info.year)[fr .. ($info.year).len()-1]
-    if fyear.len != 5: fyear = repeatChar(5-fyear.len(), '0') & fyear
+    if fyear.len != 5: fyear = repeat('0', 5-fyear.len()) & fyear
     buf.add(fyear)
   of "z":
     let hrs = (info.timezone div 60) div 60
diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim
index 2e55ff182..6242e589e 100644
--- a/lib/pure/xmldom.nim
+++ b/lib/pure/xmldom.nim
@@ -1083,7 +1083,7 @@ proc addEscaped(s: string): string =
     else: result.add(c)
 
 proc nodeToXml(n: PNode, indent: int = 0): string =
-  result = repeatChar(indent, ' ') & "<" & n.nodeName
+  result = spaces(indent) & "<" & n.nodeName
   if not isNil(n.attributes):
     for i in items(n.attributes):
       result.add(" " & i.name & "=\"" & addEscaped(i.value) & "\"")
@@ -1098,23 +1098,23 @@ proc nodeToXml(n: PNode, indent: int = 0): string =
       of ElementNode:
         result.add(nodeToXml(i, indent + 2))
       of TextNode:
-        result.add(repeatChar(indent * 2, ' '))
+        result.add(spaces(indent * 2))
         result.add(addEscaped(i.nodeValue))
       of CDataSectionNode:
-        result.add(repeatChar(indent * 2, ' '))
+        result.add(spaces(indent * 2))
         result.add("<![CDATA[" & i.nodeValue & "]]>")
       of ProcessingInstructionNode:
-        result.add(repeatChar(indent * 2, ' '))
+        result.add(spaces(indent * 2))
         result.add("<?" & PProcessingInstruction(i).target & " " &
                           PProcessingInstruction(i).data & " ?>")
       of CommentNode:
-        result.add(repeatChar(indent * 2, ' '))
+        result.add(spaces(indent * 2))
         result.add("<!-- " & i.nodeValue & " -->")
       else:
         continue
       result.add("\n")
     # Add the ending tag - </tag>
-    result.add(repeatChar(indent, ' ') & "</" & n.nodeName & ">")
+    result.add(spaces(indent) & "</" & n.nodeName & ">")
 
 proc `$`*(doc: PDocument): string =
   ## Converts a PDocument object into a string representation of it's XML
diff --git a/tests/clearmsg/tconsttypemismatch.nim b/tests/clearmsg/tconsttypemismatch.nim
new file mode 100644
index 000000000..edf480348
--- /dev/null
+++ b/tests/clearmsg/tconsttypemismatch.nim
@@ -0,0 +1,8 @@
+discard """
+  file: "tconsttypemismatch.nim"
+  line: 7
+  errormsg: "type mismatch"
+"""
+# bug #2252
+const foo: int = 1000 / 30
+
diff --git a/tests/generics/tgeneric3.nim b/tests/generics/tgeneric3.nim
index 6fb929efb..289bf1fd5 100644
--- a/tests/generics/tgeneric3.nim
+++ b/tests/generics/tgeneric3.nim
@@ -188,7 +188,7 @@ proc traceTree[T,D](root: PNode[T,D]) =
     write stdout, space
 
   proc doTrace(n: PNode[T,D], level: int) =
-    var space = repeatChar(2 * level)
+    var space = spaces(2 * level)
     traceln(space)
     write stdout, "node: "
     if n == nil:
diff --git a/tests/manyloc/argument_parser/argument_parser.nim b/tests/manyloc/argument_parser/argument_parser.nim
index a507a08e4..060610ae0 100644
--- a/tests/manyloc/argument_parser/argument_parser.nim
+++ b/tests/manyloc/argument_parser/argument_parser.nim
@@ -471,7 +471,7 @@ proc build_help*(expected: seq[Tparameter_specification] = @[],
   let width = prefixes.map(proc (x: string): int = 3 + len(x)).max
 
   for line in zip(prefixes, helps):
-    result.add(line.a & repeatChar(width - line.a.len) & line.b)
+    result.add(line.a & spaces(width - line.a.len) & line.b)
 
 
 proc echo_help*(expected: seq[Tparameter_specification] = @[],
diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim b/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim
index a9759687f..3c5a7835c 100644
--- a/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim
+++ b/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim
@@ -1,5 +1,5 @@
 import streams
-from strutils import repeatChar
+from strutils import repeat
 
 proc readPaddedStr*(s: PStream, length: int, padChar = '\0'): TaintedString = 
   var lastChr = length
@@ -10,7 +10,7 @@ proc readPaddedStr*(s: PStream, length: int, padChar = '\0'): TaintedString =
 proc writePaddedStr*(s: PStream, str: string, length: int, padChar = '\0') =
   if str.len < length:
     s.write(str)
-    s.write(repeatChar(length - str.len, padChar))
+    s.write(repeat(padChar, length - str.len))
   elif str.len > length:
     s.write(str.substr(0, length - 1))
   else:
@@ -37,7 +37,7 @@ when isMainModule:
   testStream.setPosition 0
   testStream.writePaddedStr("Sup", 10)
   echo(repr(testStream), testStream.data.len)
-  doAssert testStream.data == "Sup"&repeatChar(7, '\0')
+  doAssert testStream.data == "Sup"&repeat('\0', 7)
   
   testStream.setPosition 0
   res = testStream.readPaddedStr(10)
diff --git a/tests/manyloc/keineschweine/enet_server/enet_server.nim b/tests/manyloc/keineschweine/enet_server/enet_server.nim
index 6dd1a6a7f..c2e893273 100644
--- a/tests/manyloc/keineschweine/enet_server/enet_server.nim
+++ b/tests/manyloc/keineschweine/enet_server/enet_server.nim
@@ -144,7 +144,7 @@ when isMainModule:
     discard """block:
       var 
         TestFile: FileChallengePair
-        contents = repeatStr(2, "abcdefghijklmnopqrstuvwxyz")
+        contents = repeat("abcdefghijklmnopqrstuvwxyz", 2)
       testFile.challenge = newScFileChallenge("foobar.test", FZoneCfg, contents.len.int32) 
       testFile.file = checksumStr(contents)
       myAssets.add testFile"""
diff --git a/tests/manyloc/keineschweine/keineschweine.nim b/tests/manyloc/keineschweine/keineschweine.nim
index 0a5dc1efc..525d8a054 100644
--- a/tests/manyloc/keineschweine/keineschweine.nim
+++ b/tests/manyloc/keineschweine/keineschweine.nim
@@ -113,7 +113,7 @@ when defined(recordMode):
     isRecording = false
   proc zeroPad*(s: string; minLen: int): string =
     if s.len < minLen:
-      result = repeatChar(minLen - s.len, '0')
+      result = repeat(0, minLen - s.len)
       result.add s
     else:
       result = s
diff --git a/tests/manyloc/keineschweine/lib/map_filter.nim b/tests/manyloc/keineschweine/lib/map_filter.nim
index 966b84b6a..5776c9225 100644
--- a/tests/manyloc/keineschweine/lib/map_filter.nim
+++ b/tests/manyloc/keineschweine/lib/map_filter.nim
@@ -27,9 +27,9 @@ when isMainModule:
   var res = t.map(proc(z: int): int = result = z * 10)
   dumpSeq res
 
-  from strutils import toHex, repeatStr
+  from strutils import toHex
   var foocakes = t.map(proc(z: int): string = 
-    result = toHex((z * 23).biggestInt, 4))
+    result = toHex((z * 23).BiggestInt, 4))
   dumpSeq foocakes
 
   t.mapInPlace(proc(z: int): int = result = z * 30)
diff --git a/tests/manyloc/keineschweine/lib/zlib_helpers.nim b/tests/manyloc/keineschweine/lib/zlib_helpers.nim
index 9a6542d75..fcd0e8d24 100644
--- a/tests/manyloc/keineschweine/lib/zlib_helpers.nim
+++ b/tests/manyloc/keineschweine/lib/zlib_helpers.nim
@@ -24,17 +24,17 @@ when isMainModule:
   import strutils
   var r = compress("Hello")
   echo repr(r)
-  var l = "Hello".len
-  var rr = uncompress(r, l)
+  var ln = "Hello".len
+  var rr = uncompress(r, ln)
   echo repr(rr)
   assert rr == "Hello"
 
-  proc `*`(a: string; b: int): string {.inline.} = result = repeatStr(b, a)
+  proc `*`(a: string; b: int): string {.inline.} = result = repeat(a, b)
   var s = "yo dude sup bruh homie" * 50
   r = compress(s)
   echo s.len, " -> ", r.len
 
-  l = s.len
-  rr = uncompress(r, l)
+  ln = s.len
+  rr = uncompress(r, ln)
   echo r.len, " -> ", rr.len
   assert rr == s
\ No newline at end of file
diff --git a/tests/manyloc/keineschweine/server/old_sg_server.nim b/tests/manyloc/keineschweine/server/old_sg_server.nim
index ac85cbf62..1e57c12a1 100644
--- a/tests/manyloc/keineschweine/server/old_sg_server.nim
+++ b/tests/manyloc/keineschweine/server/old_sg_server.nim
@@ -174,7 +174,7 @@ when isMainModule:
   block:
     var 
       TestFile: FileChallengePair
-      contents = repeatStr(2, "abcdefghijklmnopqrstuvwxyz")
+      contents = repeat("abcdefghijklmnopqrstuvwxyz", 2)
     testFile.challenge = newScFileChallenge("foobar.test", FZoneCfg, contents.len.int32) 
     testFile.file = checksumStr(contents)
     myAssets.add testFile
diff --git a/tests/stdlib/tstrutil.nim b/tests/stdlib/tstrutil.nim
index ce9094bc0..3db484faa 100644
--- a/tests/stdlib/tstrutil.nim
+++ b/tests/stdlib/tstrutil.nim
@@ -46,7 +46,13 @@ assert "/1/2/3".rfind('0') == -1
 assert(toHex(100i16, 32) == "00000000000000000000000000000064")
 assert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C")
 
-main()
-#OUT ha/home/a1xyz/usr/bin
+assert(' '.repeat(8)== "        ")
+assert(" ".repeat(8) == "        ")
+assert(spaces(8) == "        ")
 
+assert(' '.repeat(0) == "")
+assert(" ".repeat(0) == "")
+assert(spaces(0) == "")
 
+main()
+#OUT ha/home/a1xyz/usr/bin
diff --git a/tests/vm/tconsteval.nim b/tests/vm/tconsteval.nim
index 96a1bafe8..4459931c5 100644
--- a/tests/vm/tconsteval.nim
+++ b/tests/vm/tconsteval.nim
@@ -24,7 +24,7 @@ Possible Commands:
   csource [options]        builds the C sources for installation
   zip                      builds the installation ZIP package
   inno                     builds the Inno Setup installer
-""" % [NimVersion & repeatChar(44-len(NimVersion)), 
+""" % [NimVersion & spaces(44-len(NimVersion)), 
        CompileDate, CompileTime]
 
 echo HelpText
diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim
index aeae86300..72e4adc07 100644
--- a/tools/nimgrep.nim
+++ b/tools/nimgrep.nim
@@ -109,7 +109,7 @@ proc highlight(s, match, repl: string, t: tuple[first, last: int],
   for i in t.last+1 .. y: stdout.write(s[i])
   stdout.write("\n")
   if showRepl:
-    stdout.write(repeatChar(alignment-1), "-> ")
+    stdout.write(spaces(alignment-1), "-> ")
     for i in x .. t.first-1: stdout.write(s[i])
     writeColored(repl)
     for i in t.last+1 .. y: stdout.write(s[i])
diff --git a/tools/nimweb.nim b/tools/nimweb.nim
index 8213cf418..a7301195e 100644
--- a/tools/nimweb.nim
+++ b/tools/nimweb.nim
@@ -99,8 +99,8 @@ macro updated(e: expr): expr {.immediate.} =
 proc updatedDate(year, month, day: string): string =
   ## wrapper around the update macro with easy input.
   result = updated("$1-$2-$3T00:00:00Z" % [year,
-    repeatStr(2 - len(month), "0") & month,
-    repeatStr(2 - len(day), "0") & day])
+    repeat("0", 2 - len(month)) & month,
+    repeat("0", 2 - len(day)) & day])
 
 macro entry(e: expr): expr {.immediate.} =
   ## generates the rss xml ``entry`` element.