summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/core/macros.nim11
-rw-r--r--lib/nimbase.h6
-rw-r--r--lib/packages/docutils/rst.nim2
-rw-r--r--lib/posix/posix.nim12
-rw-r--r--lib/pure/asyncdispatch.nim10
-rw-r--r--lib/pure/collections/queues.nim2
-rw-r--r--lib/pure/collections/rtarrays.nim2
-rw-r--r--lib/pure/collections/tables.nim33
-rw-r--r--lib/pure/json.nim7
-rw-r--r--lib/pure/logging.nim2
-rw-r--r--lib/pure/nimprof.nim4
-rw-r--r--lib/pure/os.nim2
-rw-r--r--lib/pure/ospaths.nim28
-rw-r--r--lib/pure/osproc.nim2
-rw-r--r--lib/pure/random.nim9
-rw-r--r--lib/pure/terminal.nim4
-rw-r--r--lib/pure/times.nim6
-rw-r--r--lib/system.nim8
-rw-r--r--lib/system/assign.nim4
-rw-r--r--lib/system/debugger.nim2
-rw-r--r--lib/system/endb.nim2
-rw-r--r--lib/system/excpt.nim10
-rw-r--r--lib/system/gc.nim22
-rw-r--r--lib/system/gc_common.nim4
-rw-r--r--lib/system/hti.nim2
-rw-r--r--lib/system/jssys.nim2
-rw-r--r--lib/system/mmdisp.nim14
-rw-r--r--lib/system/nimscript.nim28
-rw-r--r--lib/system/profiler.nim2
-rw-r--r--lib/system/repr.nim4
-rw-r--r--lib/system/sets.nim2
-rw-r--r--lib/system/sysio.nim2
-rw-r--r--lib/system/threads.nim4
-rw-r--r--lib/windows/winlean.nim2
34 files changed, 191 insertions, 65 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 85ebdbfd0..9623bec28 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -692,6 +692,14 @@ proc `pragma=`*(someProc: NimNode; val: NimNode){.compileTime.}=
   assert val.kind in {nnkEmpty, nnkPragma}
   someProc[4] = val
 
+proc addPragma*(someProc, pragma: NimNode) {.compileTime.} =
+  ## Adds pragma to routine definition
+  someProc.expectRoutine
+  var pragmaNode = someProc.pragma
+  if pragmaNode.isNil or pragmaNode.kind == nnkEmpty:
+    pragmaNode = newNimNode(nnkPragma)
+    someProc.pragma = pragmaNode
+  pragmaNode.add(pragma)
 
 template badNodeKind(k; f): stmt{.immediate.} =
   assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`"
@@ -884,7 +892,7 @@ proc boolVal*(n: NimNode): bool {.compileTime, noSideEffect.} =
   else: n == bindSym"true" # hacky solution for now
 
 when not defined(booting):
-  template emit*(e: static[string]): stmt =
+  template emit*(e: static[string]): stmt {.deprecated.} =
     ## accepts a single string argument and treats it as nim code
     ## that should be inserted verbatim in the program
     ## Example:
@@ -892,6 +900,7 @@ when not defined(booting):
     ## .. code-block:: nim
     ##   emit("echo " & '"' & "hello world".toUpper & '"')
     ##
+    ## Deprecated since version 0.15 since it's so rarely useful.
     macro payload: stmt {.gensym.} =
       result = parseStmt(e)
     payload()
diff --git a/lib/nimbase.h b/lib/nimbase.h
index d5a551352..3635ca006 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -102,7 +102,7 @@ __clang__
        defined __ICL || \
        defined __DMC__ || \
        defined __BORLANDC__ )
-#  define NIM_THREADVAR __declspec(thread) 
+#  define NIM_THREADVAR __declspec(thread)
 /* note that ICC (linux) and Clang are covered by __GNUC__ */
 #elif defined __GNUC__ || \
        defined __SUNPRO_C || \
@@ -449,8 +449,8 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
 
 /* 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:
-   "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];
+   "error: 'Nim_and_C_compiler_disagree_on_target_architecture' declared as an array with a negative size" */
+typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
 #endif
 
 #ifdef  __cplusplus
diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim
index ebe6fa19b..53699166f 100644
--- a/lib/packages/docutils/rst.nim
+++ b/lib/packages/docutils/rst.nim
@@ -49,7 +49,7 @@ type
               TMsgKind: MsgKind].}
 
 const
-  messages: array [MsgKind, string] = [
+  messages: array[MsgKind, string] = [
     meCannotOpenFile: "cannot open '$1'",
     meExpected: "'$1' expected",
     meGridTableNotImplemented: "grid table is not implemented",
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index 9718741a6..cd21b5c8b 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -110,7 +110,7 @@ type
                     ## (not POSIX)
       when defined(linux) or defined(bsd):
         d_off*: Off  ## Not an offset. Value that ``telldir()`` would return.
-    d_name*: array [0..255, char] ## Name of entry.
+    d_name*: array[0..255, char] ## Name of entry.
 
   Tflock* {.importc: "struct flock", final, pure,
             header: "<fcntl.h>".} = object ## flock type
@@ -242,7 +242,7 @@ type
                    ## network to which this node is attached, if any.
       release*,    ## Current release level of this implementation.
       version*,    ## Current version level of this release.
-      machine*: array [0..255, char] ## Name of the hardware type on which the
+      machine*: array[0..255, char] ## Name of the hardware type on which the
                                      ## system is running.
 
   Sem* {.importc: "sem_t", header: "<semaphore.h>", final, pure.} = object
@@ -463,12 +463,12 @@ type
   SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>",
               pure, final.} = object ## struct sockaddr
     sa_family*: TSa_Family         ## Address family.
-    sa_data*: array [0..255, char] ## Socket address (variable-length data).
+    sa_data*: array[0..255, char] ## Socket address (variable-length data).
 
   Sockaddr_un* {.importc: "struct sockaddr_un", header: "<sys/un.h>",
               pure, final.} = object ## struct sockaddr_un
     sun_family*: TSa_Family         ## Address family.
-    sun_path*: array [0..Sockaddr_un_path_length-1, char] ## Socket path
+    sun_path*: array[0..Sockaddr_un_path_length-1, char] ## Socket path
 
   Sockaddr_storage* {.importc: "struct sockaddr_storage",
                        header: "<sys/socket.h>",
@@ -526,7 +526,7 @@ type
 
   In6Addr* {.importc: "struct in6_addr", pure, final,
               header: "<netinet/in.h>".} = object ## struct in6_addr
-    s6_addr*: array [0..15, char]
+    s6_addr*: array[0..15, char]
 
   Sockaddr_in6* {.importc: "struct sockaddr_in6", pure, final,
                    header: "<netinet/in.h>".} = object ## struct sockaddr_in6
@@ -2653,7 +2653,7 @@ proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: int): cint {.
 proc realpath*(name, resolved: cstring): cstring {.
   importc: "realpath", header: "<stdlib.h>".}
 
-proc utimes*(path: cstring, times: ptr array [2, Timeval]): int {.
+proc utimes*(path: cstring, times: ptr array[2, Timeval]): int {.
   importc: "utimes", header: "<sys/time.h>".}
   ## Sets file access and modification times.
   ##
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index be6522c36..15d9ab02e 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -1699,8 +1699,10 @@ proc processBody(node, retFutureSym: NimNode,
       else:
         result.add newCall(newIdentNode("complete"), retFutureSym)
     else:
-      result.add newCall(newIdentNode("complete"), retFutureSym,
-        node[0].processBody(retFutureSym, subTypeIsVoid, tryStmt))
+      let x = node[0].processBody(retFutureSym, subTypeIsVoid, tryStmt)
+      if x.kind == nnkYieldStmt: result.add x
+      else:
+        result.add newCall(newIdentNode("complete"), retFutureSym, x)
 
     result.add newNimNode(nnkReturnStmt, node).add(newNilLit())
     return # Don't process the children of this return stmt
@@ -1896,7 +1898,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
 
   # -> createCb(retFuture)
   #var cbName = newIdentNode("cb")
-  var procCb = newCall(bindSym"createCb", retFutureSym, iteratorNameSym,
+  var procCb = getAst createCb(retFutureSym, iteratorNameSym,
                        newStrLitNode(prc[0].getName))
   outerProcBody.add procCb
 
@@ -1931,6 +1933,8 @@ macro async*(prc: stmt): stmt {.immediate.} =
       result.add asyncSingleProc(oneProc)
   else:
     result = asyncSingleProc(prc)
+  when defined(nimDumpAsync):
+    echo repr result
 
 proc recvLine*(socket: AsyncFD): Future[string] {.async.} =
   ## Reads a line of data from ``socket``. Returned future will complete once
diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim
index 911816518..399e4d413 100644
--- a/lib/pure/collections/queues.nim
+++ b/lib/pure/collections/queues.nim
@@ -152,11 +152,13 @@ proc add*[T](q: var Queue[T], item: T) =
   q.data[q.wr] = item
   q.wr = (q.wr + 1) and q.mask
 
+proc default[T](t: typedesc[T]): T {.inline.} = discard
 proc pop*[T](q: var Queue[T]): T {.inline, discardable.} =
   ## Remove and returns the first (oldest) element of the queue `q`.
   emptyCheck(q)
   dec q.count
   result = q.data[q.rd]
+  q.data[q.rd] = default(type(result))
   q.rd = (q.rd + 1) and q.mask
 
 proc enqueue*[T](q: var Queue[T], item: T) =
diff --git a/lib/pure/collections/rtarrays.nim b/lib/pure/collections/rtarrays.nim
index 9d8085643..2abe9d1f8 100644
--- a/lib/pure/collections/rtarrays.nim
+++ b/lib/pure/collections/rtarrays.nim
@@ -18,7 +18,7 @@ type
   RtArray*[T] = object  ##
     L: Natural
     spart: seq[T]
-    apart: array [ArrayPartSize, T]
+    apart: array[ArrayPartSize, T]
   UncheckedArray* {.unchecked.}[T] = array[0..100_000_000, T]
 
 template usesSeqPart(x): expr = x.L > ArrayPartSize
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 9dc29fe69..8d56669da 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -16,6 +16,39 @@
 ## semantics, this means that ``=`` performs a copy of the hash table.
 ## For **reference** semantics use the ``Ref`` variant: ``TableRef``,
 ## ``OrderedTableRef``, ``CountTableRef``.
+## To give an example, when `a` is a Table, then `var b = a` gives `b`
+## as a new independent table. b is initialised with the contents of `a`.
+## Changing `b` does not affect `a` and vice versa:
+##
+## .. code-block::
+##   import tables
+##
+##   var
+##     a = {1: "one", 2: "two"}.toTable  # creates a Table
+##     b = a
+##
+##   echo a, b  # output: {1: one, 2: two}{1: one, 2: two}
+##
+##   b[3] = "three"
+##   echo a, b  # output: {1: one, 2: two}{1: one, 2: two, 3: three}
+##   echo a == b  # output: false
+##
+## On the other hand, when `a` is a TableRef instead, then changes to `b` also affect `a`.
+## Both `a` and `b` reference the same data structure:
+##
+## .. code-block::
+##   import tables
+##
+##   var
+##     a = {1: "one", 2: "two"}.newTable  # creates a TableRef
+##     b = a
+##
+##   echo a, b  # output: {1: one, 2: two}{1: one, 2: two}
+##
+##   b[3] = "three"
+##   echo a, b  # output: {1: one, 2: two, 3: three}{1: one, 2: two, 3: three}
+##   echo a == b  # output: true
+##
 ##
 ## If you are using simple standard types like ``int`` or ``string`` for the
 ## keys of the table you won't have any problems, but as soon as you try to use
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index b4eecdf88..19947fbc2 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -126,7 +126,7 @@ type
   TJsonParser: JsonParser, TTokKind: TokKind].}
 
 const
-  errorMessages: array [JsonError, string] = [
+  errorMessages: array[JsonError, string] = [
     "no error",
     "invalid token",
     "string expected",
@@ -139,7 +139,7 @@ const
     "EOF expected",
     "expression expected"
   ]
-  tokToStr: array [TokKind, string] = [
+  tokToStr: array[TokKind, string] = [
     "invalid token",
     "EOF",
     "string literal",
@@ -712,6 +712,7 @@ proc `%`*(b: bool): JsonNode =
 
 proc `%`*(keyVals: openArray[tuple[key: string, val: JsonNode]]): JsonNode =
   ## Generic constructor for JSON data. Creates a new `JObject JsonNode`
+  if keyvals.len == 0: return newJArray()
   result = newJObject()
   for key, val in items(keyVals): result.fields[key] = val
 
@@ -1126,7 +1127,7 @@ proc parseJson(p: var JsonParser): JsonNode =
     discard getTok(p)
     while p.tok != tkCurlyRi:
       if p.tok != tkString:
-        raiseParseErr(p, "string literal as key expected")
+        raiseParseErr(p, "string literal as key")
       var key = p.a
       discard getTok(p)
       eat(p, tkColon)
diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim
index 8a0d2fedd..6a27e6af8 100644
--- a/lib/pure/logging.nim
+++ b/lib/pure/logging.nim
@@ -61,7 +61,7 @@ type
     lvlNone       ## no levels active
 
 const
-  LevelNames*: array [Level, string] = [
+  LevelNames*: array[Level, string] = [
     "DEBUG", "DEBUG", "INFO", "NOTICE", "WARN", "ERROR", "FATAL", "NONE"
   ]
 
diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim
index 5a7deaab0..956c35b2f 100644
--- a/lib/pure/nimprof.nim
+++ b/lib/pure/nimprof.nim
@@ -27,7 +27,7 @@ const
   tickCountCorrection = 50_000
 
 when not declared(system.StackTrace):
-  type StackTrace = array [0..20, cstring]
+  type StackTrace = array[0..20, cstring]
   {.deprecated: [TStackTrace: StackTrace].}
 
 # We use a simple hash table of bounded size to keep track of the stack traces:
@@ -35,7 +35,7 @@ type
   ProfileEntry = object
     total: int
     st: StackTrace
-  ProfileData = array [0..64*1024-1, ptr ProfileEntry]
+  ProfileData = array[0..64*1024-1, ptr ProfileEntry]
 {.deprecated: [TProfileEntry: ProfileEntry, TProfileData: ProfileData].}
 
 proc `==`(a, b: StackTrace): bool =
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index d543ec9a0..5611b8f0c 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1122,7 +1122,7 @@ proc parseCmdLine*(c: string): seq[string] {.
   while true:
     setLen(a, 0)
     # eat all delimiting whitespace
-    while c[i] == ' ' or c[i] == '\t' or c [i] == '\l' or c [i] == '\r' : inc(i)
+    while c[i] == ' ' or c[i] == '\t' or c[i] == '\l' or c[i] == '\r' : inc(i)
     when defined(windows):
       # parse a single argument according to the above rules:
       if c[i] == '\0': break
diff --git a/lib/pure/ospaths.nim b/lib/pure/ospaths.nim
index 65588529e..c4058ecce 100644
--- a/lib/pure/ospaths.nim
+++ b/lib/pure/ospaths.nim
@@ -556,12 +556,21 @@ when declared(getEnv) or defined(nimscript):
           yield substr(s, first, last-1)
           inc(last)
 
-  proc findExe*(exe: string): string {.
+  when not defined(windows) and declared(os):
+    proc checkSymlink(path: string): bool =
+      var rawInfo: Stat
+      if lstat(path, rawInfo) < 0'i32:
+        raiseOSError(osLastError())
+      S_ISLNK(rawInfo.st_mode)
+
+  proc findExe*(exe: string, followSymlinks: bool = true): string {.
     tags: [ReadDirEffect, ReadEnvEffect, ReadIOEffect].} =
     ## Searches for `exe` in the current working directory and then
     ## in directories listed in the ``PATH`` environment variable.
     ## Returns "" if the `exe` cannot be found. On DOS-like platforms, `exe`
     ## is added the `ExeExt <#ExeExt>`_ file extension if it has none.
+    ## If the system supports symlinks it also resolves them until it
+    ## meets the actual file. This behavior can be disabled if desired.
     result = addFileExt(exe, ExeExt)
     if existsFile(result): return
     var path = string(getEnv("PATH"))
@@ -572,7 +581,22 @@ when declared(getEnv) or defined(nimscript):
                result
       else:
         var x = expandTilde(candidate) / result
-      if existsFile(x): return x
+      if existsFile(x):
+        when not defined(windows) and declared(os):
+          while followSymlinks: # doubles as if here
+            if x.isAbsolute and x.checkSymlink:
+              var r = newString(256)
+              var len = readlink(x, r, 256)
+              if len < 0:
+                raiseOSError(osLastError())
+              if len > 256:
+                r = newString(len+1)
+                len = readlink(x, r, len)
+              setLen(r, len)
+              x = r
+            else:
+              break
+        return x
     result = ""
 
 when defined(nimscript) or (defined(nimdoc) and not declared(os)):
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 1ec4d0d8d..03b77572a 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -721,7 +721,7 @@ elif not defined(useNimRtl):
                  env: StringTableRef = nil,
                  options: set[ProcessOption] = {poStdErrToStdOut}): Process =
     var
-      pStdin, pStdout, pStderr: array [0..1, cint]
+      pStdin, pStdout, pStderr: array[0..1, cint]
     new(result)
     result.options = options
     result.exitCode = -3 # for ``waitForExit``
diff --git a/lib/pure/random.nim b/lib/pure/random.nim
index c73f403eb..08da771dc 100644
--- a/lib/pure/random.nim
+++ b/lib/pure/random.nim
@@ -7,11 +7,10 @@
 #    distribution, for details about the copyright.
 #
 
-##[Nim's standard random number generator. Based on
-
-| `http://xoroshiro.di.unimi.it/`_
-| `http://xoroshiro.di.unimi.it/xoroshiro128plus.c`_
-]##
+## Nim's standard random number generator. Based on the ``xoroshiro128+`` (xor/rotate/shift/rotate) library.
+## * More information: http://xoroshiro.di.unimi.it/
+## * C implementation: http://xoroshiro.di.unimi.it/xoroshiro128plus.c
+##
 
 include "system/inclrtl"
 {.push debugger:off.}
diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim
index c135f6a00..1f34ec07e 100644
--- a/lib/pure/terminal.nim
+++ b/lib/pure/terminal.nim
@@ -384,7 +384,7 @@ proc setForegroundColor*(f: File, fg: ForegroundColor, bright=false) =
     var old = getAttributes(h) and not 0x0007
     if bright:
       old = old or FOREGROUND_INTENSITY
-    const lookup: array [ForegroundColor, int] = [
+    const lookup: array[ForegroundColor, int] = [
       0,
       (FOREGROUND_RED),
       (FOREGROUND_GREEN),
@@ -406,7 +406,7 @@ proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
     var old = getAttributes(h) and not 0x0070
     if bright:
       old = old or BACKGROUND_INTENSITY
-    const lookup: array [BackgroundColor, int] = [
+    const lookup: array[BackgroundColor, int] = [
       0,
       (BACKGROUND_RED),
       (BACKGROUND_GREEN),
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index c0a121518..d6cb5c9da 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -477,7 +477,7 @@ when not defined(JS):
   # our own procs on top of that:
   proc tmToTimeInfo(tm: StructTM, local: bool): TimeInfo =
     const
-      weekDays: array [0..6, WeekDay] = [
+      weekDays: array[0..6, WeekDay] = [
         dSun, dMon, dTue, dWed, dThu, dFri, dSat]
     when defined(freebsd) or defined(netbsd) or defined(openbsd):
       TimeInfo(second: int(tm.second),
@@ -523,7 +523,7 @@ when not defined(JS):
 
   proc timeInfoToTM(t: TimeInfo): StructTM =
     const
-      weekDays: array [WeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8]
+      weekDays: array[WeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8]
     result.second = t.second
     result.minute = t.minute
     result.hour = t.hour
@@ -652,7 +652,7 @@ elif defined(JS):
     return newDate()
 
   const
-    weekDays: array [0..6, WeekDay] = [
+    weekDays: array[0..6, WeekDay] = [
       dSun, dMon, dTue, dWed, dThu, dFri, dSat]
 
   proc getLocalTime(t: Time): TimeInfo =
diff --git a/lib/system.nim b/lib/system.nim
index 6a4265e5a..00eae7337 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -669,6 +669,12 @@ proc newSeq*[T](len = 0.Natural): seq[T] =
   ##   #inputStrings[3] = "out of bounds"
   newSeq(result, len)
 
+proc newSeqOfCap*[T](cap: Natural): seq[T] {.
+  magic: "NewSeqOfCap", noSideEffect.} =
+  ## creates a new sequence of type ``seq[T]`` with length 0 and capacity
+  ## ``cap``.
+  discard
+
 proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.
   magic: "LengthOpenArray", noSideEffect.}
 proc len*(x: string): int {.magic: "LengthStr", noSideEffect.}
@@ -1523,7 +1529,7 @@ type # these work for most platforms:
     ## This is the same as the type ``unsigned long long`` in *C*.
 
   cstringArray* {.importc: "char**", nodecl.} = ptr
-    array [0..ArrayDummySize, cstring]
+    array[0..ArrayDummySize, cstring]
     ## This is binary compatible to the type ``char**`` in *C*. The array's
     ## high value is large enough to disable bounds checking in practice.
     ## Use `cstringArrayToSeq` to convert it into a ``seq[string]``.
diff --git a/lib/system/assign.nim b/lib/system/assign.nim
index 55d7572e2..231a20d86 100644
--- a/lib/system/assign.nim
+++ b/lib/system/assign.nim
@@ -211,14 +211,14 @@ proc genericReset(dest: pointer, mt: PNimType) =
     zeroMem(dest, mt.size) # set raw bits to zero
 
 proc selectBranch(discVal, L: int,
-                  a: ptr array [0..0x7fff, ptr TNimNode]): ptr TNimNode =
+                  a: ptr array[0..0x7fff, ptr TNimNode]): ptr TNimNode =
   result = a[L] # a[L] contains the ``else`` part (but may be nil)
   if discVal <% L:
     var x = a[discVal]
     if x != nil: result = x
 
 proc FieldDiscriminantCheck(oldDiscVal, newDiscVal: int,
-                            a: ptr array [0..0x7fff, ptr TNimNode],
+                            a: ptr array[0..0x7fff, ptr TNimNode],
                             L: int) {.compilerProc.} =
   var oldBranch = selectBranch(oldDiscVal, L, a)
   var newBranch = selectBranch(newDiscVal, L, a)
diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim
index 55f14e982..cc6919d36 100644
--- a/lib/system/debugger.nim
+++ b/lib/system/debugger.nim
@@ -159,7 +159,7 @@ type
 {.deprecated: [THash: Hash, TWatchpoint: Watchpoint].}
 
 var
-  watchpoints: array [0..99, Watchpoint]
+  watchpoints: array[0..99, Watchpoint]
   watchpointsLen: int
 
 proc `!&`(h: Hash, val: int): Hash {.inline.} =
diff --git a/lib/system/endb.nim b/lib/system/endb.nim
index 92aae8c71..d4d10a52c 100644
--- a/lib/system/endb.nim
+++ b/lib/system/endb.nim
@@ -475,7 +475,7 @@ proc dbgWriteStackTrace(f: PFrame) =
     it = f
     i = 0
     total = 0
-    tempFrames: array [0..127, PFrame]
+    tempFrames: array[0..127, PFrame]
   # setup long head:
   while it != nil and i <= high(tempFrames)-firstCalls:
     tempFrames[i] = it
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 526e27c83..b89729850 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -90,13 +90,13 @@ when defined(nativeStacktrace) and nativeStackTraceSupported:
 
   when not hasThreadSupport:
     var
-      tempAddresses: array [0..127, pointer] # should not be alloc'd on stack
+      tempAddresses: array[0..127, pointer] # should not be alloc'd on stack
       tempDlInfo: TDl_info
 
   proc auxWriteStackTraceWithBacktrace(s: var string) =
     when hasThreadSupport:
       var
-        tempAddresses: array [0..127, pointer] # but better than a threadvar
+        tempAddresses: array[0..127, pointer] # but better than a threadvar
         tempDlInfo: TDl_info
     # This is allowed to be expensive since it only happens during crashes
     # (but this way you don't need manual stack tracing)
@@ -124,12 +124,12 @@ when defined(nativeStacktrace) and nativeStackTraceSupported:
 
 when not hasThreadSupport:
   var
-    tempFrames: array [0..127, PFrame] # should not be alloc'd on stack
+    tempFrames: array[0..127, PFrame] # should not be alloc'd on stack
 
 proc auxWriteStackTrace(f: PFrame, s: var string) =
   when hasThreadSupport:
     var
-      tempFrames: array [0..127, PFrame] # but better than a threadvar
+      tempFrames: array[0..127, PFrame] # but better than a threadvar
   const
     firstCalls = 32
   var
@@ -250,7 +250,7 @@ proc raiseExceptionAux(e: ref Exception) =
             inc L, slen
         template add(buf, s: expr) =
           xadd(buf, s, s.len)
-        var buf: array [0..2000, char]
+        var buf: array[0..2000, char]
         var L = 0
         add(buf, "Error: unhandled exception: ")
         if not isNil(e.msg): add(buf, e.msg)
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index 3e71b4fe0..a36dbf02b 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -452,10 +452,13 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
   gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
   # now it is buffered in the ZCT
   res.typ = typ
-  when leakDetector and not hasThreadSupport:
-    if framePtr != nil and framePtr.prev != nil:
-      res.filename = framePtr.prev.filename
-      res.line = framePtr.prev.line
+  when leakDetector:
+    res.filename = nil
+    res.line = 0
+    when not hasThreadSupport:
+      if framePtr != nil and framePtr.prev != nil:
+        res.filename = framePtr.prev.filename
+        res.line = framePtr.prev.line
   # refcount is zero, color is black, but mark it to be in the ZCT
   res.refcount = ZctFlag
   sysAssert(isAllocatedPtr(gch.region, res), "newObj: 3")
@@ -503,10 +506,13 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
   sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
   # now it is buffered in the ZCT
   res.typ = typ
-  when leakDetector and not hasThreadSupport:
-    if framePtr != nil and framePtr.prev != nil:
-      res.filename = framePtr.prev.filename
-      res.line = framePtr.prev.line
+  when leakDetector:
+    res.filename = nil
+    res.line = 0
+    when not hasThreadSupport:
+      if framePtr != nil and framePtr.prev != nil:
+        res.filename = framePtr.prev.filename
+        res.line = framePtr.prev.line
   res.refcount = rcIncrement # refcount is 1
   sysAssert(isAllocatedPtr(gch.region, res), "newObj: 3")
   when logGC: writeCell("new cell", res)
diff --git a/lib/system/gc_common.nim b/lib/system/gc_common.nim
index 4807bb6f8..cdca36fb7 100644
--- a/lib/system/gc_common.nim
+++ b/lib/system/gc_common.nim
@@ -239,7 +239,7 @@ else:
       # We use a jmp_buf buffer that is in the C stack.
       # Used to traverse the stack and registers assuming
       # that 'setjmp' will save registers in the C stack.
-      type PStackSlice = ptr array [0..7, pointer]
+      type PStackSlice = ptr array[0..7, pointer]
       var registers {.noinit.}: Registers
       getRegisters(registers)
       for i in registers.low .. registers.high:
@@ -277,7 +277,7 @@ else:
       # We use a jmp_buf buffer that is in the C stack.
       # Used to traverse the stack and registers assuming
       # that 'setjmp' will save registers in the C stack.
-      type PStackSlice = ptr array [0..7, pointer]
+      type PStackSlice = ptr array[0..7, pointer]
       var registers {.noinit.}: C_JmpBuf
       if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
         var max = cast[ByteAddress](gch.stackBottom)
diff --git a/lib/system/hti.nim b/lib/system/hti.nim
index bfb13059e..984f888cb 100644
--- a/lib/system/hti.nim
+++ b/lib/system/hti.nim
@@ -71,7 +71,7 @@ type
     typ: ptr TNimType
     name: cstring
     len: int
-    sons: ptr array [0..0x7fff, ptr TNimNode]
+    sons: ptr array[0..0x7fff, ptr TNimNode]
 
   TNimTypeFlag = enum
     ntfNoRefs = 0,     # type contains no tyRef, tySequence, tyString
diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim
index ce67373bc..9c8a18bfe 100644
--- a/lib/system/jssys.nim
+++ b/lib/system/jssys.nim
@@ -65,7 +65,7 @@ proc auxWriteStackTrace(f: PCallFrame): string =
     it = f
     i = 0
     total = 0
-    tempFrames: array [0..63, TempFrame]
+    tempFrames: array[0..63, TempFrame]
   while it != nil and i <= high(tempFrames):
     tempFrames[i].procname = it.procname
     tempFrames[i].line = it.line
diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim
index 7ef26a7c1..186349152 100644
--- a/lib/system/mmdisp.nim
+++ b/lib/system/mmdisp.nim
@@ -354,6 +354,12 @@ elif defined(gogc):
     cast[PGenericSeq](result).reserved = len
     cast[PGenericSeq](result).elemSize = typ.base.size
 
+  proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} =
+    result = newObj(typ, cap * typ.base.size + GenericSeqSize)
+    cast[PGenericSeq](result).len = 0
+    cast[PGenericSeq](result).reserved = cap
+    cast[PGenericSeq](result).elemSize = typ.base.size
+
   proc growObj(old: pointer, newsize: int): pointer =
     # the Go GC doesn't have a realloc
     var
@@ -447,6 +453,7 @@ elif defined(nogc) and defined(useMalloc):
     result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
     cast[PGenericSeq](result).len = len
     cast[PGenericSeq](result).reserved = len
+
   proc newObjNoInit(typ: PNimType, size: int): pointer =
     result = alloc(size)
 
@@ -506,6 +513,7 @@ elif defined(nogc):
     result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
     cast[PGenericSeq](result).len = len
     cast[PGenericSeq](result).reserved = len
+
   proc growObj(old: pointer, newsize: int): pointer =
     result = realloc(old, newsize)
 
@@ -545,4 +553,10 @@ else:
   else:
     include "system/gc"
 
+when not declared(nimNewSeqOfCap):
+  proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} =
+    result = newObj(typ, addInt(mulInt(cap, typ.base.size), GenericSeqSize))
+    cast[PGenericSeq](result).len = 0
+    cast[PGenericSeq](result).reserved = cap
+
 {.pop.}
diff --git a/lib/system/nimscript.nim b/lib/system/nimscript.nim
index d587d772f..cc96bcba8 100644
--- a/lib/system/nimscript.nim
+++ b/lib/system/nimscript.nim
@@ -39,6 +39,9 @@ proc getCurrentDir(): string = builtin
 proc rawExec(cmd: string): int {.tags: [ExecIOEffect], raises: [OSError].} =
   builtin
 
+proc warningImpl(arg, orig: string) = discard
+proc hintImpl(arg, orig: string) = discard
+
 proc paramStr*(i: int): string =
   ## Retrieves the ``i``'th command line parameter.
   builtin
@@ -52,6 +55,31 @@ proc switch*(key: string, val="") =
   ## example ``switch("checks", "on")``.
   builtin
 
+proc warning*(name: string; val: bool) =
+  ## Disables or enables a specific warning.
+  let v = if val: "on" else: "off"
+  warningImpl(name & "]:" & v, "warning[" & name & "]:" & v)
+
+proc hint*(name: string; val: bool) =
+  ## Disables or enables a specific hint.
+  let v = if val: "on" else: "off"
+  hintImpl(name & "]:" & v, "hint[" & name & "]:" & v)
+
+proc patchFile*(package, filename, replacement: string) =
+  ## Overrides the location of a given file belonging to the
+  ## passed package.
+  ## If the ``replacement`` is not an absolute path, the path
+  ## is interpreted to be local to the Nimscript file that contains
+  ## the call to ``patchFile``, Nim's ``--path`` is not used at all
+  ## to resolve the filename!
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nim
+  ##
+  ##   patchFile("stdlib", "asyncdispatch", "patches/replacement")
+  discard
+
 proc getCommand*(): string =
   ## Gets the Nim command that the compiler has been invoked with, for example
   ## "c", "js", "build", "help".
diff --git a/lib/system/profiler.nim b/lib/system/profiler.nim
index ae8ff4e19..c00a7d53a 100644
--- a/lib/system/profiler.nim
+++ b/lib/system/profiler.nim
@@ -19,7 +19,7 @@ const
   MaxTraceLen = 20 # tracking the last 20 calls is enough
 
 type
-  StackTrace* = array [0..MaxTraceLen-1, cstring]
+  StackTrace* = array[0..MaxTraceLen-1, cstring]
   ProfilerHook* = proc (st: StackTrace) {.nimcall.}
 {.deprecated: [TStackTrace: StackTrace, TProfilerHook: ProfilerHook].}
 
diff --git a/lib/system/repr.nim b/lib/system/repr.nim
index 1b80cf2f8..cf7d6d7a9 100644
--- a/lib/system/repr.nim
+++ b/lib/system/repr.nim
@@ -16,7 +16,7 @@ proc reprInt(x: int64): string {.compilerproc.} = return $x
 proc reprFloat(x: float): string {.compilerproc.} = return $x
 
 proc reprPointer(x: pointer): string {.compilerproc.} =
-  var buf: array [0..59, char]
+  var buf: array[0..59, char]
   discard c_sprintf(buf, "%p", x)
   return $buf
 
@@ -24,7 +24,7 @@ proc `$`(x: uint64): string =
   if x == 0:
     result = "0"
   else:
-    var buf: array [60, char]
+    var buf: array[60, char]
     var i = 0
     var n = x
     while n != 0:
diff --git a/lib/system/sets.nim b/lib/system/sets.nim
index 66877de30..53d222468 100644
--- a/lib/system/sets.nim
+++ b/lib/system/sets.nim
@@ -10,7 +10,7 @@
 # set handling
 
 type
-  NimSet = array [0..4*2048-1, uint8]
+  NimSet = array[0..4*2048-1, uint8]
 {.deprecated: [TNimSet: NimSet].}
 
 proc countBits32(n: int32): int {.compilerproc.} =
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 6622a4f64..3e9657ce0 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -271,7 +271,7 @@ else:
     importc: "freopen", nodecl.}
 
 const
-  FormatOpen: array [FileMode, string] = ["rb", "wb", "w+b", "r+b", "ab"]
+  FormatOpen: array[FileMode, string] = ["rb", "wb", "w+b", "r+b", "ab"]
     #"rt", "wt", "w+t", "r+t", "at"
     # we always use binary here as for Nim the OS line ending
     # should not be translated.
diff --git a/lib/system/threads.nim b/lib/system/threads.nim
index 8505202b5..cc9da0a92 100644
--- a/lib/system/threads.nim
+++ b/lib/system/threads.nim
@@ -24,7 +24,7 @@
 ##  import locks
 ##
 ##  var
-##    thr: array [0..4, Thread[tuple[a,b: int]]]
+##    thr: array[0..4, Thread[tuple[a,b: int]]]
 ##    L: Lock
 ##
 ##  proc threadFunc(interval: tuple[a,b: int]) {.thread.} =
@@ -198,7 +198,7 @@ when emulatedThreadVars:
 # allocations are needed. Currently less than 7K are used on a 64bit machine.
 # We use ``float`` for proper alignment:
 type
-  ThreadLocalStorage = array [0..1_000, float]
+  ThreadLocalStorage = array[0..1_000, float]
 
   PGcThread = ptr GcThread
   GcThread {.pure, inheritable.} = object
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index c9b4b610c..b766ead9c 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -750,7 +750,7 @@ type
     D1*: int32
     D2*: int16
     D3*: int16
-    D4*: array [0..7, int8]
+    D4*: array[0..7, int8]
 {.deprecated: [TOVERLAPPED: OVERLAPPED, TGUID: GUID].}
 
 const