summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml10
-rw-r--r--compiler/ccgexprs.nim19
-rw-r--r--compiler/ccgtypes.nim2
-rw-r--r--compiler/condsyms.nim1
-rw-r--r--compiler/destroyer.nim8
-rw-r--r--compiler/docgen.nim2
-rw-r--r--compiler/passes.nim25
-rw-r--r--compiler/pragmas.nim4
-rw-r--r--compiler/sem.nim12
-rw-r--r--compiler/semasgn.nim3
-rw-r--r--compiler/suggest.nim31
-rw-r--r--compiler/transf.nim8
-rw-r--r--compiler/vmgen.nim6
-rw-r--r--doc/nims.rst53
-rw-r--r--lib/posix/posix.nim17
-rw-r--r--lib/pure/concurrency/cpuinfo.nim6
-rw-r--r--lib/pure/math.nim4
-rw-r--r--lib/pure/os.nim26
-rw-r--r--lib/system.nim16
-rw-r--r--tests/destructor/t6434.nim2
-rw-r--r--tests/destructor/t7346.nim (renamed from tests/seq/t7346.nim)0
-rw-r--r--tests/destructor/texplicit_move.nim19
-rw-r--r--tests/destructor/tmove_objconstr.nim2
-rw-r--r--tests/errmsgs/t5167_5.nim10
-rw-r--r--tests/pragmas/tnoreturn.nim4
-rw-r--r--tests/pragmas/treorder.nim6
-rw-r--r--tests/trmacros/tor.nim4
-rw-r--r--tests/types/t6969.nim6
-rw-r--r--tests/vm/t9043.nim10
29 files changed, 225 insertions, 91 deletions
diff --git a/.travis.yml b/.travis.yml
index b3b4834b3..b4fa886b7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,9 +5,9 @@ os:
   - osx
 dist: trusty
 
-matrix:
-  allow_failures:
-    - os: osx
+#matrix:
+#  allow_failures:
+#    - os: osx
 
 addons:
   apt:
@@ -43,9 +43,7 @@ script:
   #- nimble install jester@#head -y
   #- nimble install niminst
   - nim c --taintMode:on -d:nimCoroutines tests/testament/tester
-  # Do not run the tests on OSX as OSX does 'testinstall' which *also* runs all the tests!
-  - if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then tests/testament/tester --pedantic all -d:nimCoroutines; fi
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./koch testinstall; fi
+  - tests/testament/tester --pedantic all -d:nimCoroutines
   - nim c -o:bin/nimpretty nimpretty/nimpretty.nim
   - nim c -r nimpretty/tester.nim
   - ./koch docs
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index fbedf6cc6..a1365ce07 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1864,6 +1864,23 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   else:
     binaryArith(p, e, d, m)
 
+proc skipAddr(n: PNode): PNode =
+  result = if n.kind in {nkAddr, nkHiddenAddr}: n[0] else: n
+
+proc genWasMoved(p: BProc; n: PNode) =
+  var a: TLoc
+  initLocExpr(p, n[1].skipAddr, a)
+  resetLoc(p, a)
+  #linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
+  #  addrLoc(p.config, a), getTypeDesc(p.module, a.t))
+
+proc genMove(p: BProc; n: PNode; d: var TLoc) =
+  if d.k == locNone: getTemp(p, n.typ, d)
+  var a: TLoc
+  initLocExpr(p, n[1].skipAddr, a)
+  genAssignment(p, d, a, {})
+  resetLoc(p, a)
+
 proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   case op
   of mOr, mAnd: genAndOr(p, e, d, op)
@@ -1991,6 +2008,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     initLocExpr(p, e.sons[2], b)
     genDeepCopy(p, a, b)
   of mDotDot, mEqCString: genCall(p, e, d)
+  of mWasMoved: genWasMoved(p, e)
+  of mMove: genMove(p, e, d)
   else:
     when defined(debugMagics):
       echo p.prc.name.s, " ", p.prc.id, " ", p.prc.flags, " ", p.prc.ast[genericParamsPos].kind
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 52a4a72f2..3c7a0d26e 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -1206,7 +1206,7 @@ proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope =
       let x = fakeClosureType(m, t.owner)
       genTupleInfo(m, x, x, result, info)
   of tySequence:
-    if tfHasAsgn notin t.flags:
+    if m.config.selectedGC != gcDestructors:
       genTypeInfoAux(m, t, t, result, info)
       if m.config.selectedGC >= gcMarkAndSweep:
         let markerProc = genTraverseProc(m, origType, sig)
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index a22b613f0..62c55de3d 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -81,6 +81,7 @@ proc initDefines*(symbols: StringTableRef) =
   defineSymbol("nimAshr")
   defineSymbol("nimNoNilSeqs")
   defineSymbol("nimNoNilSeqs2")
+  defineSymbol("nimHasUserErrors")
 
   defineSymbol("nimHasNilSeqs")
   for f in low(Feature)..high(Feature):
diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim
index bd735560a..ff5494ad8 100644
--- a/compiler/destroyer.nim
+++ b/compiler/destroyer.nim
@@ -291,21 +291,21 @@ proc genMagicCall(n: PNode; c: var Con; magicname: string; m: TMagic): PNode =
 
 proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
   if ri.kind in constrExprs:
-    result = genSink(c, ri.typ, dest)
+    result = genSink(c, dest.typ, dest)
     # watch out and no not transform 'ri' twice if it's a call:
     let ri2 = copyNode(ri)
     recurse(ri, ri2)
     result.add ri2
   elif ri.kind == nkSym and isHarmlessVar(ri.sym, c):
     # Rule 3: `=sink`(x, z); wasMoved(z)
-    var snk = genSink(c, ri.typ, dest)
+    var snk = genSink(c, dest.typ, dest)
     snk.add p(ri, c)
     result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved))
   elif ri.kind == nkSym and isSinkParam(ri.sym):
-    result = genSink(c, ri.typ, dest)
+    result = genSink(c, dest.typ, dest)
     result.add destructiveMoveSink(ri, c)
   else:
-    result = genCopy(c, ri.typ, dest)
+    result = genCopy(c, dest.typ, dest)
     result.add p(ri, c)
 
 proc passCopyToSink(n: PNode; c: var Con): PNode =
diff --git a/compiler/docgen.nim b/compiler/docgen.nim
index 83dd5de2a..4e36b72e5 100644
--- a/compiler/docgen.nim
+++ b/compiler/docgen.nim
@@ -304,7 +304,7 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe
           d.target == outHtml:
         let external = externalDep(d, s.owner)
         result.addf "<a href=\"$1#$2\"><span class=\"Identifier\">$3</span></a>",
-          [rope changeFileExt(external, "html").string, rope literal,
+          [rope changeFileExt(external, "html"), rope literal,
            rope(esc(d.target, literal))]
       else:
         dispA(d.conf, result, "<span class=\"Identifier\">$1</span>",
diff --git a/compiler/passes.nim b/compiler/passes.nim
index 365731669..718b42c2a 100644
--- a/compiler/passes.nim
+++ b/compiler/passes.nim
@@ -125,6 +125,11 @@ proc processImplicits(conf: ConfigRef; implicits: seq[string], nodeKind: TNodeKi
       importStmt.addSon str
       if not processTopLevelStmt(importStmt, a): break
 
+const
+  imperativeCode = {low(TNodeKind)..high(TNodeKind)} - {nkTemplateDef, nkProcDef, nkMethodDef,
+    nkMacroDef, nkConverterDef, nkIteratorDef, nkFuncDef, nkPragma,
+    nkExportStmt, nkExportExceptStmt, nkFromStmt, nkImportStmt, nkImportExceptStmt}
+
 proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {.discardable.} =
   if graph.stopCompile(): return true
   var
@@ -191,7 +196,25 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
             sl = reorder(graph, sl, module)
           discard processTopLevelStmt(sl, a)
           break
-        elif not processTopLevelStmt(n, a): break
+        elif n.kind in imperativeCode:
+          # read everything until the next proc declaration etc.
+          var sl = newNodeI(nkStmtList, n.info)
+          sl.add n
+          var rest: PNode = nil
+          while true:
+            var n = parseTopLevelStmt(p)
+            if n.kind == nkEmpty or n.kind notin imperativeCode:
+              rest = n
+              break
+            sl.add n
+          #echo "-----\n", sl
+          if not processTopLevelStmt(sl, a): break
+          if rest != nil:
+            #echo "-----\n", rest
+            if not processTopLevelStmt(rest, a): break
+        else:
+          #echo "----- single\n", n
+          if not processTopLevelStmt(n, a): break
       closeParsers(p)
       if s.kind != llsStdIn: break
     closePasses(graph, a)
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 36c79bc9e..9a624fcce 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -954,12 +954,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
         recordPragma(c, it, "warning", s)
         message(c.config, it.info, warnUser, s)
       of wError:
-        if sym != nil and sym.isRoutine:
+        if sym != nil and (sym.isRoutine or sym.kind == skType):
           # This is subtle but correct: the error *statement* is only
           # allowed for top level statements. Seems to be easier than
           # distinguishing properly between
           # ``proc p() {.error}`` and ``proc p() = {.error: "msg".}``
-          noVal(c, it)
+          if it.kind in nkPragmaCallKinds: discard getStrLitNode(c, it)
           incl(sym.flags, sfError)
         else:
           let s = expectStrLit(c, it)
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 5e5205c20..dbc174d50 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -542,12 +542,20 @@ proc isImportSystemStmt(g: ModuleGraph; n: PNode): bool =
         return true
   else: discard
 
+proc isEmptyTree(n: PNode): bool =
+  case n.kind
+  of nkStmtList:
+    for it in n:
+      if not isEmptyTree(it): return false
+    result = true
+  of nkEmpty, nkCommentStmt: result = true
+  else: result = false
+
 proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
   if n.kind == nkDefer:
     localError(c.config, n.info, "defer statement not supported at top level")
   if c.topStmts == 0 and not isImportSystemStmt(c.graph, n):
-    if sfSystemModule notin c.module.flags and
-        n.kind notin {nkEmpty, nkCommentStmt}:
+    if sfSystemModule notin c.module.flags and not isEmptyTree(n):
       c.importTable.addSym c.graph.systemModule # import the "System" identifier
       importAllSymbols(c, c.graph.systemModule)
       inc c.topStmts
diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim
index 8b2e20efc..f781972a5 100644
--- a/compiler/semasgn.nim
+++ b/compiler/semasgn.nim
@@ -216,7 +216,8 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
     if c.c.config.selectedGC == gcDestructors:
       discard considerOverloadedOp(c, t, body, x, y)
     elif tfHasAsgn in t.flags:
-      body.add newSeqCall(c.c, x, y)
+      if c.kind != attachedDestructor:
+        body.add newSeqCall(c.c, x, y)
       let i = declareCounter(c, body, firstOrd(c.c.config, t))
       let whileLoop = genWhileLoop(c, i, x)
       let elemType = t.lastSon
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index b6b8d713c..b264415d8 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -33,7 +33,7 @@
 # included from sigmatch.nim
 
 import algorithm, prefixmatches, lineinfos, pathutils
-from wordrecg import wDeprecated
+from wordrecg import wDeprecated, wError
 
 when defined(nimsuggest):
   import passes, tables # importer
@@ -453,33 +453,42 @@ proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym;
         isDecl:
       suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideOutline, info, 100, PrefixMatch.None, false, 0))
 
-proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) =
-  var pragmaNode: PNode
-
+proc extractPragma(s: PSym): PNode =
   if s.kind in routineKinds:
-    pragmaNode = s.ast[pragmasPos]
+    result = s.ast[pragmasPos]
   elif s.kind in {skType}:
     # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma]
-    pragmaNode = s.ast[0][1]
-
-  doAssert pragmaNode == nil or pragmaNode.kind == nkPragma
+    result = s.ast[0][1]
+  doAssert result == nil or result.kind == nkPragma
 
+proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) =
+  let pragmaNode = extractPragma(s)
   if pragmaNode != nil:
     for it in pragmaNode:
       if whichPragma(it) == wDeprecated and it.safeLen == 2 and
-        it[1].kind in {nkStrLit..nkTripleStrLit}:
+          it[1].kind in {nkStrLit..nkTripleStrLit}:
         message(conf, info, warnDeprecated, it[1].strVal & "; " & s.name.s)
         return
-
   message(conf, info, warnDeprecated, s.name.s)
 
+proc userError(conf: ConfigRef; info: TLineInfo; s: PSym) =
+  let pragmaNode = extractPragma(s)
+
+  if pragmaNode != nil:
+    for it in pragmaNode:
+      if whichPragma(it) == wError and it.safeLen == 2 and
+          it[1].kind in {nkStrLit..nkTripleStrLit}:
+        localError(conf, info, it[1].strVal & "; usage of '$1' is a user-defined error" % s.name.s)
+        return
+  localError(conf, info, "usage of '$1' is a user-defined error" % s.name.s)
+
 proc markUsed(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) =
   incl(s.flags, sfUsed)
   if s.kind == skEnumField and s.owner != nil:
     incl(s.owner.flags, sfUsed)
   if {sfDeprecated, sfError} * s.flags != {}:
     if sfDeprecated in s.flags: warnAboutDeprecated(conf, info, s)
-    if sfError in s.flags: localError(conf, info,  "usage of '$1' is a user-defined error" % s.name.s)
+    if sfError in s.flags: userError(conf, info, s)
   when defined(nimsuggest):
     suggestSym(conf, info, s, usageSym, false)
 
diff --git a/compiler/transf.nim b/compiler/transf.nim
index b31be71a3..83e66a069 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -1054,8 +1054,8 @@ proc transformStmt*(g: ModuleGraph; module: PSym, n: PNode): PNode =
     when useEffectSystem: trackTopLevelStmt(g, module, result)
     #if n.info ?? "temp.nim":
     #  echo renderTree(result, {renderIds})
-    #if c.needsDestroyPass:
-    #  result = injectDestructorCalls(g, module, result)
+    if c.needsDestroyPass:
+      result = injectDestructorCalls(g, module, result)
     incl(result.flags, nfTransf)
 
 proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode =
@@ -1067,6 +1067,6 @@ proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode =
     liftDefer(c, result)
     # expressions are not to be injected with destructor calls as that
     # the list of top level statements needs to be collected before.
-    #if c.needsDestroyPass:
-    #  result = injectDestructorCalls(g, module, result)
+    if c.needsDestroyPass:
+      result = injectDestructorCalls(g, module, result)
     incl(result.flags, nfTransf)
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index b6b5bf4f2..e612d7a2a 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1529,7 +1529,7 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
 
 template needsRegLoad(): untyped =
   {gfNode, gfNodeAddr} * flags == {} and
-    fitsRegister(n.typ.skipTypes({tyVar, tyLent}))
+    fitsRegister(n.typ.skipTypes({tyVar, tyLent, tyStatic}))
 
 proc genArrAccess2(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
                    flags: TGenFlags) =
@@ -1590,7 +1590,7 @@ proc getNullValueAux(obj: PNode, result: PNode; conf: ConfigRef) =
   else: globalError(conf, result.info, "cannot create null element for: " & $obj)
 
 proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
-  var t = skipTypes(typ, abstractRange-{tyTypeDesc})
+  var t = skipTypes(typ, abstractRange+{tyStatic}-{tyTypeDesc})
   case t.kind
   of tyBool, tyEnum, tyChar, tyInt..tyInt64:
     result = newNodeIT(nkIntLit, info, t)
@@ -1602,7 +1602,7 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
     result = newNodeIT(nkStrLit, info, t)
     result.strVal = ""
   of tyVar, tyLent, tyPointer, tyPtr, tyExpr,
-     tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil:
+     tyStmt, tyTypeDesc, tyRef, tyNil:
     result = newNodeIT(nkNilLit, info, t)
   of tyProc:
     if t.callConv != ccClosure:
diff --git a/doc/nims.rst b/doc/nims.rst
index d4ef0055f..a0756eb13 100644
--- a/doc/nims.rst
+++ b/doc/nims.rst
@@ -4,39 +4,56 @@
 
 Strictly speaking, ``NimScript`` is the subset of Nim that can be evaluated
 by Nim's builtin virtual machine (VM). This VM is used for Nim's compiletime
-function evaluation features, but also replaces Nim's existing configuration
-system.
+function evaluation features.
 
-So instead of a ``myproject.nim.cfg`` configuration file, you can use
-a ``myproject.nims`` file that simply contains Nim code controlling the
-compilation process. For a directory wide configuration, use ``config.nims``
-instead of ``nim.cfg``.
+You can use a ``<myproject>.nims`` file that simply contains Nim code
+controlling the compilation process. For a directory wide
+configuration, use ``config.nims`` instead of ``<myproject>.nims``.
 
-The VM cannot deal with ``importc``, the FFI is not available, so there are not
-many stdlib modules that you can use with Nim's VM. However, at least the
-following modules are available:
+The VM cannot deal with ``importc`` because the FFI is not
+available. So the stdlib modules using ``importc`` cannot be used with
+Nim's VM. However, at least the following modules are available:
 
-* `strutils <strutils.html>`_
+* `macros <macros.html>`_
 * `ospaths <ospaths.html>`_
+* `strutils <strutils.html>`_
 * `math <math.html>`_
 * `distros <distros.html>`_
 
-The `system <system.html>`_ module in NimScript mode additionally supports
-these operations: `nimscript <nimscript.html>`_.
+In addition to the standard Nim syntax (`system <system.html>`_
+module), NimScripts support the procs and templates defined in the
+`nimscript <nimscript.html>`_ module too.
 
 
 NimScript as a configuration file
 =================================
 
-What is ``x.y.key = "value"`` in the configuration file
-becomes ``switch("x.y.key", "value")``. ``--option`` is ``switch("option")``.
-The ``system`` module also exports 2 ``--`` templates for convenience:
+A command-line switch ``--FOO`` is written as ``switch("FOO")`` in
+NimScript. Similarly, command-line ``--FOO:VAL`` translates to
+``switch("FOO", "VAL")``.
+
+Here are few examples of using the ``switch`` proc:
 
 .. code-block:: nim
-  --forceBuild
-  # is the same as:
+  # command-line: --opt:size
+  switch("opt", "size")
+  # command-line: --define:foo or -d:foo
+  switch("define", "foo")
+  # command-line: --forceBuild
   switch("forceBuild")
 
+*Note that specifically the ``-d:release`` define cannot be set using
+``switch`` in NimScripts.*
+
+NimScripts also support ``--`` templates for convenience, which look
+like command-line switches written as-is in the NimScript file. So the
+above example can be rewritten as:
+
+.. code-block:: nim
+  --opt:size
+  --define:foo
+  --forceBuild
+
 
 NimScript as a build tool
 =========================
@@ -91,7 +108,7 @@ Standalone NimScript
 
 NimScript can also be used directly as a portable replacement for Bash and
 Batch files. Use ``nim e myscript.nims`` to run ``myscript.nims``. For example,
-installation of Nimble is done with this simple script:
+installation of Nimble could be accomplished with this simple script:
 
 .. code-block:: nim
 
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index c230e6598..fa589e905 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -985,14 +985,21 @@ proc utimes*(path: cstring, times: ptr array[2, Timeval]): int {.
 proc handle_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.importc: "signal", header: "<signal.h>".}
 
 template onSignal*(signals: varargs[cint], body: untyped) =
-  ## Setup code to be executed when Unix signals are received. Example:
-  ## from posix import SIGINT, SIGTERM
-  ## onSignal(SIGINT, SIGTERM):
-  ##   echo "bye"
+  ## Setup code to be executed when Unix signals are received. The
+  ## currently handled signal is injected as ``sig`` into the calling
+  ## scope.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   from posix import SIGINT, SIGTERM
+  ##   onSignal(SIGINT, SIGTERM):
+  ##     echo "bye from signal ", sig
 
   for s in signals:
     handle_signal(s,
-      proc (sig: cint) {.noconv.} =
+      proc (signal: cint) {.noconv.} =
+        let sig {.inject.} = signal
         body
     )
 
diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim
index 541265da9..4f681f980 100644
--- a/lib/pure/concurrency/cpuinfo.nim
+++ b/lib/pure/concurrency/cpuinfo.nim
@@ -44,12 +44,12 @@ when defined(genode):
     importcpp: "@->cpu().affinity_space().total()".}
 
 when defined(haiku):
-  {.emit: "#include <OS.h>".}
   type
-    SystemInfo {.importc: "system_info", bycopy.} = object
+    SystemInfo {.importc: "system_info", header: "<OS.h>".} = object
       cpuCount {.importc: "cpu_count".}: uint32
 
-  proc getSystemInfo(info: ptr SystemInfo): int32 {.importc: "get_system_info".}
+  proc getSystemInfo(info: ptr SystemInfo): int32 {.importc: "get_system_info",
+                                                    header: "<OS.h>".}
 
 proc countProcessors*(): int {.rtl, extern: "ncpi$1".} =
   ## returns the numer of the processors/cores the machine has.
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index bc804eb86..909aa11b7 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -383,8 +383,8 @@ when not defined(JS): # C
       ## .. code-block:: nim
       ##  echo trunc(PI) # 3.0
 
-  proc fmod*(x, y: float32): float32 {.deprecated, importc: "fmodf", header: "<math.h>".}
-  proc fmod*(x, y: float64): float64 {.deprecated, importc: "fmod", header: "<math.h>".}
+  proc fmod*(x, y: float32): float32 {.deprecated: "use mod instead", importc: "fmodf", header: "<math.h>".}
+  proc fmod*(x, y: float64): float64 {.deprecated: "use mod instead", importc: "fmod", header: "<math.h>".}
     ## Computes the remainder of `x` divided by `y`
     ##
     ## .. code-block:: nim
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 2b3cf5142..5c7d369c9 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -802,20 +802,16 @@ type
     pcDir,                ## path refers to a directory
     pcLinkToDir           ## path refers to a symbolic link to a directory
 
-
 when defined(posix):
   proc getSymlinkFileKind(path: string): PathComponent =
     # Helper function.
     var s: Stat
     assert(path != "")
-    if stat(path, s) < 0'i32:
-      raiseOSError(osLastError())
-    if S_ISDIR(s.st_mode):
+    if stat(path, s) == 0'i32 and S_ISDIR(s.st_mode):
       result = pcLinkToDir
     else:
       result = pcLinkToFile
 
-
 proc staticWalkDir(dir: string; relative: bool): seq[
                   tuple[kind: PathComponent, path: string]] =
   discard
@@ -1480,6 +1476,24 @@ when defined(macosx):
   proc getExecPath2(c: cstring, size: var cuint32): bool {.
     importc: "_NSGetExecutablePath", header: "<mach-o/dyld.h>".}
 
+when defined(haiku):
+  const
+    PATH_MAX = 1024
+    B_FIND_PATH_IMAGE_PATH = 1000
+
+  proc find_path(codePointer: pointer, baseDirectory: cint, subPath: cstring,
+                 pathBuffer: cstring, bufferSize: csize): int32
+                {.importc, header: "<FindDirectory.h>".}
+
+  proc getApplHaiku(): string =
+    result = newString(PATH_MAX)
+
+    if find_path(nil, B_FIND_PATH_IMAGE_PATH, nil, result, PATH_MAX) == 0:
+      let realLen = len(cstring(result))
+      setLen(result, realLen)
+    else:
+      result = ""
+
 proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} =
   ## Returns the filename of the application's executable.
   ##
@@ -1534,6 +1548,8 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} =
       raiseOSError(OSErrorCode(-1), "POSIX command line not supported")
     elif defined(freebsd) or defined(dragonfly):
       result = getApplFreebsd()
+    elif defined(haiku):
+      result = getApplHaiku()
     # little heuristic that may work on other POSIX-like systems:
     if result.len == 0:
       result = getApplHeuristic()
diff --git a/lib/system.nim b/lib/system.nim
index 49e6a396d..f62842db2 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1932,10 +1932,10 @@ const
   NimMajor* {.intdefine.}: int = 0
     ## is the major number of Nim's version.
 
-  NimMinor* {.intdefine.}: int = 18
+  NimMinor* {.intdefine.}: int = 19
     ## is the minor number of Nim's version.
 
-  NimPatch* {.intdefine.}: int = 1
+  NimPatch* {.intdefine.}: int = 0
     ## is the patch number of Nim's version.
 
   NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch
@@ -4112,8 +4112,16 @@ proc `==`*(x, y: cstring): bool {.magic: "EqCString", noSideEffect,
 
 when defined(nimNoNilSeqs2):
   when not compileOption("nilseqs"):
-    proc `==`*(x: string; y: type(nil)): bool {.error.} = discard
-    proc `==`*(x: type(nil); y: string): bool {.error.} = discard
+    when defined(nimHasUserErrors):
+      proc `==`*(x: string; y: type(nil)): bool {.
+          error: "'nil' is now invalid for 'string'; compile with --nilseqs:on for a migration period".} =
+        discard
+      proc `==`*(x: type(nil); y: string): bool {.
+          error: "'nil' is now invalid for 'string'; compile with --nilseqs:on for a migration period".} =
+        discard
+    else:
+      proc `==`*(x: string; y: type(nil)): bool {.error.} = discard
+      proc `==`*(x: type(nil); y: string): bool {.error.} = discard
 
 template closureScope*(body: untyped): untyped =
   ## Useful when creating a closure in a loop to capture local loop variables by
diff --git a/tests/destructor/t6434.nim b/tests/destructor/t6434.nim
index 1657e90bc..9c912f1f9 100644
--- a/tests/destructor/t6434.nim
+++ b/tests/destructor/t6434.nim
@@ -2,6 +2,8 @@ discard """
   exitcode: 0
   output: '''assingment
 assingment
+assingment
+assingment
 '''
 """
 
diff --git a/tests/seq/t7346.nim b/tests/destructor/t7346.nim
index ef2fd5b79..ef2fd5b79 100644
--- a/tests/seq/t7346.nim
+++ b/tests/destructor/t7346.nim
diff --git a/tests/destructor/texplicit_move.nim b/tests/destructor/texplicit_move.nim
new file mode 100644
index 000000000..6735ac75d
--- /dev/null
+++ b/tests/destructor/texplicit_move.nim
@@ -0,0 +1,19 @@
+
+discard """
+  output: '''3
+0
+destroyed!'''
+"""
+
+type
+  myseq* = object
+    f: int
+
+proc `=destroy`*(x: var myseq) =
+  echo "destroyed!"
+
+var
+  x: myseq
+x.f = 3
+echo move(x.f)
+echo x.f
diff --git a/tests/destructor/tmove_objconstr.nim b/tests/destructor/tmove_objconstr.nim
index 178ff2a7d..50aecf46d 100644
--- a/tests/destructor/tmove_objconstr.nim
+++ b/tests/destructor/tmove_objconstr.nim
@@ -59,4 +59,4 @@ for x in getPony():
   echo x
 # XXX this needs to be enabled once top level statements
 # produce destructor calls again.
-echo "Pony is dying!"
+#echo "Pony is dying!"
diff --git a/tests/errmsgs/t5167_5.nim b/tests/errmsgs/t5167_5.nim
index ab02f29f6..ccd9cc0a5 100644
--- a/tests/errmsgs/t5167_5.nim
+++ b/tests/errmsgs/t5167_5.nim
@@ -1,18 +1,18 @@
 discard """
 cmd: "nim check $file"
-errormsg: "'m' has unspecified generic parameters"
+errormsg: "'t' has unspecified generic parameters"
 nimout: '''
 t5167_5.nim(20, 9) Error: 't' has unspecified generic parameters
-t5167_5.nim(21, 5) Error: 't' has unspecified generic parameters
-t5167_5.nim(23, 9) Error: 'm' has unspecified generic parameters
-t5167_5.nim(24, 5) Error: 'm' has unspecified generic parameters
 '''
 """
 
+
+
+
 template t[B]() =
   echo "foo1"
 
-macro m[T]: stmt = nil
+macro m[T]: untyped = nil
 
 proc bar(x: proc (x: int)) =
   echo "bar"
diff --git a/tests/pragmas/tnoreturn.nim b/tests/pragmas/tnoreturn.nim
index bb59b1c71..50b427d71 100644
--- a/tests/pragmas/tnoreturn.nim
+++ b/tests/pragmas/tnoreturn.nim
@@ -9,8 +9,8 @@ proc noret1*(i: int) {.noreturn.} =
 proc noret2*(i: int): void {.noreturn.} =
   echo i
 
-noret1(1)
-noret2(2)
+if true: noret1(1)
+if true: noret2(2)
 
 var p {.used.}: proc(i: int): int
 doAssert(not compiles(
diff --git a/tests/pragmas/treorder.nim b/tests/pragmas/treorder.nim
index 659a6f644..09a98ef6a 100644
--- a/tests/pragmas/treorder.nim
+++ b/tests/pragmas/treorder.nim
@@ -14,10 +14,10 @@ echo callWithFoo(0)
 echo(CA+CD)
 echo useTypes(TA(x:TB(x:1)), 2)
 second(0)
-  
+
 template callWithFoo(arg: untyped): untyped =
   foo(arg)
-  
+
 proc first(i: int): void
 
 proc second(i: int): void =
@@ -35,7 +35,7 @@ type
 type
   TCyclicA = ref object
     x: TDoubleCyclic
-  
+
 type
   TCyclicB = ref object
     x: TDoubleCyclic
diff --git a/tests/trmacros/tor.nim b/tests/trmacros/tor.nim
index d698e928d..087dc0d68 100644
--- a/tests/trmacros/tor.nim
+++ b/tests/trmacros/tor.nim
@@ -1,11 +1,11 @@
 discard """
-  output: '''3030
+  output: '''0
 true
 3'''
 """
 
 template arithOps: untyped = (`+` | `-` | `*`)
-template testOr{ (arithOps{f})(a, b) }(a, b, f: untyped): untyped = f(a+1, b)
+template testOr{ (arithOps{f})(a, b) }(a, b, f: untyped): untyped = f(a mod 10, b)
 
 let xx = 10
 echo 10*xx
diff --git a/tests/types/t6969.nim b/tests/types/t6969.nim
index d6ce5e62a..14a8481cf 100644
--- a/tests/types/t6969.nim
+++ b/tests/types/t6969.nim
@@ -3,8 +3,4 @@ errormsg: "invalid type: 'object' for var"
 line: 6
 """
 
-var a: object a: int
-# or
-var b: ref object a: int
-# or
-var c: ptr object a: int
\ No newline at end of file
+var a: object
diff --git a/tests/vm/t9043.nim b/tests/vm/t9043.nim
new file mode 100644
index 000000000..1ae2e383c
--- /dev/null
+++ b/tests/vm/t9043.nim
@@ -0,0 +1,10 @@
+discard """
+  nimout: "(Field0: 2, Field1: 2, Field2: 2, Field3: 2)"
+"""
+
+proc foo[N: static[int]](dims: array[N, int])=
+  const N1 = N
+  const N2 = dims.len
+  static: echo (N, dims.len, N1, N2)
+
+foo([1, 2])