summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler.nimble2
-rw-r--r--compiler/ccgtypes.nim10
-rw-r--r--compiler/cgen.nim1
-rw-r--r--compiler/commands.nim9
-rw-r--r--compiler/condsyms.nim2
-rw-r--r--compiler/depends.nim2
-rw-r--r--compiler/lambdalifting.nim24
-rw-r--r--compiler/main.nim10
-rw-r--r--compiler/options.nim6
-rw-r--r--compiler/pragmas.nim2
-rw-r--r--compiler/procfind.nim2
-rw-r--r--compiler/semdata.nim11
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semstmts.nim14
-rw-r--r--compiler/sighashes.nim37
-rw-r--r--compiler/sigmatch.nim2
-rw-r--r--compiler/vmgen.nim5
-rw-r--r--doc/manual/ffi.txt6
-rw-r--r--doc/nims.rst5
-rw-r--r--doc/tut1.rst30
-rw-r--r--install_nimble.nims21
-rw-r--r--install_tools.nims16
-rw-r--r--koch.nim55
-rw-r--r--lib/core/macros.nim2
-rw-r--r--lib/pure/asyncdispatch.nim15
-rw-r--r--lib/pure/asyncnet.nim2
-rw-r--r--lib/pure/distros.nim244
-rw-r--r--lib/pure/endians.nim113
-rw-r--r--lib/pure/math.nim2
-rw-r--r--lib/pure/os.nim2
-rw-r--r--lib/pure/times.nim2
-rw-r--r--lib/pure/xmldom.nim4
-rw-r--r--lib/system.nim82
-rw-r--r--lib/system/alloc.nim9
-rw-r--r--lib/system/nimscript.nim44
-rw-r--r--lib/upcoming/asyncdispatch.nim12
-rw-r--r--lib/windows/winlean.nim2
-rw-r--r--tests/async/tpendingcheck.nim21
-rw-r--r--tests/async/tupcoming_async.nim1
-rw-r--r--tests/ccgbugs/tsighash_typename_regression.nim10
-rw-r--r--tests/cpp/tembarrassing_generic_failure.nim8
-rw-r--r--tests/enum/tenumalias.nim7
-rw-r--r--tests/errmsgs/tcannot_capture_builtin.nim8
-rw-r--r--tests/iter/t2closureiters.nim14
-rw-r--r--tools/finish.nim25
-rw-r--r--tools/niminst/buildsh.tmpl2
-rw-r--r--tools/niminst/install.tmpl30
-rw-r--r--tools/niminst/niminst.nim35
-rw-r--r--tools/trimcc.nim12
-rw-r--r--web/community.rst11
-rw-r--r--web/news/e029_version_0_16_0.rst8
-rw-r--r--web/website.ini2
52 files changed, 742 insertions, 261 deletions
diff --git a/compiler.nimble b/compiler.nimble
index d949aa754..2a528ea8b 100644
--- a/compiler.nimble
+++ b/compiler.nimble
@@ -5,7 +5,7 @@ author = "Andreas Rumpf"
 description = "Compiler package providing the compiler sources as a library."
 license = "MIT"
 
-InstallDirs = "doc, compiler"
+InstallDirs = "compiler"
 
 [Deps]
 Requires: "nim >= 0.14.0"
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index a173095e8..aa0b983ff 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -116,16 +116,18 @@ proc mangleName(m: BModule; s: PSym): Rope =
       add(result, m.idOrSig(s))
     s.loc.r = result
 
+
+const
+  irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation,
+                          tyDistinct, tyRange, tyStatic, tyAlias}
+
 proc typeName(typ: PType): Rope =
+  let typ = typ.skipTypes(irrelevantForBackend)
   result = if typ.sym != nil and typ.kind in {tyObject, tyEnum}:
              typ.sym.name.s.mangle.rope
            else:
              ~"TY"
 
-const
-  irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation,
-                          tyDistinct, tyRange, tyStatic, tyAlias}
-
 proc getTypeName(m: BModule; typ: PType; sig: SigHash): Rope =
   var t = typ
   while true:
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 2fcc80eda..eca3c6db2 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -589,6 +589,7 @@ proc generateHeaders(m: BModule) =
     else:
       addf(m.s[cfsHeaders], "#include $1$N", [rope(it.data)])
     it = PStrEntry(it.next)
+  add(m.s[cfsHeaders], "#undef linux" & tnl)
 
 proc initFrame(p: BProc, procname, filename: Rope): Rope =
   discard cgsym(p.module, "nimFrame")
diff --git a/compiler/commands.nim b/compiler/commands.nim
index f85e53511..1ddc85b23 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -56,8 +56,8 @@ const
       "Copyright (c) 2006-" & CompileDate.substr(0, 3) & " by Andreas Rumpf\n"
 
 const
-  Usage = slurp"doc/basicopt.txt".replace("//", "")
-  AdvancedUsage = slurp"doc/advopt.txt".replace("//", "")
+  Usage = slurp"../doc/basicopt.txt".replace("//", "")
+  AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "")
 
 proc getCommandLineDesc(): string =
   result = (HelpMessage % [VersionAsString, platform.OS[platform.hostOS].name,
@@ -331,10 +331,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
       nimblePath(path, info)
   of "nonimblepath", "nobabelpath":
     expectNoArg(switch, arg, pass, info)
-    options.gNoNimblePath = true
-    options.lazyPaths.head = nil
-    options.lazyPaths.tail = nil
-    options.lazyPaths.counter = 0
+    disableNimblePath()
   of "excludepath":
     expectArg(switch, arg, pass, info)
     let path = processPath(arg, info)
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index bcd9592e6..98c72f862 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -99,3 +99,5 @@ proc initDefines*() =
   defineSymbol("nimKnowsNimvm")
   defineSymbol("nimArrIdx")
   defineSymbol("nimImmediateDeprecated")
+  defineSymbol("nimNewShiftOps")
+  defineSymbol("nimDistros")
diff --git a/compiler/depends.nim b/compiler/depends.nim
index 9087f89f2..e8c295a34 100644
--- a/compiler/depends.nim
+++ b/compiler/depends.nim
@@ -24,7 +24,7 @@ type
 var gDotGraph: Rope # the generated DOT file; we need a global variable
 
 proc addDependencyAux(importing, imported: string) =
-  addf(gDotGraph, "$1 -> $2;$n", [rope(importing), rope(imported)])
+  addf(gDotGraph, "$1 -> \"$2\";$n", [rope(importing), rope(imported)])
   # s1 -> s2_4[label="[0-9]"];
 
 proc addDotDependency(c: PPassContext, n: PNode): PNode =
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim
index 692d9265b..8d4badb4e 100644
--- a/compiler/lambdalifting.nim
+++ b/compiler/lambdalifting.nim
@@ -240,16 +240,22 @@ proc liftIterSym*(n: PNode; owner: PSym): PNode =
   result = newNodeIT(nkStmtListExpr, n.info, n.typ)
 
   let hp = getHiddenParam(iter)
-  let env = newSym(skLet, iter.name, owner, n.info)
-  env.typ = hp.typ
-  env.flags = hp.flags
-  var v = newNodeI(nkVarSection, n.info)
-  addVar(v, newSymNode(env))
-  result.add(v)
+  var env: PNode
+  if owner.isIterator:
+    let it = getHiddenParam(owner)
+    addUniqueField(it.typ.sons[0], hp)
+    env = indirectAccess(newSymNode(it), hp, hp.info)
+  else:
+    let e = newSym(skLet, iter.name, owner, n.info)
+    e.typ = hp.typ
+    e.flags = hp.flags
+    env = newSymNode(e)
+    var v = newNodeI(nkVarSection, n.info)
+    addVar(v, env)
+    result.add(v)
   # add 'new' statement:
-  let envAsNode = env.newSymNode
-  result.add newCall(getSysSym"internalNew", envAsNode)
-  result.add makeClosure(iter, envAsNode, n.info)
+  result.add newCall(getSysSym"internalNew", env)
+  result.add makeClosure(iter, env, n.info)
 
 proc freshVarForClosureIter*(s, owner: PSym): PNode =
   let envParam = getHiddenParam(owner)
diff --git a/compiler/main.nim b/compiler/main.nim
index e3ff99870..e6563f281 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -31,11 +31,19 @@ proc semanticPasses =
   registerPass verbosePass
   registerPass semPass
 
+proc writeDepsFile(g: ModuleGraph; project: string) =
+  let f = open(changeFileExt(project, "deps"), fmWrite)
+  for m in g.modules:
+    if m != nil:
+      f.writeLine(toFullPath(m.position.int32))
+  f.close()
+
 proc commandGenDepend(graph: ModuleGraph; cache: IdentCache) =
   semanticPasses()
   registerPass(gendependPass)
-  registerPass(cleanupPass)
+  #registerPass(cleanupPass)
   compileProject(graph, cache)
+  writeDepsFile(graph, gProjectFull)
   generateDot(gProjectFull)
   execExternalProgram("dot -Tpng -o" & changeFileExt(gProjectFull, "png") &
       ' ' & changeFileExt(gProjectFull, "dot"))
diff --git a/compiler/options.nim b/compiler/options.nim
index 50f12d843..e7c9346a7 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -254,6 +254,12 @@ proc removeTrailingDirSep*(path: string): string =
   else:
     result = path
 
+proc disableNimblePath*() =
+  gNoNimblePath = true
+  lazyPaths.head = nil
+  lazyPaths.tail = nil
+  lazyPaths.counter = 0
+
 include packagehandling
 
 proc getNimcacheDir*: string =
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index b9f00399e..a21705208 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -27,7 +27,7 @@ const
     wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
     wOverride, wConstructor, wExportNims}
   converterPragmas* = procPragmas
-  methodPragmas* = procPragmas+{wBase}
+  methodPragmas* = procPragmas+{wBase}-{wImportCpp}
   templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty,
     wDelegator, wExportNims}
   macroPragmas* = {FirstCallConv..LastCallConv, wImmediate, wImportc, wExportc,
diff --git a/compiler/procfind.nim b/compiler/procfind.nim
index 523ea2e2f..137765ddb 100644
--- a/compiler/procfind.nim
+++ b/compiler/procfind.nim
@@ -71,7 +71,7 @@ proc searchForProcNew(c: PContext, scope: PScope, fn: PSym): PSym =
 
   result = initIdentIter(it, scope.symbols, fn.name)
   while result != nil:
-    if result.kind in skProcKinds and sameType(result.typ, fn.typ, flags):
+    if result.kind == fn.kind and sameType(result.typ, fn.typ, flags):
       case equalParams(result.typ.n, fn.typ.n)
       of paramsEqual:
         if (sfExported notin result.flags) and (sfExported in fn.flags):
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 2fec8c757..641dc3304 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -243,7 +243,16 @@ proc makeAndType*(c: PContext, t1, t2: PType): PType =
 
 proc makeOrType*(c: PContext, t1, t2: PType): PType =
   result = newTypeS(tyOr, c)
-  result.sons = @[t1, t2]
+  if t1.kind != tyOr and t2.kind != tyOr:
+    result.sons = @[t1, t2]
+  else:
+    template addOr(t1) =
+      if t1.kind == tyOr:
+        for x in t1.sons: result.rawAddSon x
+      else:
+        result.rawAddSon t1
+    addOr(t1)
+    addOr(t2)
   propagateToOwner(result, t1)
   propagateToOwner(result, t2)
   result.flags.incl((t1.flags + t2.flags) * {tfHasStatic})
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 45d973d86..54a301322 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -903,7 +903,7 @@ proc makeDeref(n: PNode): PNode =
 
 const
   tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
-  tyDotOpTransparent = {tyVar, tyPtr, tyRef}
+  tyDotOpTransparent = {tyVar, tyPtr, tyRef, tyAlias}
 
 proc readTypeParameter(c: PContext, typ: PType,
                        paramName: PIdent, info: TLineInfo): PNode =
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index ec4279e60..365109249 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -70,7 +70,7 @@ proc toCover(t: PType): BiggestInt =
   else:
     result = lengthOrd(skipTypes(t, abstractVar-{tyTypeDesc}))
 
-proc performProcvarCheck(c: PContext, n: PNode, s: PSym) =
+proc performProcvarCheck(c: PContext, info: TLineInfo, s: PSym) =
   ## Checks that the given symbol is a proper procedure variable, meaning
   ## that it
   var smoduleId = getModule(s).id
@@ -80,13 +80,17 @@ proc performProcvarCheck(c: PContext, n: PNode, s: PSym) =
       for module in c.friendModules:
         if smoduleId == module.id:
           break outer
-      localError(n.info, errXCannotBePassedToProcVar, s.name.s)
+      localError(info, errXCannotBePassedToProcVar, s.name.s)
 
 proc semProcvarCheck(c: PContext, n: PNode) =
-  let n = n.skipConv
-  if n.kind == nkSym and n.sym.kind in {skProc, skMethod, skConverter,
+  var n = n.skipConv
+  if n.kind in nkSymChoices:
+    for x in n:
+      if x.sym.kind in {skProc, skMethod, skConverter, skIterator}:
+        performProcvarCheck(c, n.info, x.sym)
+  elif n.kind == nkSym and n.sym.kind in {skProc, skMethod, skConverter,
                                         skIterator}:
-    performProcvarCheck(c, n, n.sym)
+    performProcvarCheck(c, n.info, n.sym)
 
 proc semProc(c: PContext, n: PNode): PNode
 
diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim
index 145d3ff5a..4883479fa 100644
--- a/compiler/sighashes.nim
+++ b/compiler/sighashes.nim
@@ -12,7 +12,7 @@
 import ast, md5
 from hashes import Hash
 from astalgo import debug
-from types import typeToString
+from types import typeToString, preferDesc
 from strutils import startsWith, contains
 
 when false:
@@ -82,6 +82,13 @@ else:
     result = 0
     for x in 0..3:
       result = (result shl 8) or u.MD5Digest[x].int
+type
+  ConsiderFlag* = enum
+    CoProc
+    CoType
+    CoOwnerSig
+
+proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag])
 
 proc hashSym(c: var MD5Context, s: PSym) =
   if sfAnon in s.flags or s.kind == skGenericParam:
@@ -93,6 +100,19 @@ proc hashSym(c: var MD5Context, s: PSym) =
       c &= "."
       it = it.owner
 
+proc hashTypeSym(c: var MD5Context, s: PSym) =
+  if sfAnon in s.flags or s.kind == skGenericParam:
+    c &= ":anon"
+  else:
+    var it = s
+    while it != nil:
+      if sfFromGeneric in it.flags and it.kind in routineKinds and
+          it.typ != nil:
+        hashType c, it.typ, {CoProc}
+      c &= it.name.s
+      c &= "."
+      it = it.owner
+
 proc hashTree(c: var MD5Context, n: PNode) =
   if n == nil:
     c &= "\255"
@@ -118,11 +138,6 @@ proc hashTree(c: var MD5Context, n: PNode) =
   else:
     for i in 0.. <n.len: hashTree(c, n.sons[i])
 
-type
-  ConsiderFlag* = enum
-    CoProc
-    CoType
-
 proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
   if t == nil:
     c &= "\254"
@@ -163,16 +178,22 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
       #  writeStackTrace()
       #  echo "yes ", t.sym.name.s
       #  #quit 1
-      c.hashSym(t.sym)
+      if CoOwnerSig in flags:
+        c.hashTypeSym(t.sym)
+      else:
+        c.hashSym(t.sym)
       if sfAnon in t.sym.flags:
         # generated object names can be identical, so we need to
         # disambiguate furthermore by hashing the field types and names:
+        # mild hack to prevent endless recursions (makes nimforum compile again):
+        excl t.sym.flags, sfAnon
         let n = t.n
         for i in 0 ..< n.len:
           assert n[i].kind == nkSym
           let s = n[i].sym
           c.hashSym s
           c.hashType s.typ, flags
+        incl t.sym.flags, sfAnon
     else:
       c &= t.id
     if t.len > 0 and t.sons[0] != nil:
@@ -246,7 +267,7 @@ when defined(debugSigHashes):
 proc hashType*(t: PType; flags: set[ConsiderFlag] = {CoType}): SigHash =
   var c: MD5Context
   md5Init c
-  hashType c, t, flags
+  hashType c, t, flags+{CoOwnerSig}
   md5Final c, result.Md5Digest
   when defined(debugSigHashes):
     db.exec(sql"INSERT OR IGNORE INTO sighashes(type, hash) VALUES (?, ?)",
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index a94579339..7f7572968 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -180,7 +180,7 @@ proc sumGeneric(t: PType): int =
     of tyAlias: t = t.lastSon
     of tyBool, tyChar, tyEnum, tyObject, tyPointer,
         tyString, tyCString, tyInt..tyInt64, tyFloat..tyFloat128,
-        tyUInt..tyUInt64:
+        tyUInt..tyUInt64, tyCompositeTypeClass:
       return isvar
     else:
       return 0
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 69249abfe..e0f737f08 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -261,8 +261,9 @@ proc gen(c: PCtx; n: PNode; flags: TGenFlags = {}) =
 proc genx(c: PCtx; n: PNode; flags: TGenFlags = {}): TRegister =
   var tmp: TDest = -1
   gen(c, n, tmp, flags)
-  internalAssert tmp >= 0
-  result = TRegister(tmp)
+  #internalAssert tmp >= 0 # 'nim check' does not like this internalAssert.
+  if tmp >= 0:
+    result = TRegister(tmp)
 
 proc clearDest(c: PCtx; n: PNode; dest: var TDest) {.inline.} =
   # stmt is different from 'void' in meta programming contexts.
diff --git a/doc/manual/ffi.txt b/doc/manual/ffi.txt
index d7d9596d2..e9b52eaca 100644
--- a/doc/manual/ffi.txt
+++ b/doc/manual/ffi.txt
@@ -226,4 +226,8 @@ conjunction with the ``exportc`` pragma:
   proc exportme(): int {.cdecl, exportc, dynlib.}
 
 This is only useful if the program is compiled as a dynamic library via the
-``--app:lib`` command line option.
+``--app:lib`` command line option. This pragma only has an effect for the code 
+generation on the Windows target, so when this pragma is forgotten and the dynamic 
+library is only tested on Mac and/or Linux, there won't be an error. On Windows
+this pragma adds ``__declspec(dllexport)`` to the function declaration.
+
diff --git a/doc/nims.rst b/doc/nims.rst
index 12d86a905..967dd4149 100644
--- a/doc/nims.rst
+++ b/doc/nims.rst
@@ -19,6 +19,7 @@ following modules are available:
 * `strutils <strutils.html>`_
 * `ospaths <ospaths.html>`_
 * `math <math.html>`_
+* `distros <distros.html>`_
 
 The `system <system.html>`_ module in NimScript mode additionally supports
 these operations: `nimscript <nimscript.html>`_.
@@ -72,6 +73,10 @@ done:
     setCommand "nop"
 
 
+Look at the module `distros <distros.html>`_ for some support of the
+OS's native package managers.
+
+
 Nimble integration
 ==================
 
diff --git a/doc/tut1.rst b/doc/tut1.rst
index d896a7044..32faf6168 100644
--- a/doc/tut1.rst
+++ b/doc/tut1.rst
@@ -380,6 +380,28 @@ Since counting up occurs so often in programs, Nim also has a `..
   for i in 1..10:
     ...
 
+Zero-indexed counting have two shortcuts ``..<`` and ``..^`` to simplify counting to one less then the higher index:
+
+.. code-block:: nim
+  for i in 0..<10:
+    ...  # 0..9
+
+or
+
+.. code-block:: nim
+  var s = "some string"
+  for i in 0..<s.len:
+    ...
+
+Other useful iterators for collections (like arrays and sequences) are
+* ``items`` and ``mitems``, which provides immutable and mutable elements respectively, and 
+* ``pairs`` and ``mpairs`` which provides the element and an index number (immutable and mutable respectively)
+
+.. code-block:: nim
+  for indx, itm in ["a","b"].pairs:
+    echo itm, " at index ", indx
+  # => a at index 0
+  # => b at index 1
 
 Scopes and the block statement
 ------------------------------
@@ -1516,8 +1538,14 @@ Example:
 A subtle issue with procedural types is that the calling convention of the
 procedure influences the type compatibility: procedural types are only compatible
 if they have the same calling convention. The different calling conventions are
-listed in the `manual <manual.html>`_.
+listed in the `manual <manual.html#types-procedural-type>`_.
 
+Distinct type
+-------------
+A Distinct type allows for the creation of new type that "does not imply a subtype relationship  between it and its base type".
+You must EXPLICITLY define all behaviour for the distinct type.
+To help with this, both the distinct type and its base type can cast from one type to the other.
+Examples are provided in the `manual <manual.html#types-distinct-type>`_.
 
 Modules
 =======
diff --git a/install_nimble.nims b/install_nimble.nims
index 6e929f499..e1b665d58 100644
--- a/install_nimble.nims
+++ b/install_nimble.nims
@@ -1,25 +1,6 @@
 
-import ospaths
-
 mode = ScriptMode.Verbose
 
 echo "This script is deprecated. Use 'koch nimble' instead."
 
-var id = 0
-while dirExists("nimble" & $id):
-  inc id
-
-exec "git clone https://github.com/nim-lang/nimble.git nimble" & $id
-
-withDir "nimble" & $id & "/src":
-  exec "nim c nimble"
-
-mkDir "bin/nimblepkg"
-for file in listFiles("nimble" & $id & "/src/nimblepkg/"):
-  cpFile file, "bin/nimblepkg/" & file.extractFilename
-
-try:
-  mvFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe
-except OSError:
-  cpFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe
-
+exec "koch nimble"
diff --git a/install_tools.nims b/install_tools.nims
index f5f320f78..e7f0aee2c 100644
--- a/install_tools.nims
+++ b/install_tools.nims
@@ -1,20 +1,6 @@
 
-import ospaths
-
 mode = ScriptMode.Verbose
 
 echo "This script is deprecated. Use 'koch tools' instead."
 
-if not dirExists"dist/nimble":
-  echo "[Error] This script only works for the tarball."
-else:
-  let nimbleExe = "./bin/nimble".toExe
-  selfExec "c --noNimblePath -p:compiler -o:" & nimbleExe &
-      " dist/nimble/src/nimble.nim"
-
-  let nimsugExe = "./bin/nimsuggest".toExe
-  selfExec "c --noNimblePath -d:release -p:compiler -o:" & nimsugExe &
-      " dist/nimsuggest/nimsuggest.nim"
-
-  let nimgrepExe = "./bin/nimgrep".toExe
-  selfExec "c -d:release -o:" & nimgrepExe & " tools/nimgrep.nim"
+exec "koch tools"
diff --git a/koch.nim b/koch.nim
index 586565fc7..f117f136c 100644
--- a/koch.nim
+++ b/koch.nim
@@ -23,7 +23,7 @@ when defined(i386) and defined(windows) and defined(vcc):
 import
   os, strutils, parseopt, osproc, streams
 
-const VersionAsString = system.NimVersion #"0.10.2"
+const VersionAsString = system.NimVersion
 
 const
   HelpText = """
@@ -75,6 +75,14 @@ proc exe(f: string): string =
   when defined(windows):
     result = result.replace('/','\\')
 
+template withDir(dir, body) =
+  let old = getCurrentDir()
+  try:
+    setCurrentDir(dir)
+    body
+  finally:
+    setCurrentdir(old)
+
 proc findNim(): string =
   var nim = "nim".exe
   result = "bin" / nim
@@ -131,7 +139,7 @@ proc testUnixInstall() =
       # check the docs build:
       execCleanPath("./koch web", destDir / "bin")
       # check nimble builds:
-      execCleanPath("./bin/nim e install_tools.nims")
+      execCleanPath("./koch tools")
       # check the tests work:
       execCleanPath("./koch tests", destDir / "bin")
     else:
@@ -162,13 +170,11 @@ proc csource(args: string) =
 proc bundleNimbleSrc() =
   ## bunldeNimbleSrc() bundles a specific Nimble commit with the tarball. We
   ## always bundle the latest official release.
-  if dirExists("dist/nimble/.git"):
-    exec("git --git-dir dist/nimble/.git pull")
-  else:
+  if not dirExists("dist/nimble/.git"):
     exec("git clone https://github.com/nim-lang/nimble.git dist/nimble")
-  let tags = execProcess("git --git-dir dist/nimble/.git tag -l v*").splitLines
-  let tag = tags[^1]
-  exec("git --git-dir dist/nimble/.git checkout " & tag)
+  withDir("dist/nimble"):
+    exec("git checkout -f stable")
+    exec("git pull")
 
 proc bundleNimbleExe() =
   bundleNimbleSrc()
@@ -177,13 +183,13 @@ proc bundleNimbleExe() =
   nimexec("c dist/nimble/src/nimble.nim")
   copyExe("dist/nimble/src/nimble".exe, "bin/nimble".exe)
 
-proc buildNimble() =
-  ## buildNimble() builds Nimble for the building via "github". As such, we
-  ## choose the most recent commit of Nimble too.
+proc buildNimble(latest: bool) =
+  # old installations created nim/nimblepkg/*.nim files. We remove these
+  # here so that it cannot cause problems (nimble bug #306):
+  if dirExists("bin/nimblepkg"):
+    removeDir("bin/nimblepkg")
   var installDir = "dist/nimble"
-  if dirExists("dist/nimble/.git"):
-    exec("git --git-dir dist/nimble/.git pull")
-  else:
+  if not dirExists("dist/nimble/.git"):
     # if dist/nimble exist, but is not a git repo, don't mess with it:
     if dirExists(installDir):
       var id = 0
@@ -191,7 +197,13 @@ proc buildNimble() =
         inc id
       installDir = "dist/nimble" & $id
     exec("git clone https://github.com/nim-lang/nimble.git " & installDir)
-  nimexec("c " & installDir / "src/nimble.nim")
+  withDir(installDir):
+    if latest:
+      exec("git checkout -f master")
+    else:
+      exec("git checkout -f stable")
+    exec("git pull")
+  nimexec("c --noNimblePath -p:compiler " & installDir / "src/nimble.nim")
   copyExe(installDir / "src/nimble".exe, "bin/nimble".exe)
 
 proc bundleNimsuggest(buildExe: bool) =
@@ -227,19 +239,14 @@ proc buildTool(toolname, args: string) =
   nimexec("cc $# $#" % [args, toolname])
   copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe)
 
-proc buildTools() =
+proc buildTools(latest: bool) =
   let nimsugExe = "bin/nimsuggest".exe
   nimexec "c --noNimblePath -p:compiler -d:release -o:" & nimsugExe &
       " tools/nimsuggest/nimsuggest.nim"
 
   let nimgrepExe = "bin/nimgrep".exe
   nimexec "c -o:" & nimgrepExe & " tools/nimgrep.nim"
-  if dirExists"dist/nimble":
-    let nimbleExe = "bin/nimble".exe
-    nimexec "c --noNimblePath -p:compiler -o:" & nimbleExe &
-        " dist/nimble/src/nimble.nim"
-  else:
-    buildNimble()
+  buildNimble(latest)
 
 proc nsis(args: string) =
   bundleNimbleExe()
@@ -477,8 +484,8 @@ of cmdArgument:
   of "test", "tests": tests(op.cmdLineRest)
   of "temp": temp(op.cmdLineRest)
   of "winrelease": winRelease()
-  of "nimble": buildNimble()
-  of "tools": buildTools()
+  of "nimble": buildNimble(existsDir(".git"))
+  of "tools": buildTools(existsDir(".git"))
   of "pushcsource", "pushcsources": pushCsources()
   else: showHelp()
 of cmdEnd: showHelp()
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index b0ef54397..3adf4670d 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -80,7 +80,7 @@ type
   NimNodeKinds* = set[NimNodeKind]
   NimTypeKind* = enum  # some types are no longer used, see ast.nim
     ntyNone, ntyBool, ntyChar, ntyEmpty,
-    ntyArrayConstr, ntyNil, ntyExpr, ntyStmt,
+    ntyAlias, ntyNil, ntyExpr, ntyStmt,
     ntyTypeDesc, ntyGenericInvocation, ntyGenericBody, ntyGenericInst,
     ntyGenericParam, ntyDistinct, ntyEnum, ntyOrdinal,
     ntyArray, ntyObject, ntyTuple, ntySet,
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index 1367bc411..b72596060 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -254,8 +254,14 @@ when defined(windows) or defined(nimdoc):
         "Operation performed on a socket which has not been registered with" &
         " the dispatcher yet.")
 
+  proc hasPendingOperations*(): bool =
+    ## Returns `true` if the global dispatcher has pending operations.
+    let p = getGlobalDispatcher()
+    p.handles.len != 0 or p.timers.len != 0 or p.callbacks.len != 0
+
   proc poll*(timeout = 500) =
-    ## Waits for completion events and processes them.
+    ## Waits for completion events and processes them. Raises ``ValueError``
+    ## if there are no pending operations.
     let p = getGlobalDispatcher()
     if p.handles.len == 0 and p.timers.len == 0 and p.callbacks.len == 0:
       raise newException(ValueError,
@@ -1056,8 +1062,15 @@ else:
           newCBs.add(cb)
     callbacks = newCBs & callbacks
 
+  proc hasPendingOperations*(): bool =
+    let p = getGlobalDispatcher()
+    p.selector.len != 0 or p.timers.len != 0 or p.callbacks.len != 0
+
   proc poll*(timeout = 500) =
     let p = getGlobalDispatcher()
+    if p.selector.len == 0 and p.timers.len == 0 and p.callbacks.len == 0:
+      raise newException(ValueError,
+        "No handles or timers registered in dispatcher.")
 
     if p.selector.len > 0:
       for info in p.selector.select(p.adjustedTimeout(timeout)):
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim
index 3b64c278f..5ad3b5263 100644
--- a/lib/pure/asyncnet.nim
+++ b/lib/pure/asyncnet.nim
@@ -36,12 +36,14 @@
 ##   proc processClient(client: AsyncSocket) {.async.} =
 ##     while true:
 ##       let line = await client.recvLine()
+##       if line.len == 0: break
 ##       for c in clients:
 ##         await c.send(line & "\c\L")
 ##
 ##   proc serve() {.async.} =
 ##     clients = @[]
 ##     var server = newAsyncSocket()
+##     server.setSockOpt(OptReuseAddr, true)
 ##     server.bindAddr(Port(12345))
 ##     server.listen()
 ##
diff --git a/lib/pure/distros.nim b/lib/pure/distros.nim
new file mode 100644
index 000000000..ff30f6134
--- /dev/null
+++ b/lib/pure/distros.nim
@@ -0,0 +1,244 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2016 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## This module implements the basics for Linux distribution ("distro")
+## detection and the OS's native package manager. Its primary purpose is to
+## produce output for Nimble packages like::
+##
+##  To complete the installation, run:
+##
+##  sudo apt-get libblas-dev
+##  sudo apt-get libvoodoo
+##
+## The above output could be the result of a code snippet like:
+##
+## .. code-block:: nim
+##
+##   if detectOs(Ubuntu):
+##     foreignDep "lbiblas-dev"
+##     foreignDep "libvoodoo"
+##
+
+from strutils import contains, toLowerAscii
+
+when not defined(nimscript):
+  from osproc import execProcess
+
+type
+  Distribution* {.pure.} = enum ## the list of known distributions
+    Windows ## some version of Windows
+    Posix   ## some Posix system
+    MacOSX  ## some version of OSX
+    Linux   ## some version of Linux
+    Ubuntu
+    Debian
+    Gentoo
+    Fedora
+    RedHat
+
+    OpenSUSE
+    Manjaro
+    Elementary
+    Zorin
+    CentOS
+    Deepin
+    ArchLinux
+    Antergos
+    PCLinuxOS
+    Mageia
+    LXLE
+    Solus
+    Lite
+    Slackware
+    Androidx86
+    Puppy
+    Peppermint
+    Tails
+    AntiX
+    Kali
+    SparkyLinux
+    Apricity
+    BlackLab
+    Bodhi
+    TrueOS
+    ArchBang
+    KaOS
+    WattOS
+    Korora
+    Simplicity
+    RemixOS
+    OpenMandriva
+    Netrunner
+    Alpine
+    BlackArch
+    Ultimate
+    Gecko
+    Parrot
+    KNOPPIX
+    GhostBSD
+    Sabayon
+    Salix
+    Q4OS
+    ClearOS
+    Container
+    ROSA
+    Zenwalk
+    Parabola
+    ChaletOS
+    BackBox
+    MXLinux
+    Vector
+    Maui
+    Qubes
+    RancherOS
+    Oracle
+    TinyCore
+    Robolinux
+    Trisquel
+    Voyager
+    Clonezilla
+    SteamOS
+    Absolute
+    NixOS
+    AUSTRUMI
+    Arya
+    Porteus
+    AVLinux
+    Elive
+    Bluestar
+    SliTaz
+    Solaris
+    Chakra
+    Wifislax
+    Scientific
+    ExTiX
+    Rockstor
+    GoboLinux
+
+    BSD
+    FreeBSD
+    OpenBSD
+    DragonFlyBSD
+
+
+const
+  LacksDevPackages* = {Distribution.Gentoo, Distribution.Slackware,
+    Distribution.ArchLinux}
+
+var unameRes, releaseRes: string ## we cache the result of the 'uname -a'
+                                 ## execution for faster platform detections.
+
+template unameRelease(cmd, cache): untyped =
+  if cache.len == 0:
+    cache = (when defined(nimscript): gorge(cmd) else: execProcess(cmd))
+  cache
+
+template uname(): untyped = unameRelease("uname -a", unameRes)
+template release(): untyped = unameRelease("lsb_release -a", releaseRes)
+
+proc detectOsImpl(d: Distribution): bool =
+  case d
+  of Distribution.Windows: ## some version of Windows
+    result = defined(windows)
+  of Distribution.Posix: result = defined(posix)
+  of Distribution.MacOSX: result = defined(macosx)
+  of Distribution.Linux: result = defined(linux)
+  of Distribution.Ubuntu, Distribution.Gentoo, Distribution.FreeBSD,
+     Distribution.OpenBSD:
+    result = ("-" & $d & " ") in uname()
+  of Distribution.RedHat:
+    result = "Red Hat" in uname()
+  of Distribution.BSD: result = defined(bsd)
+  of Distribution.ArchLinux:
+    result = "arch" in toLowerAscii(uname())
+  of Distribution.OpenSUSE:
+    result = "suse" in toLowerAscii(uname())
+  of Distribution.GoboLinux:
+    result = "-Gobo " in uname()
+  of Distribution.OpenMandriva:
+    result = "mandriva" in toLowerAscii(uname())
+  of Distribution.Solaris:
+    let uname = toLowerAscii(uname())
+    result = ("sun" in uname) or ("solaris" in uname)
+  else:
+    let dd = toLowerAscii($d)
+    result = dd in toLowerAscii(uname()) or dd in toLowerAscii(release())
+
+template detectOs*(d: untyped): bool =
+  ## Distro/OS detection. For convenience the
+  ## required ``Distribution.`` qualifier is added to the
+  ## enum value.
+  detectOsImpl(Distribution.d)
+
+when not defined(nimble):
+  var foreignDeps: seq[string] = @[]
+
+proc foreignCmd*(cmd: string; requiresSudo=false) =
+  ## Registers a foreign command to the intern list of commands
+  ## that can be queried later.
+  let c = (if requiresSudo: "sudo " else: "") & cmd
+  when defined(nimble):
+    nimscriptapi.foreignDeps.add(c)
+  else:
+    foreignDeps.add(c)
+
+proc foreignDepInstallCmd*(foreignPackageName: string): (string, bool) =
+  ## Returns the distro's native command line to install 'foreignPackageName'
+  ## and whether it requires root/admin rights.
+  let p = foreignPackageName
+  when defined(windows):
+    result = ("Chocolatey install " & p, false)
+  elif defined(bsd):
+    result = ("ports install " & p, true)
+  elif defined(linux):
+    if detectOs(Ubuntu) or detectOs(Elementary) or detectOs(Debian) or
+        detectOs(KNOPPIX) or detectOs(SteamOS):
+      result = ("apt-get install " & p, true)
+    elif detectOs(Gentoo):
+      result = ("emerge install " & p, true)
+    elif detectOs(Fedora):
+      result = ("yum install " & p, true)
+    elif detectOs(RedHat):
+      result = ("rpm install " & p, true)
+    elif detectOs(OpenSUSE):
+      result = ("yast -i " & p, true)
+    elif detectOs(Slackware):
+      result = ("installpkg " & p, true)
+    elif detectOs(OpenMandriva):
+      result = ("urpmi " & p, true)
+    elif detectOs(ZenWalk):
+      result = ("netpkg install " & p, true)
+    elif detectOs(NixOS):
+      result = ("nix-env -i " & p, false)
+    elif detectOs(Solaris):
+      result = ("pkg install " & p, true)
+    elif detectOs(PCLinuxOS):
+      result = ("rpm -ivh " & p, true)
+    elif detectOs(ArchLinux):
+      result = ("pacman -S " & p, true)
+    else:
+      result = ("<your package manager here> install " & p, true)
+  else:
+    result = ("brew install " & p, true)
+
+proc foreignDep*(foreignPackageName: string) =
+  ## Registers 'foreignPackageName' to the internal list of foreign deps.
+  ## It is your job to ensure the package name
+  let (installCmd, sudo) = foreignDepInstallCmd(foreignPackageName)
+  foreignCmd installCmd, sudo
+
+proc echoForeignDeps*() =
+  ## Writes the list of registered foreign deps to stdout.
+  for d in foreignDeps:
+    echo d
+
+when false:
+  foreignDep("libblas-dev")
+  foreignDep "libfoo"
+  echoForeignDeps()
diff --git a/lib/pure/endians.nim b/lib/pure/endians.nim
index 5a23169d4..6f80d56ef 100644
--- a/lib/pure/endians.nim
+++ b/lib/pure/endians.nim
@@ -10,38 +10,87 @@
 ## This module contains helpers that deal with different byte orders
 ## (`endian`:idx:).
 
-proc swapEndian64*(outp, inp: pointer) =
-  ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to
-  ## contain at least 8 bytes.
-  var i = cast[cstring](inp)
-  var o = cast[cstring](outp)
-  o[0] = i[7]
-  o[1] = i[6]
-  o[2] = i[5]
-  o[3] = i[4]
-  o[4] = i[3]
-  o[5] = i[2]
-  o[6] = i[1]
-  o[7] = i[0]
-
-proc swapEndian32*(outp, inp: pointer) =
-  ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to
-  ## contain at least 4 bytes.
-  var i = cast[cstring](inp)
-  var o = cast[cstring](outp)
-  o[0] = i[3]
-  o[1] = i[2]
-  o[2] = i[1]
-  o[3] = i[0]
-
-proc swapEndian16*(outp, inp: pointer) =
-  ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to
-  ## contain at least 2 bytes.
-  var
-    i = cast[cstring](inp)
-    o = cast[cstring](outp)
-  o[0] = i[1]
-  o[1] = i[0]
+when defined(gcc) or defined(llvm_gcc) or defined(clang):
+  const useBuiltinSwap = true
+  proc builtin_bswap16(a: uint16): uint16 {.
+      importc: "__builtin_bswap16", nodecl, nosideeffect.}
+
+  proc builtin_bswap32(a: uint32): uint32 {.
+      importc: "__builtin_bswap32", nodecl, nosideeffect.}
+
+  proc builtin_bswap64(a: uint64): uint64 {.
+      importc: "__builtin_bswap64", nodecl, nosideeffect.}
+elif defined(icc):
+  const useBuiltinSwap = true
+  proc builtin_bswap16(a: uint16): uint16 {.
+      importc: "_bswap16", nodecl, nosideeffect.}
+
+  proc builtin_bswap32(a: uint32): uint32 {.
+      importc: "_bswap", nodecl, nosideeffect.}
+
+  proc builtin_bswap64(a: uint64): uint64 {.
+      importc: "_bswap64", nodecl, nosideeffect.}
+elif defined(vcc):
+  const useBuiltinSwap = true
+  proc builtin_bswap16(a: uint16): uint16 {.
+      importc: "_byteswap_ushort", nodecl, header: "<intrin.h>", nosideeffect.}
+
+  proc builtin_bswap32(a: uint32): uint32 {.
+      importc: "_byteswap_ulong", nodecl, header: "<intrin.h>", nosideeffect.}
+
+  proc builtin_bswap64(a: uint64): uint64 {.
+      importc: "_byteswap_uint64", nodecl, header: "<intrin.h>", nosideeffect.}
+else:
+  const useBuiltinSwap = false
+
+when useBuiltinSwap:
+  proc swapEndian64*(outp, inp: pointer) {.inline, nosideeffect.}=
+    var i = cast[ptr uint64](inp)
+    var o = cast[ptr uint64](outp)
+    o[] = builtin_bswap64(i[])
+
+  proc swapEndian32*(outp, inp: pointer) {.inline, nosideeffect.}=
+    var i = cast[ptr uint32](inp)
+    var o = cast[ptr uint32](outp)
+    o[] = builtin_bswap32(i[])
+
+  proc swapEndian16*(outp, inp: pointer) {.inline, nosideeffect.}=
+    var i = cast[ptr uint16](inp)
+    var o = cast[ptr uint16](outp)
+    o[] = builtin_bswap16(i[])
+
+else:
+  proc swapEndian64*(outp, inp: pointer) =
+    ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to
+    ## contain at least 8 bytes.
+    var i = cast[cstring](inp)
+    var o = cast[cstring](outp)
+    o[0] = i[7]
+    o[1] = i[6]
+    o[2] = i[5]
+    o[3] = i[4]
+    o[4] = i[3]
+    o[5] = i[2]
+    o[6] = i[1]
+    o[7] = i[0]
+
+  proc swapEndian32*(outp, inp: pointer) =
+    ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to
+    ## contain at least 4 bytes.
+    var i = cast[cstring](inp)
+    var o = cast[cstring](outp)
+    o[0] = i[3]
+    o[1] = i[2]
+    o[2] = i[1]
+    o[3] = i[0]
+
+  proc swapEndian16*(outp, inp: pointer) =
+    ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to
+    ## contain at least 2 bytes.
+    var i = cast[cstring](inp)
+    var o = cast[cstring](outp)
+    o[0] = i[1]
+    o[1] = i[0]
 
 when system.cpuEndian == bigEndian:
   proc littleEndian64*(outp, inp: pointer) {.inline.} = swapEndian64(outp, inp)
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 4ef169b4f..a8432b6f0 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -213,7 +213,7 @@ when not defined(JS):
     ## .. code-block:: nim
     ##  echo ceil(-2.1) ## -2.0
 
-  when defined(windows) and defined(vcc):
+  when defined(windows) and (defined(vcc) or defined(bcc)):
     # MSVC 2010 don't have trunc/truncf
     # this implementation was inspired by Go-lang Math.Trunc
     proc truncImpl(f: float64): float64 =
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index f077e798a..8a5461567 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1427,7 +1427,7 @@ elif defined(windows):
     if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine())
     return TaintedString(ownArgv[i])
 
-elif not defined(createNimRtl):
+elif not defined(createNimRtl) and not(defined(posix) and appType == "lib"):
   # On Posix, there is no portable way to get the command line from a DLL.
   var
     cmdCount {.importc: "cmdCount".}: cint
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index 99fdb5b0e..39d46c675 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -70,7 +70,7 @@ when defined(posix) and not defined(JS):
 elif defined(windows):
   import winlean
 
-  when defined(vcc):
+  when defined(vcc) or defined(bcc):
     # newest version of Visual C++ defines time_t to be of 64 bits
     type TimeImpl {.importc: "time_t", header: "<time.h>".} = int64
     # visual c's c runtime exposes these under a different name
diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim
index 559f45348..3c891c81b 100644
--- a/lib/pure/xmldom.nim
+++ b/lib/pure/xmldom.nim
@@ -890,7 +890,7 @@ proc tagName*(el: PElement): string =
   return el.fTagName
 
 # Procedures
-proc getAttribute*(el: PElement, name: string): string =
+proc getAttribute*(el: PNode, name: string): string =
   ## Retrieves an attribute value by ``name``
   if isNil(el.attributes):
     return nil
@@ -900,7 +900,7 @@ proc getAttribute*(el: PElement, name: string): string =
   else:
     return nil
 
-proc getAttributeNS*(el: PElement, namespaceURI: string, localName: string): string =
+proc getAttributeNS*(el: PNode, namespaceURI: string, localName: string): string =
   ## Retrieves an attribute value by ``localName`` and ``namespaceURI``
   if isNil(el.attributes):
     return nil
diff --git a/lib/system.nim b/lib/system.nim
index 8209dbc23..309df7f84 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -551,8 +551,6 @@ type
     ##
     ## See the full `exception hierarchy`_.
 
-  TResult* {.deprecated.} = enum Failure, Success
-
 {.deprecated: [TObject: RootObj, PObject: RootRef, TEffect: RootEffect,
   FTime: TimeEffect, FIO: IOEffect, FReadIO: ReadIOEffect,
   FWriteIO: WriteIOEffect, FExecIO: ExecIOEffect,
@@ -870,29 +868,43 @@ when defined(nimnomagic64):
 else:
   proc `mod` *(x, y: int64): int64 {.magic: "ModI64", noSideEffect.}
 
-proc `shr` *(x, y: int): int {.magic: "ShrI", noSideEffect.}
-proc `shr` *(x, y: int8): int8 {.magic: "ShrI", noSideEffect.}
-proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.}
-proc `shr` *(x, y: int32): int32 {.magic: "ShrI", noSideEffect.}
-proc `shr` *(x, y: int64): int64 {.magic: "ShrI", noSideEffect.}
-  ## computes the `shift right` operation of `x` and `y`, filling
-  ## vacant bit positions with zeros.
-  ##
-  ## .. code-block:: Nim
-  ##   0b0001_0000'i8 shr 2 == 0b0000_0100'i8
-  ##   0b1000_0000'i8 shr 8 == 0b0000_0000'i8
-  ##   0b0000_0001'i8 shr 1 == 0b0000_0000'i8
-
-proc `shl` *(x, y: int): int {.magic: "ShlI", noSideEffect.}
-proc `shl` *(x, y: int8): int8 {.magic: "ShlI", noSideEffect.}
-proc `shl` *(x, y: int16): int16 {.magic: "ShlI", noSideEffect.}
-proc `shl` *(x, y: int32): int32 {.magic: "ShlI", noSideEffect.}
-proc `shl` *(x, y: int64): int64 {.magic: "ShlI", noSideEffect.}
-  ## computes the `shift left` operation of `x` and `y`.
-  ##
-  ## .. code-block:: Nim
-  ##  1'i32 shl 4 == 0x0000_0010
-  ##  1'i64 shl 4 == 0x0000_0000_0000_0010
+when defined(nimNewShiftOps):
+  proc `shr` *(x: int, y: SomeInteger): int {.magic: "ShrI", noSideEffect.}
+  proc `shr` *(x: int8, y: SomeInteger): int8 {.magic: "ShrI", noSideEffect.}
+  proc `shr` *(x: int16, y: SomeInteger): int16 {.magic: "ShrI", noSideEffect.}
+  proc `shr` *(x: int32, y: SomeInteger): int32 {.magic: "ShrI", noSideEffect.}
+  proc `shr` *(x: int64, y: SomeInteger): int64 {.magic: "ShrI", noSideEffect.}
+    ## computes the `shift right` operation of `x` and `y`, filling
+    ## vacant bit positions with zeros.
+    ##
+    ## .. code-block:: Nim
+    ##   0b0001_0000'i8 shr 2 == 0b0000_0100'i8
+    ##   0b1000_0000'i8 shr 8 == 0b0000_0000'i8
+    ##   0b0000_0001'i8 shr 1 == 0b0000_0000'i8
+
+
+  proc `shl` *(x: int, y: SomeInteger): int {.magic: "ShlI", noSideEffect.}
+  proc `shl` *(x: int8, y: SomeInteger): int8 {.magic: "ShlI", noSideEffect.}
+  proc `shl` *(x: int16, y: SomeInteger): int16 {.magic: "ShlI", noSideEffect.}
+  proc `shl` *(x: int32, y: SomeInteger): int32 {.magic: "ShlI", noSideEffect.}
+  proc `shl` *(x: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.}
+    ## computes the `shift left` operation of `x` and `y`.
+    ##
+    ## .. code-block:: Nim
+    ##  1'i32 shl 4 == 0x0000_0010
+    ##  1'i64 shl 4 == 0x0000_0000_0000_0010
+else:
+  proc `shr` *(x, y: int): int {.magic: "ShrI", noSideEffect.}
+  proc `shr` *(x, y: int8): int8 {.magic: "ShrI", noSideEffect.}
+  proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.}
+  proc `shr` *(x, y: int32): int32 {.magic: "ShrI", noSideEffect.}
+  proc `shr` *(x, y: int64): int64 {.magic: "ShrI", noSideEffect.}
+
+  proc `shl` *(x, y: int): int {.magic: "ShlI", noSideEffect.}
+  proc `shl` *(x, y: int8): int8 {.magic: "ShlI", noSideEffect.}
+  proc `shl` *(x, y: int16): int16 {.magic: "ShlI", noSideEffect.}
+  proc `shl` *(x, y: int32): int32 {.magic: "ShlI", noSideEffect.}
+  proc `shl` *(x, y: int64): int64 {.magic: "ShlI", noSideEffect.}
 
 proc `and` *(x, y: int): int {.magic: "BitandI", noSideEffect.}
 proc `and` *(x, y: int8): int8 {.magic: "BitandI", noSideEffect.}
@@ -993,11 +1005,18 @@ proc `<%` *(x, y: int64): bool {.magic: "LtU64", noSideEffect.}
 proc `not`*[T: SomeUnsignedInt](x: T): T {.magic: "BitnotI", noSideEffect.}
   ## computes the `bitwise complement` of the integer `x`.
 
-proc `shr`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShrI", noSideEffect.}
-  ## computes the `shift right` operation of `x` and `y`.
+when defined(nimNewShiftOps):
+  proc `shr`*[T: SomeUnsignedInt](x: T, y: SomeInteger): T {.magic: "ShrI", noSideEffect.}
+    ## computes the `shift right` operation of `x` and `y`.
+
+  proc `shl`*[T: SomeUnsignedInt](x: T, y: SomeInteger): T {.magic: "ShlI", noSideEffect.}
+    ## computes the `shift left` operation of `x` and `y`.
+else:
+  proc `shr`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShrI", noSideEffect.}
+    ## computes the `shift right` operation of `x` and `y`.
 
-proc `shl`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShlI", noSideEffect.}
-  ## computes the `shift left` operation of `x` and `y`.
+  proc `shl`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShlI", noSideEffect.}
+    ## computes the `shift left` operation of `x` and `y`.
 
 proc `and`*[T: SomeUnsignedInt](x, y: T): T {.magic: "BitandI", noSideEffect.}
   ## computes the `bitwise and` of numbers `x` and `y`.
@@ -2706,8 +2725,9 @@ when not defined(JS): #and not defined(nimscript):
     when defined(windows):
       # work-around C's sucking abstraction:
       # BUGFIX: stdin and stdout should be binary files!
-      proc c_setmode(handle, mode: cint) {.importc: "_setmode",
-                                           header: "<io.h>".}
+      proc c_setmode(handle, mode: cint) {.
+        importc: when defined(bcc): "setmode" else: "_setmode",
+        header: "<io.h>".}
       var
         O_BINARY {.importc: "O_BINARY", nodecl.}: cint
 
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 5b0955132..3b886b2fc 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -276,10 +276,11 @@ proc pageAddr(p: pointer): PChunk {.inline.} =
   #sysAssert(Contains(allocator.chunkStarts, pageIndex(result)))
 
 proc requestOsChunks(a: var MemRegion, size: int): PBigChunk =
-  if not a.blockChunkSizeIncrease:
-    a.nextChunkSize =
-      if a.currMem < 64 * 1024: PageSize*4
-      else: a.nextChunkSize*2
+  when not defined(emscripten):
+    if not a.blockChunkSizeIncrease:
+      a.nextChunkSize =
+        if a.currMem < 64 * 1024: PageSize*4
+        else: a.nextChunkSize*2
   var size = size
 
   if size > a.nextChunkSize:
diff --git a/lib/system/nimscript.nim b/lib/system/nimscript.nim
index 29466c34d..f675a9472 100644
--- a/lib/system/nimscript.nim
+++ b/lib/system/nimscript.nim
@@ -293,26 +293,28 @@ template task*(name: untyped; description: string; body: untyped): untyped =
     setCommand "nop"
     `name Task`()
 
-var
-  packageName* = ""    ## Nimble support: Set this to the package name. It
-                       ## is usually not required to do that, nims' filename is
-                       ## the default.
-  version*: string     ## Nimble support: The package's version.
-  author*: string      ## Nimble support: The package's author.
-  description*: string ## Nimble support: The package's description.
-  license*: string     ## Nimble support: The package's license.
-  srcDir*: string      ## Nimble support: The package's source directory.
-  binDir*: string      ## Nimble support: The package's binary directory.
-  backend*: string     ## Nimble support: The package's backend.
-
-  skipDirs*, skipFiles*, skipExt*, installDirs*, installFiles*,
-    installExt*, bin*: seq[string] = @[] ## Nimble metadata.
-  requiresData*: seq[string] = @[] ## Exposes the list of requirements for read
-                                   ## and write accesses.
-
-proc requires*(deps: varargs[string]) =
-  ## Nimble support: Call this to set the list of requirements of your Nimble
-  ## package.
-  for d in deps: requiresData.add(d)
+when not defined(nimble):
+  # nimble has its own implementation for these things.
+  var
+    packageName* = ""    ## Nimble support: Set this to the package name. It
+                         ## is usually not required to do that, nims' filename is
+                         ## the default.
+    version*: string     ## Nimble support: The package's version.
+    author*: string      ## Nimble support: The package's author.
+    description*: string ## Nimble support: The package's description.
+    license*: string     ## Nimble support: The package's license.
+    srcDir*: string      ## Nimble support: The package's source directory.
+    binDir*: string      ## Nimble support: The package's binary directory.
+    backend*: string     ## Nimble support: The package's backend.
+
+    skipDirs*, skipFiles*, skipExt*, installDirs*, installFiles*,
+      installExt*, bin*: seq[string] = @[] ## Nimble metadata.
+    requiresData*: seq[string] = @[] ## Exposes the list of requirements for read
+                                     ## and write accesses.
+
+  proc requires*(deps: varargs[string]) =
+    ## Nimble support: Call this to set the list of requirements of your Nimble
+    ## package.
+    for d in deps: requiresData.add(d)
 
 {.pop.}
diff --git a/lib/upcoming/asyncdispatch.nim b/lib/upcoming/asyncdispatch.nim
index ca5c1f64c..78c7afffc 100644
--- a/lib/upcoming/asyncdispatch.nim
+++ b/lib/upcoming/asyncdispatch.nim
@@ -231,8 +231,14 @@ when defined(windows) or defined(nimdoc):
         "Operation performed on a socket which has not been registered with" &
         " the dispatcher yet.")
 
+  proc hasPendingOperations*(): bool =
+    ## Returns `true` if the global dispatcher has pending operations.
+    let p = getGlobalDispatcher()
+    p.handles.len != 0 or p.timers.len != 0 or p.callbacks.len != 0
+
   proc poll*(timeout = 500) =
-    ## Waits for completion events and processes them.
+    ## Waits for completion events and processes them. Raises ``ValueError``
+    ## if there are no pending operations.
     let p = getGlobalDispatcher()
     if p.handles.len == 0 and p.timers.len == 0 and p.callbacks.len == 0:
       raise newException(ValueError,
@@ -1182,6 +1188,10 @@ else:
       raise newException(ValueError, "File descriptor not registered.")
     p.selector.updateHandle(fd.SocketHandle, newEvents)
 
+  proc hasPendingOperations*(): bool =
+    let p = getGlobalDispatcher()
+    not p.selector.isEmpty() or p.timers.len != 0 or p.callbacks.len != 0
+
   proc poll*(timeout = 500) =
     var keys: array[64, ReadyKey[AsyncData]]
 
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index 2441c7267..bb0e7a648 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -790,7 +790,7 @@ const
  IOC_WS2* = 0x08000000
  IOC_INOUT* = IOC_IN or IOC_OUT
 
-template WSAIORW*(x,y): expr = (IOC_INOUT or x or y)
+template WSAIORW*(x,y): untyped = (IOC_INOUT or x or y)
 
 const
   SIO_GET_EXTENSION_FUNCTION_POINTER* = WSAIORW(IOC_WS2,6).DWORD
diff --git a/tests/async/tpendingcheck.nim b/tests/async/tpendingcheck.nim
new file mode 100644
index 000000000..825acb613
--- /dev/null
+++ b/tests/async/tpendingcheck.nim
@@ -0,0 +1,21 @@
+discard """
+  file: "tpendingcheck.nim"
+  exitcode: 0
+  output: ""
+"""
+
+import asyncdispatch
+
+doAssert(not hasPendingOperations())
+
+proc test() {.async.} =
+  await sleepAsync(100)
+
+var f = test()
+while not f.finished:
+  doAssert(hasPendingOperations())
+  poll(10)
+f.read
+
+doAssert(not hasPendingOperations())
+
diff --git a/tests/async/tupcoming_async.nim b/tests/async/tupcoming_async.nim
index 7d255f213..9cdc6fd0a 100644
--- a/tests/async/tupcoming_async.nim
+++ b/tests/async/tupcoming_async.nim
@@ -1,4 +1,5 @@
 discard """
+  cmd: "nim c -r -f $file"
   output: '''
 OK
 OK
diff --git a/tests/ccgbugs/tsighash_typename_regression.nim b/tests/ccgbugs/tsighash_typename_regression.nim
new file mode 100644
index 000000000..7122902d9
--- /dev/null
+++ b/tests/ccgbugs/tsighash_typename_regression.nim
@@ -0,0 +1,10 @@
+# bug #5147
+
+proc foo[T](t: T) =
+  type Wrapper = object
+    get: T
+  let w = Wrapper(get: t)
+  echo w.get
+
+foo(123)
+foo("baz")
diff --git a/tests/cpp/tembarrassing_generic_failure.nim b/tests/cpp/tembarrassing_generic_failure.nim
new file mode 100644
index 000000000..3c31dcdb8
--- /dev/null
+++ b/tests/cpp/tembarrassing_generic_failure.nim
@@ -0,0 +1,8 @@
+discard """
+  cmd: "nim cpp --threads:on $file"
+"""
+
+# bug #5142
+
+var ci: Channel[int]
+ci.open
diff --git a/tests/enum/tenumalias.nim b/tests/enum/tenumalias.nim
new file mode 100644
index 000000000..2d1f70d0e
--- /dev/null
+++ b/tests/enum/tenumalias.nim
@@ -0,0 +1,7 @@
+# bug #5148
+
+type
+  A = enum foo, bar
+  B = A
+
+echo B.foo
diff --git a/tests/errmsgs/tcannot_capture_builtin.nim b/tests/errmsgs/tcannot_capture_builtin.nim
new file mode 100644
index 000000000..3b8aae241
--- /dev/null
+++ b/tests/errmsgs/tcannot_capture_builtin.nim
@@ -0,0 +1,8 @@
+discard """
+errormsg: "'+' cannot be passed to a procvar"
+line: 8
+"""
+
+# bug #2050
+
+let v: proc (a, b: int): int = `+`
diff --git a/tests/iter/t2closureiters.nim b/tests/iter/t2closureiters.nim
new file mode 100644
index 000000000..ceb24548c
--- /dev/null
+++ b/tests/iter/t2closureiters.nim
@@ -0,0 +1,14 @@
+discard """
+  output: '''1'''
+"""
+# bug #3837
+
+iterator t1(): int {.closure.} =
+  yield 1
+
+iterator t2(): int {.closure.} =
+  for i in t1():
+    yield i
+
+for i in t2():
+  echo $i
diff --git a/tools/finish.nim b/tools/finish.nim
index cac001d79..afb3d9fc1 100644
--- a/tools/finish.nim
+++ b/tools/finish.nim
@@ -85,14 +85,33 @@ when defined(windows):
         let arch = execProcess(gccExe, ["-dumpmachine"], nil, {poStdErrToStdOut,
                                                                poUsePath})
         when hostCPU == "i386":
-          result = arch.startsWith("i686-")
+          result = arch.contains("i686-")
         elif hostCPU == "amd64":
-          result = arch.startsWith("x86_64-")
+          result = arch.contains("x86_64-")
         else:
           {.error: "Unknown CPU for Windows.".}
       except OSError, IOError:
         result = false
 
+  proc defaultMingwLocations(): seq[string] =
+    proc probeDir(dir: string; result: var seq[string]) =
+      for k, x in walkDir(dir, relative=true):
+        if k in {pcDir, pcLinkToDir}:
+          if x.contains("mingw") or x.contains("posix"):
+            let dest = dir / x
+            probeDir(dest, result)
+            result.add(dest)
+
+    result = @["dist/mingw", "../mingw", r"C:\mingw"]
+    let pfx86 = getEnv("programfiles(x86)")
+    let pf = getEnv("programfiles")
+    when hostCPU == "i386":
+      probeDir(pfx86, result)
+      probeDir(pf, result)
+    else:
+      probeDir(pf, result)
+      probeDir(pfx86, result)
+
   proc tryDirs(incompat: var seq[string]; dirs: varargs[string]): string =
     let bits = $(sizeof(pointer)*8)
     for d in dirs:
@@ -132,7 +151,7 @@ proc main() =
         addToPathEnv(desiredPath)
     if mingWchoices.len == 0:
       # No mingw in path, so try a few locations:
-      let alternative = tryDirs(incompat, "dist/mingw", "../mingw", r"C:\mingw")
+      let alternative = tryDirs(incompat, defaultMingwLocations())
       if alternative.len == 0:
         if incompat.len > 0:
           echo "The following *incompatible* MingW installations exist"
diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl
index c571f4d66..aaefa88c6 100644
--- a/tools/niminst/buildsh.tmpl
+++ b/tools/niminst/buildsh.tmpl
@@ -126,6 +126,8 @@ case $ucpu in
     mycpu="mips" ;;
   *arm*|*armv6l* )
     mycpu="arm" ;;
+  *aarch64* )
+    mycpu="arm64" ;;
   *)
     echo 2>&1 "Error: unknown processor: $ucpu"
     exit 1
diff --git a/tools/niminst/install.tmpl b/tools/niminst/install.tmpl
index d72b132ef..91504891d 100644
--- a/tools/niminst/install.tmpl
+++ b/tools/niminst/install.tmpl
@@ -3,35 +3,7 @@
 #  result = "#! /bin/sh\n# Generated by niminst\n"
 #  var proj = c.name.toLowerAscii
 
-## Current directory you start script from
-BASE_DIR=$(pwd)
-
-## The following one-liner takes directory path which contains install script.
-## `command -v -- "$0"` takes path if script sourced from interactive shell
-## `dirname` returns relative directory path to install script
-## `cd -P` dive into directory to use `pwd`
-## `pwd -P` prints full path to install script directory path
-## -P option allows to use symlinks in path
-## Good explanation can be found here:
-## http://stackoverflow.com/questions/29832037/how-to-get-script-directory-in-posix-sh
-NIM_DIR=$(cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P)
-
-go_back() {
-  cd $BASE_DIR
-}
-
-## Go to base dir on exit
-trap go_back EXIT
-
-install_error() {
-  echo "Nim installation failed!"
-  exit 1
-}
-
-## Exit if any command failed
-trap install_error ERR ## `set -e` alternative
-
-cd $NIM_DIR
+set -e
 
 if [ $# -eq 1 ] ; then
 # if c.cat[fcUnixBin].len > 0:
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim
index e0b8ad9b3..e7e978dc0 100644
--- a/tools/niminst/niminst.nim
+++ b/tools/niminst/niminst.nim
@@ -14,7 +14,8 @@ when haveZipLib:
   import zipfiles
 
 import
-  os, osproc, strutils, parseopt, parsecfg, strtabs, streams, debcreation
+  os, osproc, strutils, parseopt, parsecfg, strtabs, streams, debcreation,
+  securehash
 
 const
   maxOS = 20 # max number of OSes
@@ -476,23 +477,23 @@ proc writeFile(filename, content, newline: string) =
   else:
     quit("Cannot open for writing: " & filename)
 
-proc removeDuplicateFiles(c: var ConfigData) =
-  for osA in countdown(c.oses.len, 1):
-    for cpuA in countdown(c.cpus.len, 1):
+proc deduplicateFiles(c: var ConfigData) =
+  var tab = newStringTable()
+  let build = getOutputDir(c)
+  for osA in countup(1, c.oses.len):
+    for cpuA in countup(1, c.cpus.len):
       if c.cfiles[osA][cpuA].isNil: c.cfiles[osA][cpuA] = @[]
       if c.explicitPlatforms and not c.platforms[osA][cpuA]: continue
-      for i in 0..c.cfiles[osA][cpuA].len-1:
-        var dup = c.cfiles[osA][cpuA][i]
-        var f = extractFilename(dup)
-        for osB in 1..c.oses.len:
-          for cpuB in 1..c.cpus.len:
-            if osB != osA or cpuB != cpuA:
-              var orig = buildDir(osB, cpuB) / f
-              if existsFile(orig) and existsFile(dup) and
-                  sameFileContent(orig, dup):
-                # file is identical, so delete duplicate:
-                removeFile(dup)
-                c.cfiles[osA][cpuA][i] = orig
+      for dup in mitems(c.cfiles[osA][cpuA]):
+        let key = $secureHashFile(build / dup)
+        let val = build / buildDir(osA, cpuA) / extractFilename(dup)
+        let orig = tab.getOrDefault(key)
+        if orig.len > 0:
+          # file is identical, so delete duplicate:
+          removeFile(dup)
+          dup = orig
+        else:
+          tab[key] = val
 
 proc writeInstallScripts(c: var ConfigData) =
   if c.installScript:
@@ -536,7 +537,7 @@ proc srcdist(c: var ConfigData) =
         copyFile(dest=dest, source=c.cfiles[osA][cpuA][i])
         c.cfiles[osA][cpuA][i] = relDest
   # second pass: remove duplicate files
-  removeDuplicateFiles(c)
+  deduplicateFiles(c)
   writeFile(getOutputDir(c) / buildShFile, generateBuildShellScript(c), "\10")
   inclFilePermissions(getOutputDir(c) / buildShFile, {fpUserExec, fpGroupExec, fpOthersExec})
   writeFile(getOutputDir(c) / makeFile, generateMakefile(c), "\10")
diff --git a/tools/trimcc.nim b/tools/trimcc.nim
index 276ea1dbe..959eaf310 100644
--- a/tools/trimcc.nim
+++ b/tools/trimcc.nim
@@ -1,6 +1,6 @@
 # Trim C compiler installation to a minimum
 
-import strutils, os, pegs, strtabs, math, threadpool, times
+import strutils, os, pegs, strtabs, math, times
 
 const
   Essential = """gcc.exe g++.exe gdb.exe ld.exe as.exe c++.exe cpp.exe cc1.exe
@@ -20,7 +20,7 @@ proc includes(headerpath, headerfile: string, whitelist: StringTableRef) =
                      comment <- '/*' @ '*/' / '//' .*
                      ws <- (comment / \s+)* """:
       let m = matches[0].extractFilename
-      if whitelist[m] != "processed":
+      if whitelist.getOrDefault(m) != "processed":
         whitelist[m] = "found"
 
 proc processIncludes(dir: string, whitelist: StringTableRef) =
@@ -29,10 +29,10 @@ proc processIncludes(dir: string, whitelist: StringTableRef) =
     of pcFile:
       let name = extractFilename(path)
       if ('.' notin name and "include" in path) or ("c++" in path):
-        let n = whitelist[name]
+        let n = whitelist.getOrDefault(name)
         if n != "processed": whitelist[name] = "found"
       if name.endswith(".h"):
-        let n = whitelist[name]
+        let n = whitelist.getOrDefault(name)
         if n == "found": includes(path, name, whitelist)
     of pcDir: processIncludes(path, whitelist)
     else: discard
@@ -72,8 +72,8 @@ proc newName(f: string): string =
 proc ccStillWorks(): bool =
   const
     c1 = r"nim c --verbosity:0 --force_build koch"
-    c2 = r"nim c --verbosity:0 --force_build --threads:on --out:tempOne.exe trimcc"
-    c3 = r"nim c --verbosity:0 --force_build --threads:on --out:tempTwo.exe fakeDeps"
+    c2 = r"nim c --verbosity:0 --force_build --threads:on --out:tempOne.exe tools/trimcc"
+    c3 = r"nim c --verbosity:0 --force_build --threads:on --out:tempTwo.exe tools/fakeDeps"
     c4 = r".\koch.exe"
     c5 = r".\tempOne.exe"
     c6 = r".\tempTwo.exe"
diff --git a/web/community.rst b/web/community.rst
index 9ce87b546..1e4faff91 100644
--- a/web/community.rst
+++ b/web/community.rst
@@ -97,7 +97,7 @@ Nim's Community
 
   Meetup
   ------
-  
+
   The `Nim BR Meetup <http://www.meetup.com/pt-BR/nim-br>`_ is a brazilian user group about Nim where they are having discussions, talks or workshops about Nim programming language.
 
 .. container:: standout
@@ -132,7 +132,7 @@ Nim's Community
   BountySource
 
     .. raw:: html
-      
+
       <img src="https://img.shields.io/bountysource/team/mozilla-core/activity.svg">
 
   Paypal
@@ -140,10 +140,11 @@ Nim's Community
 
       <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
       <input type="hidden" name="cmd" value="_s-xclick">
-      <input type="hidden" name="hosted_button_id" value="ZQC6CVEEYNTLN">
-      <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
-      <img alt="" border="0" src="https://www.paypalobjects.com/de_DE/i/scr/pixel.gif" width="1" height="1">
+      <input type="hidden" name="hosted_button_id" value="C6PBFRF4WDR2E">
+      <input type="image" src="https://www.paypalobjects.com/en_US/GB/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal – The safer, easier way to pay online!">
+      <img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1">
       </form>
 
+
   Bitcoin
     Bitcoin address: 1BXfuKM2uvoD6mbx4g5xM3eQhLzkCK77tJ
diff --git a/web/news/e029_version_0_16_0.rst b/web/news/e029_version_0_16_0.rst
index 4f5571256..a1cc54417 100644
--- a/web/news/e029_version_0_16_0.rst
+++ b/web/news/e029_version_0_16_0.rst
@@ -43,6 +43,10 @@ Library Additions
   ``terminalWidthIoctl`` and ``terminalSize`` to the ``terminal``
   `(doc) <http://nim-lang.org/docs/terminal.html>`_ module.
 
+- Added new module ``distros``
+  `(doc) <http://nim-lang.org/docs/distros.html>`_  that can be used in Nimble
+  packages to aid in supporting the OS's native package managers.
+
 
 Tool Additions
 --------------
@@ -51,6 +55,10 @@ Tool Additions
 Compiler Additions
 ------------------
 
+- The C/C++ code generator has been rewritten to use stable
+  name mangling rules. This means that compile times for
+  edit-compile-run cycles are much reduced.
+
 
 Language Additions
 ------------------
diff --git a/web/website.ini b/web/website.ini
index 3b8203cc0..b929712bf 100644
--- a/web/website.ini
+++ b/web/website.ini
@@ -62,7 +62,7 @@ srcdoc2: "pure/nativesockets;pure/asynchttpserver;pure/net;pure/selectors;pure/f
 srcdoc2: "deprecated/pure/ftpclient"
 srcdoc2: "pure/asyncfile;pure/asyncftpclient"
 srcdoc2: "pure/md5;pure/rationals"
-srcdoc2: "posix/posix"
+srcdoc2: "posix/posix;distros"
 srcdoc2: "pure/fenv;pure/securehash;impure/rdstdin"
 srcdoc2: "pure/basic2d;pure/basic3d;pure/mersenne;pure/coro;pure/httpcore"