summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--appveyor.yml4
-rw-r--r--changelog.md7
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/astalgo.nim15
-rw-r--r--compiler/ccgexprs.nim7
-rw-r--r--compiler/ccgstmts.nim23
-rw-r--r--compiler/cgen.nim3
-rw-r--r--compiler/commands.nim6
-rw-r--r--compiler/evaltempl.nim2
-rw-r--r--compiler/incremental.nim2
-rw-r--r--compiler/int128.nim8
-rw-r--r--compiler/lexer.nim2
-rw-r--r--compiler/nim.cfg2
-rw-r--r--compiler/options.nim2
-rw-r--r--compiler/packagehandling.nim8
-rw-r--r--compiler/pragmas.nim73
-rw-r--r--compiler/rodimpl.nim7
-rw-r--r--compiler/scriptconfig.nim63
-rw-r--r--compiler/semexprs.nim5
-rw-r--r--compiler/semfold.nim9
-rw-r--r--compiler/semtempl.nim39
-rw-r--r--compiler/semtypes.nim15
-rw-r--r--compiler/suggest.nim2
-rw-r--r--compiler/transf.nim2
-rw-r--r--compiler/types.nim11
-rw-r--r--compiler/vm.nim41
-rw-r--r--compiler/vmgen.nim14
-rw-r--r--compiler/vmops.nim10
-rw-r--r--compiler/wordrecg.nim4
-rw-r--r--doc/manual.rst25
-rw-r--r--lib/posix/posix.nim4
-rw-r--r--lib/posix/posix_linux_amd64.nim2
-rw-r--r--lib/posix/posix_macos_amd64.nim7
-rw-r--r--lib/posix/posix_nintendoswitch.nim2
-rw-r--r--lib/posix/posix_other.nim8
-rw-r--r--lib/pure/collections/tables.nim64
-rw-r--r--lib/pure/os.nim40
-rw-r--r--lib/pure/parsexml.nim9
-rw-r--r--lib/pure/pegs.nim7
-rw-r--r--lib/pure/streams.nim2
-rw-r--r--lib/pure/unittest.nim6
-rw-r--r--lib/system.nim4
-rw-r--r--lib/system/mmdisp.nim8
-rw-r--r--lib/wrappers/sqlite3.nim200
-rw-r--r--nimsuggest/tests/disabled_ttemplate_highlight.nim (renamed from nimsuggest/tests/ttemplate_highlight.nim)0
-rw-r--r--testament/categories.nim3
-rw-r--r--testament/important_packages.nim6
-rw-r--r--testament/testament.nim3
-rw-r--r--tests/arithm/tarithm.nim1
-rw-r--r--tests/cpp/mexportc.nim9
-rw-r--r--tests/cpp/texportc.nim22
-rw-r--r--tests/errmsgs/tnnodeadd.nim8
-rw-r--r--tests/errmsgs/tnnodeindex.nim8
-rw-r--r--tests/errmsgs/tnnodeindexkind.nim8
-rw-r--r--tests/gc/gcbench.nim4
-rw-r--r--tests/gensym/tgensymgeneric.nim14
-rw-r--r--tests/misc/tlowhigh.nim14
-rw-r--r--tests/niminaction/Chapter8/sdl/sdl.nim6
-rw-r--r--tests/range/tcompiletime_range_checks.nim52
-rw-r--r--tests/stdlib/tbitops.nim14
-rw-r--r--tests/stdlib/thtmlparser.nim20
-rw-r--r--tests/template/mtempl5.nim14
-rw-r--r--tests/template/template_issues.nim10
-rw-r--r--tests/template/tparams_gensymed.nim31
-rw-r--r--tests/vm/tcompiletimetable.nim11
-rw-r--r--tests/vm/ttouintconv.nim4
-rw-r--r--tests/vm/tzero_extend.nim6
67 files changed, 703 insertions, 343 deletions
diff --git a/appveyor.yml b/appveyor.yml
index 45529cf00..f172405cb 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -15,10 +15,6 @@ cache:
     - '%MINGW_ARCHIVE%'
     - '%DLLS_ARCHIVE%'
 
-matrix:
-  #allow_failures:
-  #  - NIM_TEST_PACKAGES: true
-  fast_finish: true
 
 install:
   - ps: Install-Product node 8 # node 8 or later is required to test js async stuff
diff --git a/changelog.md b/changelog.md
index 57820c81f..5735dd033 100644
--- a/changelog.md
+++ b/changelog.md
@@ -13,7 +13,7 @@
 - The language definition and compiler are now stricter about ``gensym``'ed
   symbols in hygienic templates. See the section in the
   [manual](https://nim-lang.org/docs/manual.html#templates-hygiene-in-templates)
-  for further details. Use the compiler switch `--useVersion:0.19` for a
+  for further details. Use the compiler switch `--oldgensym:on` for a
   transition period.
 
 
@@ -31,6 +31,8 @@ type
 
 ```
 
+- `exportc` now uses C instead of C++ mangling with `nim cpp`, matching behavior of `importc`, see #10578
+  Use the new `exportcpp` to mangle as C++ when using `nim cpp`.
 
 ### Breaking changes in the compiler
 
@@ -71,6 +73,9 @@ iterator mypairs[T](x: openarray[T]): tuple[idx: int, val: lent T]
 
 ## Language changes
 
+- `uint64` is now finally a regular ordinal type. This means `high(uint64)` compiles
+  and yields the correct value.
+
 
 ### Tool changes
 
diff --git a/compiler/ast.nim b/compiler/ast.nim
index db0321f6c..758cd7cfe 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -228,7 +228,7 @@ type
   TNodeKinds* = set[TNodeKind]
 
 type
-  TSymFlag* = enum    # already 36 flags!
+  TSymFlag* = enum    # already 38 flags!
     sfUsed,           # read access of sym (for warnings) or simply used
     sfExported,       # symbol is exported from module
     sfFromGeneric,    # symbol is instantiation of a generic; this is needed
@@ -239,6 +239,7 @@ type
     sfForward,        # symbol is forward declared
     sfImportc,        # symbol is external; imported
     sfExportc,        # symbol is exported (under a specified name)
+    sfMangleCpp,      # mangle as cpp (combines with `sfExportc`)
     sfVolatile,       # variable is volatile
     sfRegister,       # variable should be placed in a register
     sfPure,           # object is "pure" that means it has no type-information
@@ -282,6 +283,7 @@ type
     sfGeneratedOp     # proc is a generated '='; do not inject destructors in it
                       # variable is generated closure environment; requires early
                       # destruction for --newruntime.
+    sfTemplateParam   # symbol is a template parameter
 
 
   TSymFlags* = set[TSymFlag]
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 11144ebf4..700092e67 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -31,6 +31,15 @@ when declared(echo):
   proc debug*(n: PType; conf: ConfigRef = nil) {.exportc: "debugType", deprecated.}
   proc debug*(n: PNode; conf: ConfigRef = nil) {.exportc: "debugNode", deprecated.}
 
+  proc typekinds*(t: PType) {.deprecated.} =
+    var t = t
+    var s = ""
+    while t != nil and t.len > 0:
+      s.add $t.kind
+      s.add " "
+      t = t.lastSon
+    echo s
+
   template debug*(x: PSym|PType|PNode) {.deprecated.} =
     when compiles(c.config):
       debug(c.config, x)
@@ -116,7 +125,7 @@ proc sameValue*(a, b: PNode): bool =
   result = false
   case a.kind
   of nkCharLit..nkUInt64Lit:
-    if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal
+    if b.kind in {nkCharLit..nkUInt64Lit}: result = getInt(a) == getInt(b)
   of nkFloatLit..nkFloat64Lit:
     if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
   of nkStrLit..nkTripleStrLit:
@@ -130,8 +139,8 @@ proc leValue*(a, b: PNode): bool =
   # a <= b?
   result = false
   case a.kind
-  of nkCharLit..nkUInt32Lit:
-    if b.kind in {nkCharLit..nkUInt32Lit}: result = a.intVal <= b.intVal
+  of nkCharLit..nkUInt64Lit:
+    if b.kind in {nkCharLit..nkUInt64Lit}: result = getInt(a) <= getInt(b)
   of nkFloatLit..nkFloat64Lit:
     if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal
   of nkStrLit..nkTripleStrLit:
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 0902e2e19..fa3a1fb86 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1193,6 +1193,8 @@ proc genDefault(p: BProc; n: PNode; d: var TLoc) =
   if d.k == locNone: getTemp(p, n.typ, d, needsInit=true)
   else: resetLoc(p, d)
 
+proc trivialDestructor(s: PSym): bool {.inline.} = s.ast[bodyPos].len == 0
+
 proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
   var sizeExpr = sizeExpr
   let typ = a.t
@@ -1210,7 +1212,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
     genAssignment(p, a, b, {})
   else:
     let ti = genTypeInfo(p.module, typ, a.lode.info)
-    if bt.destructor != nil:
+    if bt.destructor != nil and not trivialDestructor(bt.destructor):
       # the prototype of a destructor is ``=destroy(x: var T)`` and that of a
       # finalizer is: ``proc (x: ref T) {.nimcall.}``. We need to check the calling
       # convention at least:
@@ -2533,6 +2535,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
     of skVar, skForVar, skResult, skLet:
       if {sfGlobal, sfThread} * sym.flags != {}:
         genVarPrototype(p.module, n)
+        if sfCompileTime in sym.flags:
+          genSingleVar(p, sym, n, astdef(sym))
+
       if sym.loc.r == nil or sym.loc.t == nil:
         #echo "FAILED FOR PRCO ", p.prc.name.s
         #echo renderTree(p.prc.ast, {renderIds})
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index ffeeb0db9..29e245ef7 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -271,19 +271,16 @@ proc genGotoVar(p: BProc; value: PNode) =
   else:
     lineF(p, cpsStmts, "goto NIMSTATE_$#;$n", [value.intVal.rope])
 
-proc genSingleVar(p: BProc, a: PNode) =
-  let vn = a.sons[0]
-  let v = vn.sym
-  if sfCompileTime in v.flags: return
+proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) =
   if sfGoto in v.flags:
     # translate 'var state {.goto.} = X' into 'goto LX':
-    genGotoVar(p, a.sons[2])
+    genGotoVar(p, value)
     return
   var targetProc = p
   var traverseProc: Rope
   if sfGlobal in v.flags:
     if v.flags * {sfImportc, sfExportc} == {sfImportc} and
-        a.sons[2].kind == nkEmpty and
+        value.kind == nkEmpty and
         v.loc.flags * {lfHeader, lfNoDecl} != {}:
       return
     if sfPure in v.flags:
@@ -313,14 +310,13 @@ proc genSingleVar(p: BProc, a: PNode) =
     if traverseProc != nil and not p.hcrOn:
       registerTraverseProc(p, v, traverseProc)
   else:
-    let value = a.sons[2]
     let imm = isAssignedImmediately(p.config, value)
     if imm and p.module.compileToCpp and p.splitDecls == 0 and
         not containsHiddenPointer(v.typ):
       # C++ really doesn't like things like 'Foo f; f = x' as that invokes a
       # parameterless constructor followed by an assignment operator. So we
       # generate better code here: 'Foo f = x;'
-      genLineDir(p, a)
+      genLineDir(p, vn)
       let decl = localVarDecl(p, vn)
       var tmp: TLoc
       if value.kind in nkCallKinds and value[0].kind == nkSym and
@@ -363,12 +359,17 @@ proc genSingleVar(p: BProc, a: PNode) =
     lineCg(targetProc, cpsStmts, "if (hcrRegisterGlobal($3, \"$1\", sizeof($2), $4, (void**)&$1))$N",
            [v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc])
     startBlock(targetProc)
-  if a.sons[2].kind != nkEmpty:
-    genLineDir(targetProc, a)
-    loadInto(targetProc, a.sons[0], a.sons[2], v.loc)
+  if value.kind != nkEmpty:
+    genLineDir(targetProc, vn)
+    loadInto(targetProc, vn, value, v.loc)
   if forHcr:
     endBlock(targetProc)
 
+proc genSingleVar(p: BProc, a: PNode) =
+  let v = a[0].sym
+  if sfCompileTime in v.flags: return
+  genSingleVar(p, v, a[0], a.sons[2])
+
 proc genClosureVar(p: BProc, a: PNode) =
   var immediateAsgn = a.sons[2].kind != nkEmpty
   var v: TLoc
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 6e79b2d7b..ba240a020 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -1039,7 +1039,8 @@ proc requiresExternC(m: BModule; sym: PSym): bool {.inline.} =
   result = (sfCompileToCpp in m.module.flags and
            sfCompileToCpp notin sym.getModule().flags and
            m.config.cmd != cmdCompileToCpp) or (
-           sym.flags * {sfImportc, sfInfixCall, sfCompilerProc} == {sfImportc} and
+           sym.flags * {sfInfixCall, sfCompilerProc, sfMangleCpp} == {} and
+           sym.flags * {sfImportc, sfExportc} != {} and
            sym.magic == mNone and
            m.config.cmd == cmdCompileToCpp)
 
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 1123996c1..386b29f8f 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -783,15 +783,15 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
   of "expandmacro":
     expectArg(conf, switch, arg, pass, info)
     conf.macrosToExpand[arg] = "T"
+  of "oldgensym":
+    processOnOffSwitchG(conf, {optNimV019}, arg, pass, info)
   of "useversion":
     expectArg(conf, switch, arg, pass, info)
     case arg
-    of "0.19":
-      conf.globalOptions.incl optNimV019
     of "1.0":
       discard "the default"
     else:
-      localError(conf, info, "unknown Nim version; currently supported values are: {0.19, 1.0}")
+      localError(conf, info, "unknown Nim version; currently supported values are: {1.0}")
   of "":
     conf.projectName = "-"
   else:
diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim
index d941f6c46..8ac7d82be 100644
--- a/compiler/evaltempl.nim
+++ b/compiler/evaltempl.nim
@@ -38,7 +38,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
   of nkSym:
     var s = templ.sym
     if (s.owner == nil and s.kind == skParam) or s.owner == c.owner:
-      if s.kind == skParam and sfGenSym notin s.flags:
+      if s.kind == skParam and {sfGenSym, sfTemplateParam} * s.flags == {sfTemplateParam}:
         handleParam actual.sons[s.position]
       elif (s.owner != nil) and (s.kind == skGenericParam or
            s.kind == skType and s.typ != nil and s.typ.kind == tyGenericParam):
diff --git a/compiler/incremental.nim b/compiler/incremental.nim
index 6cc085020..8b3a9bf55 100644
--- a/compiler/incremental.nim
+++ b/compiler/incremental.nim
@@ -10,7 +10,7 @@
 ## Basic type definitions the module graph needs in order to support
 ## incremental compilations.
 
-const nimIncremental* = true # defined(nimIncremental)
+const nimIncremental* = defined(nimIncremental)
 
 import options, lineinfos
 
diff --git a/compiler/int128.nim b/compiler/int128.nim
index efa55f9c7..5d326ccab 100644
--- a/compiler/int128.nim
+++ b/compiler/int128.nim
@@ -16,13 +16,6 @@ template sdata(arg: Int128, idx: int): int32 =
 
 # encoding least significant int first (like LittleEndian)
 
-type
-  InvalidArgument = object of Exception
-
-template require(cond: bool) =
-  if unlikely(not cond):
-    raise newException(InvalidArgument, "")
-
 const
   Zero* = Int128(udata: [0'u32,0,0,0])
   One* = Int128(udata: [1'u32,0,0,0])
@@ -378,7 +371,6 @@ proc `*`*(lhs,rhs: Int128): Int128 =
   result = result + toInt128(a00 * b32) shl 32
 
   if isNegative != isNegative(result):
-    echo result
     assert(false, "overflow")
 
 proc `*=`*(a: var Int128, b: Int128) =
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index c2b95c481..d1e75d314 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -565,7 +565,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
       case result.tokType
       of floatTypes:
         result.fNumber = parseFloat(result.literal)
-      of tkUInt64Lit:
+      of tkUInt64Lit, tkUIntLit:
         var iNumber: uint64
         var len: int
         try:
diff --git a/compiler/nim.cfg b/compiler/nim.cfg
index b9480007f..ba90a8284 100644
--- a/compiler/nim.cfg
+++ b/compiler/nim.cfg
@@ -7,6 +7,8 @@ define:nimcore
 #define:nimIncremental
 #import:"$projectpath/testability"
 
+#define:staticSqlite
+
 @if windows:
   cincludes: "$lib/wrappers/libffi/common"
 @end
diff --git a/compiler/options.nim b/compiler/options.nim
index 1b9bbb38f..5c7513f6b 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -110,7 +110,7 @@ type
     cmdJsonScript             # compile a .json build file
   TStringSeq* = seq[string]
   TGCMode* = enum             # the selected GC
-    gcNone, gcBoehm, gcRegions, gcMarkAndSweep, gcDestructors,
+    gcUnselected, gcNone, gcBoehm, gcRegions, gcMarkAndSweep, gcDestructors,
     gcRefc, gcV2, gcGo
     # gcRefc and the GCs that follow it use a write barrier,
     # as far as usesWriteBarrier() is concerned
diff --git a/compiler/packagehandling.nim b/compiler/packagehandling.nim
index b9db61b4d..54fbe23a4 100644
--- a/compiler/packagehandling.nim
+++ b/compiler/packagehandling.nim
@@ -39,13 +39,11 @@ proc getPackageName*(conf: ConfigRef; path: string): string =
     if parents <= 0: break
 
 proc fakePackageName*(conf: ConfigRef; path: AbsoluteFile): string =
-  # foo/../bar becomes foo7_7bar
-  result = relativeTo(path, conf.projectPath, '/').string.multiReplace(
-    {"/": "7", "..": "_", "7": "77", "_": "__", ":": "8", "8": "88"})
+  # foo/../bar becomes foo@..@bar
+  result = relativeTo(path, conf.projectPath, '/').string.multiReplace({"/": "@", "@": "@@"})
 
 proc demanglePackageName*(path: string): string =
-  result = path.multiReplace(
-    {"88": "8", "8": ":", "77": "7", "__": "_", "_7": "../", "7": "/"})
+  result = path.multiReplace({"@@": "@", "@": "/"})
 
 proc withPackageName*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile =
   let x = getPackageName(conf, path.string)
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 3de12cfa9..a314277be 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -19,25 +19,27 @@ const
   LastCallConv* = wNoconv
 
 const
-  procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
+  declPragmas = {wImportc, wImportObjC, wImportCpp, wExportc, wExportCpp,
+    wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed}
+    ## common pragmas for declarations, to a good approximation
+  procPragmas* = declPragmas + {FirstCallConv..LastCallConv,
     wMagic, wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader,
-    wCompilerProc, wNonReloadable, wCore, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
-    wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
-    wAsmNoStackFrame, wError, wDiscardable, wNoInit, wCodegenDecl,
+    wCompilerProc, wNonReloadable, wCore, wProcVar, wVarargs, wCompileTime, wMerge,
+    wBorrow, wImportCompilerProc, wThread,
+    wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl,
     wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
-    wConstructor, wExportNims, wUsed, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy}
+    wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy}
   converterPragmas* = procPragmas - {wNoDestroy}
   methodPragmas* = procPragmas+{wBase}-{wImportCpp, wNoDestroy}
   templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty,
     wDelegator, wExportNims, wUsed, wPragma}
-  macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc,
-    wNodecl, wMagic, wNoSideEffect, wCompilerProc, wNonReloadable, wCore, wDeprecated, wExtern,
-    wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator,
-    wExportNims, wUsed}
-  iteratorPragmas* = {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect,
-    wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
-    wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
-    wTags, wLocks, wGcSafe, wExportNims, wUsed}
+  macroPragmas* = declPragmas + {FirstCallConv..LastCallConv,
+    wMagic, wNoSideEffect, wCompilerProc, wNonReloadable, wCore,
+    wDiscardable, wGensym, wInject, wDelegator}
+  iteratorPragmas* = declPragmas + {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect,
+    wMagic, wBorrow,
+    wDiscardable, wGensym, wInject, wRaises,
+    wTags, wLocks, wGcSafe}
   exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe, wNoSideEffect}
   stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangeChecks,
     wBoundChecks, wOverflowChecks, wNilChecks, wStyleChecks, wAssertions,
@@ -49,25 +51,25 @@ const
     wDeprecated,
     wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
     wLinearScanEnd, wPatterns, wTrMacros, wEffects, wNoForward, wReorder, wComputedGoto,
-    wInjectStmt, wDeprecated, wExperimental, wThis, wUsed}
-  lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
+    wInjectStmt, wExperimental, wThis, wUsed}
+  lambdaPragmas* = declPragmas + {FirstCallConv..LastCallConv,
     wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader,
-    wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame,
-    wRaises, wLocks, wTags, wGcSafe, wCodegenDecl}
-  typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
-    wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wExtern, wShallow,
-    wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
+    wThread, wAsmNoStackFrame,
+    wRaises, wLocks, wTags, wGcSafe, wCodegenDecl} - {wExportNims, wError, wUsed}  # why exclude these?
+  typePragmas* = declPragmas + {wMagic, wAcyclic,
+    wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wShallow,
+    wIncompleteStruct, wByCopy, wByRef,
     wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
-    wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain, wPackage}
-  fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
-    wImportCpp, wImportObjC, wError, wGuard, wBitsize, wUsed}
-  varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
-    wMagic, wHeader, wDeprecated, wCompilerProc, wCore, wDynlib, wExtern,
-    wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal,
-    wGensym, wInject, wCodegenDecl, wGuard, wGoto, wExportNims, wUsed, wCursor}
-  constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
-    wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject, wExportNims,
-    wIntDefine, wStrDefine, wBoolDefine, wUsed, wCompilerProc, wCore}
+    wBorrow, wGcSafe, wPartial, wExplain, wPackage}
+  fieldPragmas* = declPragmas + {
+    wGuard, wBitsize} - {wExportNims, wNodecl} # why exclude these?
+  varPragmas* = declPragmas + {wVolatile, wRegister, wThreadVar,
+    wMagic, wHeader, wCompilerProc, wCore, wDynlib,
+    wNoInit, wCompileTime, wGlobal,
+    wGensym, wInject, wCodegenDecl, wGuard, wGoto, wCursor}
+  constPragmas* = declPragmas + {wHeader, wMagic,
+    wGensym, wInject,
+    wIntDefine, wStrDefine, wBoolDefine, wCompilerProc, wCore}
   letPragmas* = varPragmas
   procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNoSideEffect,
                       wThread, wRaises, wLocks, wTags, wGcSafe}
@@ -775,8 +777,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
       if {optStyleHint, optStyleError} * c.config.globalOptions != {}:
         checkPragmaUse(c.config, key.info, k, ident.s)
       case k
-      of wExportc:
+      of wExportc, wExportCpp:
         makeExternExport(c, sym, getOptionalStr(c, it, "$1"), it.info)
+        if k == wExportCpp:
+          if c.config.cmd != cmdCompileToCpp:
+            localError(c.config, it.info, "exportcpp requires `nim cpp`, got " & $c.config.cmd)
+          else:
+            incl(sym.flags, sfMangleCpp)
         incl(sym.flags, sfUsed) # avoid wrong hints
       of wImportc:
         let name = getOptionalStr(c, it, "$1")
@@ -839,7 +846,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
       of wCompileTime:
         noVal(c, it)
         incl(sym.flags, sfCompileTime)
-        incl(sym.loc.flags, lfNoDecl)
+        #incl(sym.loc.flags, lfNoDecl)
       of wGlobal:
         noVal(c, it)
         incl(sym.flags, sfGlobal)
@@ -1131,7 +1138,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
     elif comesFromPush and whichKeyword(ident) in {wTags, wRaises}:
       discard "ignore the .push pragma; it doesn't apply"
     else:
-      if sym == nil or (sym != nil and sym.kind in {skVar, skLet, skParam,
+      if sym == nil or (sym.kind in {skVar, skLet, skParam,
                         skField, skProc, skFunc, skConverter, skMethod, skType}):
         n.sons[i] = semCustomPragma(c, it)
       elif sym != nil:
diff --git a/compiler/rodimpl.nim b/compiler/rodimpl.nim
index b58f77ff6..2c84111d8 100644
--- a/compiler/rodimpl.nim
+++ b/compiler/rodimpl.nim
@@ -223,6 +223,9 @@ proc encodeType(g: ModuleGraph, t: PType, result: var string) =
   if t.lockLevel.ord != UnspecifiedLockLevel.ord:
     add(result, '\14')
     encodeVInt(t.lockLevel.int16, result)
+  if t.paddingAtEnd != 0:
+    add(result, '\15')
+    encodeVInt(t.paddingAtEnd, result)
   for a in t.attachedOps:
     add(result, '\16')
     if a == nil:
@@ -631,6 +634,10 @@ proc loadType(g; id: int; info: TLineInfo): PType =
   else:
     result.lockLevel = UnspecifiedLockLevel
 
+  if b.s[b.pos] == '\15':
+    inc(b.pos)
+    result.paddingAtEnd = decodeVInt(b.s, b.pos).int16
+
   for a in low(result.attachedOps)..high(result.attachedOps):
     if b.s[b.pos] == '\16':
       inc(b.pos)
diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim
index 9878cf597..2dcac5666 100644
--- a/compiler/scriptconfig.nim
+++ b/compiler/scriptconfig.nim
@@ -62,9 +62,15 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
   cbos listDirs:
     listDirs(a, {pcDir})
   cbos removeDir:
-    os.removeDir getString(a, 0)
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.removeDir getString(a, 0)
   cbos removeFile:
-    os.removeFile getString(a, 0)
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.removeFile getString(a, 0)
   cbos createDir:
     os.createDir getString(a, 0)
 
@@ -76,20 +82,35 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
   cbos getCurrentDir:
     setResult(a, os.getCurrentDir())
   cbos moveFile:
-    os.moveFile(getString(a, 0), getString(a, 1))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.moveFile(getString(a, 0), getString(a, 1))
   cbos moveDir:
-    os.moveDir(getString(a, 0), getString(a, 1))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.moveDir(getString(a, 0), getString(a, 1))
   cbos copyFile:
-    os.copyFile(getString(a, 0), getString(a, 1))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.copyFile(getString(a, 0), getString(a, 1))
   cbos copyDir:
-    os.copyDir(getString(a, 0), getString(a, 1))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      os.copyDir(getString(a, 0), getString(a, 1))
   cbos getLastModificationTime:
     setResult(a, getLastModificationTime(getString(a, 0)).toUnix)
   cbos findExe:
     setResult(a, os.findExe(getString(a, 0)))
 
   cbos rawExec:
-    setResult(a, osproc.execCmd getString(a, 0))
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      setResult(a, osproc.execCmd getString(a, 0))
 
   cbconf getEnv:
     setResult(a, os.getEnv(a.getString 0, a.getString 1))
@@ -164,11 +185,17 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
   cbconf cppDefine:
     options.cppDefine(conf, a.getString(0))
   cbexc stdinReadLine, EOFError:
-    setResult(a, "")
-    setResult(a, stdin.readLine())
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      setResult(a, "")
+      setResult(a, stdin.readLine())
   cbexc stdinReadAll, EOFError:
-    setResult(a, "")
-    setResult(a, stdin.readAll())
+    if defined(nimsuggest) or graph.config.cmd == cmdCheck:
+      discard
+    else:
+      setResult(a, "")
+      setResult(a, stdin.readAll())
 
 proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
                    freshDefines=true; conf: ConfigRef) =
@@ -187,6 +214,12 @@ proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
 
   conf.searchPaths.add(conf.libpath)
 
+  let oldGlobalOptions = conf.globalOptions
+  let oldSelectedGC = conf.selectedGC
+  undefSymbol(conf.symbols, "nimv2")
+  conf.globalOptions.excl optNimV2
+  conf.selectedGC = gcUnselected
+
   var m = graph.makeModule(scriptName)
   incl(m.flags, sfMainModule)
   graph.vm = setupVM(m, cache, scriptName.string, graph)
@@ -194,6 +227,14 @@ proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
   graph.compileSystemModule() # TODO: see why this unsets hintConf in conf.notes
   discard graph.processModule(m, llStreamOpen(scriptName, fmRead))
 
+  # watch out, "newruntime" can be set within NimScript itself and then we need
+  # to remember this:
+  if optNimV2 in oldGlobalOptions:
+    conf.globalOptions.incl optNimV2
+    defineSymbol(conf.symbols, "nimv2")
+  if conf.selectedGC == gcUnselected:
+    conf.selectedGC = oldSelectedGC
+
   # ensure we load 'system.nim' again for the real non-config stuff!
   resetSystemArtifacts(graph)
   # do not remove the defined symbols
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index a3d92da8c..1785ae143 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -149,7 +149,7 @@ proc checkConvertible(c: PContext, targetTyp: PType, src: PNode): TConvStatus =
       (srcBaseTyp.kind in IntegralTypes):
     if targetTyp.isOrdinalType:
       if src.kind in nkCharLit..nkUInt64Lit and
-          src.intVal notin firstOrd(c.config, targetTyp)..lastOrd(c.config, targetTyp):
+          src.getInt notin firstOrd(c.config, targetTyp)..lastOrd(c.config, targetTyp):
         result = convNotInRange
       elif src.kind in nkFloatLit..nkFloat64Lit and
           (classify(src.floatVal) in {fcNan, fcNegInf, fcInf} or
@@ -341,7 +341,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
       n.typ = getSysType(c.graph, n.info, tyInt)
     of tyArray:
       n.typ = typ.sons[0] # indextype
-    of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32, tyFloat..tyFloat64:
+    of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt..tyUInt64, tyFloat..tyFloat64:
       n.typ = n.sons[1].typ.skipTypes({tyTypeDesc})
     of tyGenericParam:
       # prepare this for resolving in semtypinst:
@@ -1896,7 +1896,6 @@ proc expectString(c: PContext, n: PNode): string =
 
 proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo): PSym =
   result = newSym(kind, c.cache.idAnon, getCurrOwner(c), info)
-  result.flags = {sfGenSym}
 
 proc semExpandToAst(c: PContext, n: PNode): PNode =
   let macroCall = n[1]
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 3bc6f0f23..81efc2436 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -205,8 +205,9 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
   of mSubI: result = foldSub(getInt(a), getInt(b), n, g)
   of mMulI: result = foldMul(getInt(a), getInt(b), n, g)
   of mMinI:
-    if getInt(a) > getInt(b): result = newIntNodeT(getInt64(b), n, g)
-    else: result = newIntNodeT(getInt64(a), n, g)
+    let argA = getInt(a)
+    let argB = getInt(b)
+    result = newIntNodeT(if argA < argB: argA else: argB, n, g)
   of mMaxI:
     let argA = getInt(a)
     let argB = getInt(b)
@@ -388,13 +389,13 @@ proc leValueConv*(a, b: PNode): bool =
   case a.kind
   of nkCharLit..nkUInt64Lit:
     case b.kind
-    of nkCharLit..nkUInt64Lit: result = a.intVal <= b.intVal
+    of nkCharLit..nkUInt64Lit: result = a.getInt <= b.getInt
     of nkFloatLit..nkFloat128Lit: result = a.intVal <= round(b.floatVal).int
     else: result = false #internalError(a.info, "leValueConv")
   of nkFloatLit..nkFloat128Lit:
     case b.kind
     of nkFloatLit..nkFloat128Lit: result = a.floatVal <= b.floatVal
-    of nkCharLit..nkUInt64Lit: result = a.floatVal <= toFloat(int(b.intVal))
+    of nkCharLit..nkUInt64Lit: result = a.floatVal <= toFloat64(b.getInt)
     else: result = false # internalError(a.info, "leValueConv")
   else: result = false # internalError(a.info, "leValueConv")
 
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index acf32d1b3..bb8748460 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -125,6 +125,7 @@ type
     cursorInBody: bool # only for nimsuggest
     scopeN: int
     noGenSym: int
+    inTemplateHeader: int
 
 template withBracketExpr(ctx, x, body: untyped) =
   body
@@ -144,9 +145,12 @@ proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
     illFormedAst(n, c.c.config)
     result = n
 
+template oldCheck(cx: TemplCtx; cond: bool): bool =
+  (optNimV019 notin cx.c.config.globalOptions or cond)
+
 proc isTemplParam(c: TemplCtx, n: PNode): bool {.inline.} =
   result = n.kind == nkSym and n.sym.kind == skParam and
-           n.sym.owner == c.owner and sfGenSym notin n.sym.flags
+           n.sym.owner == c.owner and sfTemplateParam in n.sym.flags
 
 proc semTemplBody(c: var TemplCtx, n: PNode): PNode
 
@@ -231,6 +235,8 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
         styleCheckDef(c.c.config, n.info, local)
         onDef(n.info, local)
         replaceIdentBySym(c.c, n, newSymNode(local, n.info))
+        if k == skParam and c.inTemplateHeader > 0:
+          local.flags.incl sfTemplateParam
     else:
       replaceIdentBySym(c.c, n, ident)
 
@@ -245,15 +251,15 @@ proc semTemplSymbol(c: PContext, n: PNode, s: PSym; isField: bool): PNode =
   of OverloadableSyms:
     result = symChoice(c, n, s, scOpen, isField)
   of skGenericParam:
-    if isField: result = n
+    if isField and sfGenSym in s.flags: result = n
     else: result = newSymNodeTypeDesc(s, n.info)
   of skParam:
     result = n
   of skType:
-    if isField: result = n
+    if isField and sfGenSym in s.flags: result = n
     else: result = newSymNodeTypeDesc(s, n.info)
   else:
-    if isField: result = n
+    if isField and sfGenSym in s.flags: result = n
     else: result = newSymNode(s, n.info)
 
 proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode =
@@ -288,7 +294,14 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
     n.sons[namePos] = semRoutineInTemplName(c, n.sons[namePos])
   # open scope for parameters
   openScope(c)
-  for i in patternPos..miscPos:
+  for i in patternPos..paramsPos-1:
+    n.sons[i] = semTemplBody(c, n.sons[i])
+
+  if k == skTemplate: inc(c.inTemplateHeader)
+  n.sons[paramsPos] = semTemplBody(c, n.sons[paramsPos])
+  if k == skTemplate: dec(c.inTemplateHeader)
+
+  for i in paramsPos+1..miscPos:
     n.sons[i] = semTemplBody(c, n.sons[i])
   # open scope for locals
   inc c.scopeN
@@ -331,8 +344,8 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
     if n.ident.id in c.toInject: return n
     let s = qualifiedLookUp(c.c, n, {})
     if s != nil:
-      if s.owner == c.owner and s.kind == skParam and
-          (sfGenSym notin s.flags or c.noGenSym == 0):
+      if s.owner == c.owner and s.kind == skParam and sfTemplateParam in s.flags:
+        # oldCheck(c, sfGenSym notin s.flags or c.noGenSym == 0):
         incl(s.flags, sfUsed)
         result = newSymNode(s, n.info)
         onUse(n.info, s)
@@ -542,16 +555,16 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
     if n.kind == nkDotExpr:
       result = n
       result.sons[0] = semTemplBody(c, n.sons[0])
-      inc c.noGenSym
+      if optNimV019 notin c.c.config.globalOptions: inc c.noGenSym
       result.sons[1] = semTemplBody(c, n.sons[1])
-      dec c.noGenSym
+      if optNimV019 notin c.c.config.globalOptions: dec c.noGenSym
     else:
       result = semTemplBodySons(c, n)
   of nkExprColonExpr, nkExprEqExpr:
     if n.len == 2:
-      inc c.noGenSym
+      if optNimV019 notin c.c.config.globalOptions: inc c.noGenSym
       result.sons[0] = semTemplBody(c, n.sons[0])
-      dec c.noGenSym
+      if optNimV019 notin c.c.config.globalOptions: dec c.noGenSym
       result.sons[1] = semTemplBody(c, n.sons[1])
     else:
       result = semTemplBodySons(c, n)
@@ -625,7 +638,9 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
     # body by the absence of the sfGenSym flag:
     for i in 1 .. s.typ.n.len-1:
       let param = s.typ.n.sons[i].sym
-      param.flags.excl sfGenSym
+      param.flags.incl sfTemplateParam
+      if optNimV019 in c.config.globalOptions:
+        param.flags.excl sfGenSym
       if param.typ.kind != tyUntyped: allUntyped = false
     if sonsLen(gp) > 0:
       if n.sons[genericParamsPos].kind == nkEmpty:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 41d7f0d19..0894267b9 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -225,7 +225,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
   if not hasUnknownTypes:
     if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})):
       localError(c.config, n.info, "type mismatch")
-    elif not rangeT[0].isOrdinalType and rangeT[0].kind notin tyFloat..tyFloat128 or
+    elif not isOrdinalType(rangeT[0]) and rangeT[0].kind notin tyFloat..tyFloat128 or
         rangeT[0].kind == tyBool:
       localError(c.config, n.info, "ordinal or float type expected")
     elif enumHasHoles(rangeT[0]):
@@ -850,6 +850,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
       localError(c.config, n.info, "type '$1 void' is not allowed" % kindToStr[kind])
     result = newOrPrevType(kind, prev, c)
     var isNilable = false
+    var isOwned = false
     # check every except the last is an object:
     for i in isCall .. n.len-2:
       let ni = n[i]
@@ -857,16 +858,24 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
         isNilable = true
       else:
         let region = semTypeNode(c, ni, nil)
-        if region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin {
+        if region.kind == tyOwned:
+          isOwned = true
+        elif region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin {
               tyError, tyObject}:
           message c.config, n[i].info, errGenerated, "region needs to be an object type"
+          addSonSkipIntLit(result, region)
         else:
           message(c.config, n.info, warnDeprecated, "region for pointer types is deprecated")
-        addSonSkipIntLit(result, region)
+          addSonSkipIntLit(result, region)
     addSonSkipIntLit(result, t)
     if tfPartial in result.flags:
       if result.lastSon.kind == tyObject: incl(result.lastSon.flags, tfPartial)
     #if not isNilable: result.flags.incl tfNotNil
+    if isOwned and optNimV2 in c.config.globalOptions:
+      let t = newTypeS(tyOwned, c)
+      t.flags.incl tfHasOwned
+      t.rawAddSonNoPropagationOfTypeFlags result
+      result = t
 
 proc findEnforcedStaticType(t: PType): PType =
   # This handles types such as `static[T] and Foo`,
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index 9680bc846..5cb365a4a 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -641,7 +641,7 @@ proc suggestSentinel*(c: PContext) =
       var pm: PrefixMatch
       if filterSymNoOpr(it, nil, pm):
         outputs.add(symToSuggest(c.config, it, isLocal = isLocal, ideSug,
-            newLineInfo(c.config.m.trackPos.fileIndex, -1, -1), 0,
+            newLineInfo(c.config.m.trackPos.fileIndex, 0, -1), 0,
             PrefixMatch.None, false, scopeN))
 
   dec(c.compilesContextId)
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 836a6154c..dc700278f 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -717,7 +717,7 @@ proc transformCase(c: PTransf, n: PNode): PTransNode =
     result.add(elseBranch)
   elif result.PNode.lastSon.kind != nkElse and not (
       skipTypes(n.sons[0].typ, abstractVarRange).kind in
-        {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32}):
+        {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt64}):
     # fix a stupid code gen bug by normalizing:
     var elseBranch = newTransNode(nkElse, n.info, 1)
     elseBranch[0] = newTransNode(nkNilLit, n.info, 0)
diff --git a/compiler/types.nim b/compiler/types.nim
index e2de8280e..a05625327 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -162,14 +162,13 @@ proc enumHasHoles*(t: PType): bool =
   var b = t.skipTypes({tyRange, tyGenericInst, tyAlias, tySink})
   result = b.kind == tyEnum and tfEnumHasHoles in b.flags
 
-proc isOrdinalType*(t: PType, allowEnumWithHoles = false): bool =
+proc isOrdinalType*(t: PType, allowEnumWithHoles: bool = false): bool =
   assert(t != nil)
   const
-    # caution: uint, uint64 are no ordinal types!
-    baseKinds = {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum}
+    baseKinds = {tyChar,tyInt..tyInt64,tyUInt..tyUInt64,tyBool,tyEnum}
     parentKinds = {tyRange, tyOrdinal, tyGenericInst, tyAlias, tySink, tyDistinct}
-  (t.kind in baseKinds and not (t.enumHasHoles and not allowEnumWithHoles)) or
-    (t.kind in parentKinds and isOrdinalType(t.lastSon))
+  result = (t.kind in baseKinds and (not t.enumHasHoles or allowEnumWithHoles)) or
+    (t.kind in parentKinds and isOrdinalType(t.lastSon, allowEnumWithHoles))
 
 proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
                      closure: RootRef): bool
@@ -1319,7 +1318,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
     result = typeAllowedAux(marker, lastSon(t), kind, flags)
   of tyRange:
     if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
-      {tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t
+      {tyChar, tyEnum, tyInt..tyFloat128, tyInt..tyUInt64}: result = t
   of tyOpenArray, tyVarargs, tySink:
     # you cannot nest openArrays/sinks/etc.
     if kind != skParam or taIsOpenArray in flags:
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 072a1826b..130027edd 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1384,17 +1384,21 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       decodeBC(rkNode)
       let idx = regs[rc].intVal.int
       let src = regs[rb].node
-      if src.kind notin {nkEmpty..nkNilLit} and idx <% src.len:
-        regs[ra].node = src.sons[idx]
-      else:
+      if src.kind in {nkEmpty..nkNilLit}:
+        stackTrace(c, tos, pc, "cannot get child of node kind: n" & $src.kind)
+      elif idx >=% src.len:
         stackTrace(c, tos, pc, formatErrorIndexBound(idx, src.len-1))
+      else:
+        regs[ra].node = src.sons[idx]
     of opcNSetChild:
       decodeBC(rkNode)
       let idx = regs[rb].intVal.int
       var dest = regs[ra].node
       if nfSem in dest.flags and allowSemcheckedAstModification notin c.config.legacyFeatures:
         stackTrace(c, tos, pc, "typechecked nodes may not be modified")
-      elif dest.kind in {nkEmpty..nkNilLit} or idx >=% dest.len:
+      elif dest.kind in {nkEmpty..nkNilLit}:
+        stackTrace(c, tos, pc, "cannot set child of node kind: n" & $dest.kind)
+      elif idx >=% dest.len:
         stackTrace(c, tos, pc, formatErrorIndexBound(idx, dest.len-1))
       else:
         dest.sons[idx] = regs[rc].node
@@ -1404,7 +1408,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       if nfSem in u.flags and allowSemcheckedAstModification notin c.config.legacyFeatures:
         stackTrace(c, tos, pc, "typechecked nodes may not be modified")
       elif u.kind in {nkEmpty..nkNilLit}:
-        stackTrace(c, tos, pc, "cannot add to node kind: " & $u.kind)
+        stackTrace(c, tos, pc, "cannot add to node kind: n" & $u.kind)
       else:
         u.add(regs[rc].node)
       regs[ra].node = u
@@ -1415,7 +1419,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       if nfSem in u.flags and allowSemcheckedAstModification notin c.config.legacyFeatures:
         stackTrace(c, tos, pc, "typechecked nodes may not be modified")
       elif u.kind in {nkEmpty..nkNilLit}:
-        stackTrace(c, tos, pc, "cannot add to node kind: " & $u.kind)
+        stackTrace(c, tos, pc, "cannot add to node kind: n" & $u.kind)
       else:
         for i in 0 ..< x.len: u.add(x.sons[i])
       regs[ra].node = u
@@ -1549,17 +1553,20 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       regs[ra].node.strVal = opSlurp(regs[rb].node.strVal, c.debug[pc],
                                      c.module, c.config)
     of opcGorge:
-      when defined(nimcore):
-        decodeBC(rkNode)
-        inc pc
-        let rd = c.code[pc].regA
-
-        createStr regs[ra]
-        regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
-                                      regs[rc].node.strVal, regs[rd].node.strVal,
-                                      c.debug[pc], c.config)[0]
-      else:
-        globalError(c.config, c.debug[pc], "VM is not built with 'gorge' support")
+      if defined(nimsuggest) or c.config.cmd == cmdCheck:
+        discard "don't run staticExec for 'nim suggest'"
+      else:
+        when defined(nimcore):
+          decodeBC(rkNode)
+          inc pc
+          let rd = c.code[pc].regA
+
+          createStr regs[ra]
+          regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
+                                        regs[rc].node.strVal, regs[rd].node.strVal,
+                                        c.debug[pc], c.config)[0]
+        else:
+          globalError(c.config, c.debug[pc], "VM is not built with 'gorge' support")
     of opcNError, opcNWarning, opcNHint:
       decodeB(rkNode)
       let a = regs[ra].node
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 9a16bd5b9..8863b2dc9 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -682,6 +682,7 @@ proc genUnaryABI(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; imm: BiggestI
   c.gABI(n, opc, dest, tmp, imm)
   c.freeTemp(tmp)
 
+
 proc genBinaryABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
   let
     tmp = c.genx(n.sons[1])
@@ -999,22 +1000,15 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
   of mMulF64: genBinaryABC(c, n, dest, opcMulFloat)
   of mDivF64: genBinaryABC(c, n, dest, opcDivFloat)
   of mShrI:
-    # the idea here is to narrow type if needed before executing right shift
-    # inlined modified: genNarrowU(c, n, dest)
-    let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
-    # uint is uint64 in the VM, we we only need to mask the result for
-    # other unsigned types:
+    # modified: genBinaryABC(c, n, dest, opcShrInt)
+    # narrowU is applied to the left operandthe idea here is to narrow the left operand
     let tmp = c.genx(n.sons[1])
-    if t.kind in {tyUInt8..tyUInt32, tyInt8..tyInt32}:
-      c.gABC(n, opcNarrowU, tmp, TRegister(t.size*8))
-
-    # inlined modified: genBinaryABC(c, n, dest, opcShrInt)
+    c.genNarrowU(n, tmp)
     let tmp2 = c.genx(n.sons[2])
     if dest < 0: dest = c.getTemp(n.typ)
     c.gABC(n, opcShrInt, dest, tmp, tmp2)
     c.freeTemp(tmp)
     c.freeTemp(tmp2)
-
   of mShlI:
     genBinaryABC(c, n, dest, opcShlInt)
     # genNarrowU modified
diff --git a/compiler/vmops.nim b/compiler/vmops.nim
index b0325b5b0..fe3c2516b 100644
--- a/compiler/vmops.nim
+++ b/compiler/vmops.nim
@@ -77,6 +77,14 @@ template wrap2svoid(op, modop) {.dirty.} =
     op(getString(a, 0), getString(a, 1))
   modop op
 
+template wrapDangerous(op, modop) {.dirty.} =
+  proc `op Wrapper`(a: VmArgs) {.nimcall.} =
+    if defined(nimsuggest) or c.config.cmd == cmdCheck:
+      discard
+    else:
+      op(getString(a, 0), getString(a, 1))
+  modop op
+
 proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} =
   setResult(a, if a.currentException.isNil: ""
                else: a.currentException.sons[3].skipColon.strVal)
@@ -133,7 +141,7 @@ proc registerAdditionalOps*(c: PCtx) =
     wrap2svoid(putEnv, osop)
     wrap1s(dirExists, osop)
     wrap1s(fileExists, osop)
-    wrap2svoid(writeFile, ioop)
+    wrapDangerous(writeFile, ioop)
     wrap1s(readFile, ioop)
     wrap2si(readLines, ioop)
     systemop getCurrentExceptionMsg
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index 62b26adf3..23c87ac39 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -42,7 +42,7 @@ type
     wImmediate, wConstructor, wDestructor, wDelegator, wOverride,
     wImportCpp, wImportObjC,
     wImportCompilerProc,
-    wImportc, wExportc, wExportNims, wIncompleteStruct, wRequiresInit,
+    wImportc, wExportc, wExportCpp, wExportNims, wIncompleteStruct, wRequiresInit,
     wAlign, wNodecl, wPure, wSideEffect, wHeader,
     wNoSideEffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib,
     wCompilerProc, wCore, wProcVar, wBase, wUsed,
@@ -129,7 +129,7 @@ const
 
     "immediate", "constructor", "destructor", "delegator", "override",
     "importcpp", "importobjc",
-    "importcompilerproc", "importc", "exportc", "exportnims",
+    "importcompilerproc", "importc", "exportc", "exportcpp", "exportnims",
     "incompletestruct",
     "requiresinit", "align", "nodecl", "pure", "sideeffect",
     "header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib",
diff --git a/doc/manual.rst b/doc/manual.rst
index a8326d94d..3c194b1d2 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -5928,6 +5928,31 @@ Is the same as:
   proc astHelper(n: NimNode): NimNode {.compileTime.} =
     result = n
 
+``compileTime`` variables are available at runtime too. This simplifies certain
+idioms where variables are filled at compile-time (for example, lookup tables)
+but accessed at runtime:
+
+.. code-block:: nim
+    :test: "nim c -r $1"
+
+  import macros
+
+  var nameToProc {.compileTime.}: seq[(string, proc (): string {.nimcall.})]
+
+  macro registerProc(p: untyped): untyped =
+    result = newTree(nnkStmtList, p)
+
+    let procName = p[0]
+    let procNameAsStr = $p[0]
+    result.add quote do:
+      nameToProc.add((`procNameAsStr`, `procName`))
+
+  proc foo: string {.registerProc.} = "foo"
+  proc bar: string {.registerProc.} = "bar"
+  proc baz: string {.registerProc.} = "baz"
+
+  doAssert nameToProc[2][1]() == "baz"
+
 
 noReturn pragma
 ---------------
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index dea247246..a285928c2 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -95,9 +95,9 @@ const StatHasNanoseconds* = defined(linux) or defined(freebsd) or
 
 # Platform specific stuff
 
-when defined(linux) and defined(amd64):
+when (defined(linux) and not defined(android)) and defined(amd64):
   include posix_linux_amd64
-elif (defined(macosx) or defined(bsd)) and defined(cpu64):
+elif (defined(macos) or defined(macosx) or defined(bsd)) and defined(cpu64):
   include posix_macos_amd64
 elif defined(nintendoswitch):
   include posix_nintendoswitch
diff --git a/lib/posix/posix_linux_amd64.nim b/lib/posix/posix_linux_amd64.nim
index b4331fdad..be7934f2f 100644
--- a/lib/posix/posix_linux_amd64.nim
+++ b/lib/posix/posix_linux_amd64.nim
@@ -147,7 +147,7 @@ type
   Id* {.importc: "id_t", header: "<sys/types.h>".} = cuint
   Ino* {.importc: "ino_t", header: "<sys/types.h>".} = culong
   Key* {.importc: "key_t", header: "<sys/types.h>".} = cint
-  Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint # cuint really!
+  Mode* {.importc: "mode_t", header: "<sys/types.h>".} = uint32
   Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = culong
   Off* {.importc: "off_t", header: "<sys/types.h>".} = clong
   Pid* {.importc: "pid_t", header: "<sys/types.h>".} = cint
diff --git a/lib/posix/posix_macos_amd64.nim b/lib/posix/posix_macos_amd64.nim
index 5000c1160..41522fd17 100644
--- a/lib/posix/posix_macos_amd64.nim
+++ b/lib/posix/posix_macos_amd64.nim
@@ -140,7 +140,12 @@ type
   Id* {.importc: "id_t", header: "<sys/types.h>".} = int
   Ino* {.importc: "ino_t", header: "<sys/types.h>".} = int
   Key* {.importc: "key_t", header: "<sys/types.h>".} = int
-  Mode* {.importc: "mode_t", header: "<sys/types.h>".} = int16
+  Mode* {.importc: "mode_t", header: "<sys/types.h>".} = (
+    when defined(openbsd) or defined(netbsd):
+      uint32
+    else:
+      uint16
+  )
   Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = int16
   Off* {.importc: "off_t", header: "<sys/types.h>".} = int64
   Pid* {.importc: "pid_t", header: "<sys/types.h>".} = int32
diff --git a/lib/posix/posix_nintendoswitch.nim b/lib/posix/posix_nintendoswitch.nim
index 887d16586..d1cc042ea 100644
--- a/lib/posix/posix_nintendoswitch.nim
+++ b/lib/posix/posix_nintendoswitch.nim
@@ -123,7 +123,7 @@ type
   Id* {.importc: "id_t", header: "<sys/types.h>".} = cuint
   Ino* {.importc: "ino_t", header: "<sys/types.h>".} = culong
   Key* {.importc: "key_t", header: "<sys/types.h>".} = cint
-  Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint # cuint really!
+  Mode* {.importc: "mode_t", header: "<sys/types.h>".} = uint16
   Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = culong
   Off* {.importc: "off_t", header: "<sys/types.h>".} = clong
   Pid* {.importc: "pid_t", header: "<sys/types.h>".} = cint
diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim
index b9a6c2517..c582240d1 100644
--- a/lib/posix/posix_other.nim
+++ b/lib/posix/posix_other.nim
@@ -149,7 +149,13 @@ type
   Id* {.importc: "id_t", header: "<sys/types.h>".} = int
   Ino* {.importc: "ino_t", header: "<sys/types.h>".} = int
   Key* {.importc: "key_t", header: "<sys/types.h>".} = int
-  Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint
+  Mode* {.importc: "mode_t", header: "<sys/types.h>".} = (
+    when defined(android) or defined(macos) or defined(macosx) or
+        (defined(bsd) and not defined(openbsd) and not defined(netbsd)):
+      uint16
+    else:
+      uint32
+  )
   Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = int
   Off* {.importc: "off_t", header: "<sys/types.h>".} = int64
   Pid* {.importc: "pid_t", header: "<sys/types.h>".} = int32
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 1352bdf68..967a6726f 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -307,6 +307,22 @@ proc initTable*[A, B](initialSize = defaultInitialSize): Table[A, B] =
       b = initTable[char, seq[int]]()
   initImpl(result, initialSize)
 
+proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) =
+  ## Inserts a ``(key, value)`` pair into ``t``.
+  ##
+  ## See also:
+  ## * `[] proc<#[],Table[A,B],A>`_ for retrieving a value of a key
+  ## * `hasKeyOrPut proc<#hasKeyOrPut,Table[A,B],A,B>`_
+  ## * `mgetOrPut proc<#mgetOrPut,Table[A,B],A,B>`_
+  ## * `del proc<#del,Table[A,B],A>`_ for removing a key from the table
+  runnableExamples:
+    var a = initTable[char, int]()
+    a['x'] = 7
+    a['y'] = 33
+    doAssert a == {'x': 7, 'y': 33}.toTable
+
+  putImpl(enlarge)
+
 proc toTable*[A, B](pairs: openArray[(A, B)]): Table[A, B] =
   ## Creates a new hash table that contains the given ``pairs``.
   ##
@@ -362,22 +378,6 @@ proc `[]`*[A, B](t: var Table[A, B], key: A): var B =
   ##   the table
   get(t, key)
 
-proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) =
-  ## Inserts a ``(key, value)`` pair into ``t``.
-  ##
-  ## See also:
-  ## * `[] proc<#[],Table[A,B],A>`_ for retrieving a value of a key
-  ## * `hasKeyOrPut proc<#hasKeyOrPut,Table[A,B],A,B>`_
-  ## * `mgetOrPut proc<#mgetOrPut,Table[A,B],A,B>`_
-  ## * `del proc<#del,Table[A,B],A>`_ for removing a key from the table
-  runnableExamples:
-    var a = initTable[char, int]()
-    a['x'] = 7
-    a['y'] = 33
-    doAssert a == {'x': 7, 'y': 33}.toTable
-
-  putImpl(enlarge)
-
 proc hasKey*[A, B](t: Table[A, B], key: A): bool =
   ## Returns true if ``key`` is in the table ``t``.
   ##
@@ -1285,6 +1285,22 @@ proc initOrderedTable*[A, B](initialSize = defaultInitialSize): OrderedTable[A,
       b = initOrderedTable[char, seq[int]]()
   initImpl(result, initialSize)
 
+proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: B) =
+  ## Inserts a ``(key, value)`` pair into ``t``.
+  ##
+  ## See also:
+  ## * `[] proc<#[],OrderedTable[A,B],A>`_ for retrieving a value of a key
+  ## * `hasKeyOrPut proc<#hasKeyOrPut,OrderedTable[A,B],A,B>`_
+  ## * `mgetOrPut proc<#mgetOrPut,OrderedTable[A,B],A,B>`_
+  ## * `del proc<#del,OrderedTable[A,B],A>`_ for removing a key from the table
+  runnableExamples:
+    var a = initOrderedTable[char, int]()
+    a['x'] = 7
+    a['y'] = 33
+    doAssert a == {'x': 7, 'y': 33}.toOrderedTable
+
+  putImpl(enlarge)
+
 proc toOrderedTable*[A, B](pairs: openArray[(A, B)]): OrderedTable[A, B] =
   ## Creates a new ordered hash table that contains the given ``pairs``.
   ##
@@ -1342,22 +1358,6 @@ proc `[]`*[A, B](t: var OrderedTable[A, B], key: A): var B =
   ##   key is in the table
   get(t, key)
 
-proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: B) =
-  ## Inserts a ``(key, value)`` pair into ``t``.
-  ##
-  ## See also:
-  ## * `[] proc<#[],OrderedTable[A,B],A>`_ for retrieving a value of a key
-  ## * `hasKeyOrPut proc<#hasKeyOrPut,OrderedTable[A,B],A,B>`_
-  ## * `mgetOrPut proc<#mgetOrPut,OrderedTable[A,B],A,B>`_
-  ## * `del proc<#del,OrderedTable[A,B],A>`_ for removing a key from the table
-  runnableExamples:
-    var a = initOrderedTable[char, int]()
-    a['x'] = 7
-    a['y'] = 33
-    doAssert a == {'x': 7, 'y': 33}.toOrderedTable
-
-  putImpl(enlarge)
-
 proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool =
   ## Returns true if ``key`` is in the table ``t``.
   ##
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index b0c3d3441..65b98d7a1 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1435,17 +1435,17 @@ proc getFilePermissions*(filename: string): set[FilePermission] {.
     var a: Stat
     if stat(filename, a) < 0'i32: raiseOSError(osLastError())
     result = {}
-    if (a.st_mode and S_IRUSR) != 0'i32: result.incl(fpUserRead)
-    if (a.st_mode and S_IWUSR) != 0'i32: result.incl(fpUserWrite)
-    if (a.st_mode and S_IXUSR) != 0'i32: result.incl(fpUserExec)
+    if (a.st_mode and S_IRUSR.Mode) != 0.Mode: result.incl(fpUserRead)
+    if (a.st_mode and S_IWUSR.Mode) != 0.Mode: result.incl(fpUserWrite)
+    if (a.st_mode and S_IXUSR.Mode) != 0.Mode: result.incl(fpUserExec)
 
-    if (a.st_mode and S_IRGRP) != 0'i32: result.incl(fpGroupRead)
-    if (a.st_mode and S_IWGRP) != 0'i32: result.incl(fpGroupWrite)
-    if (a.st_mode and S_IXGRP) != 0'i32: result.incl(fpGroupExec)
+    if (a.st_mode and S_IRGRP.Mode) != 0.Mode: result.incl(fpGroupRead)
+    if (a.st_mode and S_IWGRP.Mode) != 0.Mode: result.incl(fpGroupWrite)
+    if (a.st_mode and S_IXGRP.Mode) != 0.Mode: result.incl(fpGroupExec)
 
-    if (a.st_mode and S_IROTH) != 0'i32: result.incl(fpOthersRead)
-    if (a.st_mode and S_IWOTH) != 0'i32: result.incl(fpOthersWrite)
-    if (a.st_mode and S_IXOTH) != 0'i32: result.incl(fpOthersExec)
+    if (a.st_mode and S_IROTH.Mode) != 0.Mode: result.incl(fpOthersRead)
+    if (a.st_mode and S_IWOTH.Mode) != 0.Mode: result.incl(fpOthersWrite)
+    if (a.st_mode and S_IXOTH.Mode) != 0.Mode: result.incl(fpOthersExec)
   else:
     when useWinUnicode:
       wrapUnary(res, getFileAttributesW, filename)
@@ -1470,18 +1470,18 @@ proc setFilePermissions*(filename: string, permissions: set[FilePermission]) {.
   ## * `getFilePermissions <#getFilePermissions,string>`_
   ## * `FilePermission enum <#FilePermission>`_
   when defined(posix):
-    var p = 0'i32
-    if fpUserRead in permissions: p = p or S_IRUSR
-    if fpUserWrite in permissions: p = p or S_IWUSR
-    if fpUserExec in permissions: p = p or S_IXUSR
+    var p = 0.Mode
+    if fpUserRead in permissions: p = p or S_IRUSR.Mode
+    if fpUserWrite in permissions: p = p or S_IWUSR.Mode
+    if fpUserExec in permissions: p = p or S_IXUSR.Mode
 
-    if fpGroupRead in permissions: p = p or S_IRGRP
-    if fpGroupWrite in permissions: p = p or S_IWGRP
-    if fpGroupExec in permissions: p = p or S_IXGRP
+    if fpGroupRead in permissions: p = p or S_IRGRP.Mode
+    if fpGroupWrite in permissions: p = p or S_IWGRP.Mode
+    if fpGroupExec in permissions: p = p or S_IXGRP.Mode
 
-    if fpOthersRead in permissions: p = p or S_IROTH
-    if fpOthersWrite in permissions: p = p or S_IWOTH
-    if fpOthersExec in permissions: p = p or S_IXOTH
+    if fpOthersRead in permissions: p = p or S_IROTH.Mode
+    if fpOthersWrite in permissions: p = p or S_IWOTH.Mode
+    if fpOthersExec in permissions: p = p or S_IXOTH.Mode
 
     if chmod(filename, cast[Mode](p)) != 0: raiseOSError(osLastError())
   else:
@@ -2854,7 +2854,7 @@ template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped =
 
   else:
     template checkAndIncludeMode(rawMode, formalMode: untyped) =
-      if (rawInfo.st_mode and rawMode) != 0'i32:
+      if (rawInfo.st_mode and rawMode.Mode) != 0.Mode:
         formalInfo.permissions.incl(formalMode)
     formalInfo.id = (rawInfo.st_dev, rawInfo.st_ino)
     formalInfo.size = rawInfo.st_size
diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim
index 3b77f9c62..686aad110 100644
--- a/lib/pure/parsexml.nim
+++ b/lib/pure/parsexml.nim
@@ -472,16 +472,19 @@ proc parseEntity(my: var XmlParser, dest: var string) =
     inc(pos, 4)
   else:
     my.bufpos = pos
-    parseName(my, dest)
+    var name = ""
+    parseName(my, name)
     pos = my.bufpos
-    if my.err != errNameExpected:
+    if my.err != errNameExpected and my.buf[pos] == ';':
       my.kind = xmlEntity
     else:
       add(dest, '&')
+    add(dest, name)
   if my.buf[pos] == ';':
     inc(pos)
   else:
-    markError(my, errSemicolonExpected)
+    my.err = errSemicolonExpected
+    # do not overwrite 'my.state' here, it's a benign error
   my.bufpos = pos
 
 proc parsePI(my: var XmlParser) =
diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim
index 844fbd13c..7ce65b438 100644
--- a/lib/pure/pegs.nim
+++ b/lib/pure/pegs.nim
@@ -890,12 +890,13 @@ macro mkHandlerTplts(handlers: untyped): untyped =
   #           <handler code block>
   #   ...
   proc mkEnter(hdName, body: NimNode): NimNode =
-    quote do:
-      template `hdName`(s, p, start) =
+    template helper(hdName, body) {.dirty.} =
+      template hdName(s, p, start) =
         let s {.inject.} = s
         let p {.inject.} = p
         let start {.inject.} = start
-        `body`
+        body
+    result = getAst(helper(hdName, body))
 
   template mkLeave(hdPostf, body) {.dirty.} =
     # this has to be dirty to be able to capture *result* as *length* in
diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim
index 28d9d7612..448c6121a 100644
--- a/lib/pure/streams.nim
+++ b/lib/pure/streams.nim
@@ -127,7 +127,7 @@ type
     peekDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int
       {.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
     writeDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int)
-        {.nimcall, raises: [Defect, IOError, OSError], tags: [WriteIOEffect], gcsafe.}
+      {.nimcall, raises: [Defect, IOError, OSError], tags: [WriteIOEffect], gcsafe.}
 
     flushImpl*: proc (s: Stream)
       {.nimcall, raises: [Defect, IOError, OSError], tags: [WriteIOEffect], gcsafe.}
diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim
index 3f84c1853..469e75c16 100644
--- a/lib/pure/unittest.nim
+++ b/lib/pure/unittest.nim
@@ -89,7 +89,7 @@
 ##     echo "suite teardown: run once after the tests"
 
 import
-  macros, strutils, streams, times, sets
+  macros, strutils, streams, times, sets, sequtils
 
 when declared(stdout):
   import os
@@ -176,6 +176,10 @@ method suiteEnded*(formatter: OutputFormatter) {.base, gcsafe.} =
 proc addOutputFormatter*(formatter: OutputFormatter) =
   formatters.add(formatter)
 
+proc delOutputFormatter*(formatter: OutputFormatter) =
+  keepIf(formatters, proc (x: OutputFormatter) : bool =
+    x != formatter)
+
 proc newConsoleOutputFormatter*(outputLevel: OutputLevel = PRINT_ALL,
                                 colorOutput = true): <//>ConsoleOutputFormatter =
   ConsoleOutputFormatter(
diff --git a/lib/system.nim b/lib/system.nim
index 05dc43ab2..ebea457dd 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -97,7 +97,7 @@ type
   SomeInteger* = SomeSignedInt|SomeUnsignedInt
     ## Type class matching all integer types.
 
-  SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint8|uint16|uint32
+  SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint|uint8|uint16|uint32|uint64
     ## Type class matching all ordinal types; however this includes enums with
     ## holes.
 
@@ -1989,6 +1989,8 @@ when defined(boehmgc):
       const boehmLib = "boehmgc.dll"
   elif defined(macosx):
     const boehmLib = "libgc.dylib"
+  elif defined(openbsd):
+    const boehmLib = "libgc.so.4.0"
   else:
     const boehmLib = "libgc.so.1"
   {.pragma: boehmGC, noconv, dynlib: boehmLib.}
diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim
index 47bb400a7..0d1bb1767 100644
--- a/lib/system/mmdisp.nim
+++ b/lib/system/mmdisp.nim
@@ -112,8 +112,8 @@ when defined(boehmgc):
       if result == nil: raiseOutOfMem()
     proc alloc0(size: Natural): pointer =
       result = alloc(size)
-    proc realloc(p: pointer, newsize: Natural): pointer =
-      result = boehmRealloc(p, newsize)
+    proc realloc(p: pointer, newSize: Natural): pointer =
+      result = boehmRealloc(p, newSize)
       if result == nil: raiseOutOfMem()
     proc dealloc(p: pointer) = boehmDealloc(p)
 
@@ -122,8 +122,8 @@ when defined(boehmgc):
       if result == nil: raiseOutOfMem()
     proc allocShared0(size: Natural): pointer =
       result = allocShared(size)
-    proc reallocShared(p: pointer, newsize: Natural): pointer =
-      result = boehmRealloc(p, newsize)
+    proc reallocShared(p: pointer, newSize: Natural): pointer =
+      result = boehmRealloc(p, newSize)
       if result == nil: raiseOutOfMem()
     proc deallocShared(p: pointer) = boehmDealloc(p)
 
diff --git a/lib/wrappers/sqlite3.nim b/lib/wrappers/sqlite3.nim
index e47e82a74..45ccbe6c0 100644
--- a/lib/wrappers/sqlite3.nim
+++ b/lib/wrappers/sqlite3.nim
@@ -26,6 +26,12 @@ else:
   const
     Lib = "libsqlite3.so(|.0)"
 
+when defined(staticSqlite):
+  {.pragma: mylib.}
+  {.compile: "sqlite3.c".}
+else:
+  {.pragma: mylib, dynlib: Lib.}
+
 const
   SQLITE_INTEGER* = 1
   SQLITE_FLOAT* = 2
@@ -130,235 +136,235 @@ const
   SQLITE_STATIC* = nil
   SQLITE_TRANSIENT* = cast[Tbind_destructor_func](-1)
 
-proc close*(para1: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_close".}
+proc close*(para1: PSqlite3): int32{.cdecl, mylib, importc: "sqlite3_close".}
 proc exec*(para1: PSqlite3, sql: cstring, para3: Callback, para4: pointer,
-           errmsg: var cstring): int32{.cdecl, dynlib: Lib,
+           errmsg: var cstring): int32{.cdecl, mylib,
                                         importc: "sqlite3_exec".}
-proc last_insert_rowid*(para1: PSqlite3): int64{.cdecl, dynlib: Lib,
+proc last_insert_rowid*(para1: PSqlite3): int64{.cdecl, mylib,
     importc: "sqlite3_last_insert_rowid".}
-proc changes*(para1: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_changes".}
-proc total_changes*(para1: PSqlite3): int32{.cdecl, dynlib: Lib,
+proc changes*(para1: PSqlite3): int32{.cdecl, mylib, importc: "sqlite3_changes".}
+proc total_changes*(para1: PSqlite3): int32{.cdecl, mylib,
                                       importc: "sqlite3_total_changes".}
-proc interrupt*(para1: PSqlite3){.cdecl, dynlib: Lib, importc: "sqlite3_interrupt".}
-proc complete*(sql: cstring): int32{.cdecl, dynlib: Lib,
+proc interrupt*(para1: PSqlite3){.cdecl, mylib, importc: "sqlite3_interrupt".}
+proc complete*(sql: cstring): int32{.cdecl, mylib,
                                      importc: "sqlite3_complete".}
-proc complete16*(sql: pointer): int32{.cdecl, dynlib: Lib,
+proc complete16*(sql: pointer): int32{.cdecl, mylib,
                                        importc: "sqlite3_complete16".}
 proc busy_handler*(para1: PSqlite3,
                    para2: proc (para1: pointer, para2: int32): int32{.cdecl.},
-                   para3: pointer): int32{.cdecl, dynlib: Lib,
+                   para3: pointer): int32{.cdecl, mylib,
     importc: "sqlite3_busy_handler".}
-proc busy_timeout*(para1: PSqlite3, ms: int32): int32{.cdecl, dynlib: Lib,
+proc busy_timeout*(para1: PSqlite3, ms: int32): int32{.cdecl, mylib,
     importc: "sqlite3_busy_timeout".}
 proc get_table*(para1: PSqlite3, sql: cstring, resultp: var cstringArray,
                 nrow, ncolumn: var cint, errmsg: ptr cstring): int32{.cdecl,
-    dynlib: Lib, importc: "sqlite3_get_table".}
-proc free_table*(result: cstringArray){.cdecl, dynlib: Lib,
+    mylib, importc: "sqlite3_get_table".}
+proc free_table*(result: cstringArray){.cdecl, mylib,
                                         importc: "sqlite3_free_table".}
   # Todo: see how translate sqlite3_mprintf, sqlite3_vmprintf, sqlite3_snprintf
   # function sqlite3_mprintf(_para1:Pchar; args:array of const):Pchar;cdecl; external Sqlite3Lib name 'sqlite3_mprintf';
-proc mprintf*(para1: cstring): cstring{.cdecl, varargs, dynlib: Lib,
+proc mprintf*(para1: cstring): cstring{.cdecl, varargs, mylib,
                                         importc: "sqlite3_mprintf".}
   #function sqlite3_vmprintf(_para1:Pchar; _para2:va_list):Pchar;cdecl; external Sqlite3Lib name 'sqlite3_vmprintf';
-proc free*(z: cstring){.cdecl, dynlib: Lib, importc: "sqlite3_free".}
+proc free*(z: cstring){.cdecl, mylib, importc: "sqlite3_free".}
   #function sqlite3_snprintf(_para1:longint; _para2:Pchar; _para3:Pchar; args:array of const):Pchar;cdecl; external Sqlite3Lib name 'sqlite3_snprintf';
 proc snprintf*(para1: int32, para2: cstring, para3: cstring): cstring{.cdecl,
-    dynlib: Lib, varargs, importc: "sqlite3_snprintf".}
+    mylib, varargs, importc: "sqlite3_snprintf".}
 proc set_authorizer*(para1: PSqlite3, xAuth: proc (para1: pointer, para2: int32,
     para3: cstring, para4: cstring, para5: cstring, para6: cstring): int32{.
-    cdecl.}, pUserData: pointer): int32{.cdecl, dynlib: Lib,
+    cdecl.}, pUserData: pointer): int32{.cdecl, mylib,
     importc: "sqlite3_set_authorizer".}
 proc trace*(para1: PSqlite3, xTrace: proc (para1: pointer, para2: cstring){.cdecl.},
-            para3: pointer): pointer{.cdecl, dynlib: Lib,
+            para3: pointer): pointer{.cdecl, mylib,
                                       importc: "sqlite3_trace".}
 proc progress_handler*(para1: PSqlite3, para2: int32,
                        para3: proc (para1: pointer): int32{.cdecl.},
-                       para4: pointer){.cdecl, dynlib: Lib,
+                       para4: pointer){.cdecl, mylib,
                                         importc: "sqlite3_progress_handler".}
 proc commit_hook*(para1: PSqlite3, para2: proc (para1: pointer): int32{.cdecl.},
-                  para3: pointer): pointer{.cdecl, dynlib: Lib,
+                  para3: pointer): pointer{.cdecl, mylib,
     importc: "sqlite3_commit_hook".}
-proc open*(filename: cstring, ppDb: var PSqlite3): int32{.cdecl, dynlib: Lib,
+proc open*(filename: cstring, ppDb: var PSqlite3): int32{.cdecl, mylib,
     importc: "sqlite3_open".}
-proc open16*(filename: pointer, ppDb: var PSqlite3): int32{.cdecl, dynlib: Lib,
+proc open16*(filename: pointer, ppDb: var PSqlite3): int32{.cdecl, mylib,
     importc: "sqlite3_open16".}
-proc errcode*(db: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_errcode".}
-proc errmsg*(para1: PSqlite3): cstring{.cdecl, dynlib: Lib, importc: "sqlite3_errmsg".}
-proc errmsg16*(para1: PSqlite3): pointer{.cdecl, dynlib: Lib,
+proc errcode*(db: PSqlite3): int32{.cdecl, mylib, importc: "sqlite3_errcode".}
+proc errmsg*(para1: PSqlite3): cstring{.cdecl, mylib, importc: "sqlite3_errmsg".}
+proc errmsg16*(para1: PSqlite3): pointer{.cdecl, mylib,
                                    importc: "sqlite3_errmsg16".}
 proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: var PStmt,
-              pzTail: ptr cstring): int32{.cdecl, dynlib: Lib,
+              pzTail: ptr cstring): int32{.cdecl, mylib,
     importc: "sqlite3_prepare".}
 
 proc prepare_v2*(db: PSqlite3, zSql: cstring, nByte: cint, ppStmt: var PStmt,
                 pzTail: ptr cstring): cint {.
-                importc: "sqlite3_prepare_v2", cdecl, dynlib: Lib.}
+                importc: "sqlite3_prepare_v2", cdecl, mylib.}
 
 proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: var PStmt,
-                pzTail: var pointer): int32{.cdecl, dynlib: Lib,
+                pzTail: var pointer): int32{.cdecl, mylib,
     importc: "sqlite3_prepare16".}
 proc bind_blob*(para1: PStmt, para2: int32, para3: pointer, n: int32,
-                para5: Tbind_destructor_func): int32{.cdecl, dynlib: Lib,
+                para5: Tbind_destructor_func): int32{.cdecl, mylib,
     importc: "sqlite3_bind_blob".}
 proc bind_double*(para1: PStmt, para2: int32, para3: float64): int32{.cdecl,
-    dynlib: Lib, importc: "sqlite3_bind_double".}
+    mylib, importc: "sqlite3_bind_double".}
 proc bind_int*(para1: PStmt, para2: int32, para3: int32): int32{.cdecl,
-    dynlib: Lib, importc: "sqlite3_bind_int".}
+    mylib, importc: "sqlite3_bind_int".}
 proc bind_int64*(para1: PStmt, para2: int32, para3: int64): int32{.cdecl,
-    dynlib: Lib, importc: "sqlite3_bind_int64".}
-proc bind_null*(para1: PStmt, para2: int32): int32{.cdecl, dynlib: Lib,
+    mylib, importc: "sqlite3_bind_int64".}
+proc bind_null*(para1: PStmt, para2: int32): int32{.cdecl, mylib,
     importc: "sqlite3_bind_null".}
 proc bind_text*(para1: PStmt, para2: int32, para3: cstring, n: int32,
-                para5: Tbind_destructor_func): int32{.cdecl, dynlib: Lib,
+                para5: Tbind_destructor_func): int32{.cdecl, mylib,
     importc: "sqlite3_bind_text".}
 proc bind_text16*(para1: PStmt, para2: int32, para3: pointer, para4: int32,
-                  para5: Tbind_destructor_func): int32{.cdecl, dynlib: Lib,
+                  para5: Tbind_destructor_func): int32{.cdecl, mylib,
     importc: "sqlite3_bind_text16".}
   #function sqlite3_bind_value(_para1:Psqlite3_stmt; _para2:longint; _para3:Psqlite3_value):longint;cdecl; external Sqlite3Lib name 'sqlite3_bind_value';
   #These overloaded functions were introduced to allow the use of SQLITE_STATIC and SQLITE_TRANSIENT
   #It's the c world man ;-)
 proc bind_blob*(para1: PStmt, para2: int32, para3: pointer, n: int32,
-                para5: int32): int32{.cdecl, dynlib: Lib,
+                para5: int32): int32{.cdecl, mylib,
                                       importc: "sqlite3_bind_blob".}
 proc bind_text*(para1: PStmt, para2: int32, para3: cstring, n: int32,
-                para5: int32): int32{.cdecl, dynlib: Lib,
+                para5: int32): int32{.cdecl, mylib,
                                       importc: "sqlite3_bind_text".}
 proc bind_text16*(para1: PStmt, para2: int32, para3: pointer, para4: int32,
-                  para5: int32): int32{.cdecl, dynlib: Lib,
+                  para5: int32): int32{.cdecl, mylib,
                                         importc: "sqlite3_bind_text16".}
-proc bind_parameter_count*(para1: PStmt): int32{.cdecl, dynlib: Lib,
+proc bind_parameter_count*(para1: PStmt): int32{.cdecl, mylib,
     importc: "sqlite3_bind_parameter_count".}
 proc bind_parameter_name*(para1: PStmt, para2: int32): cstring{.cdecl,
-    dynlib: Lib, importc: "sqlite3_bind_parameter_name".}
+    mylib, importc: "sqlite3_bind_parameter_name".}
 proc bind_parameter_index*(para1: PStmt, zName: cstring): int32{.cdecl,
-    dynlib: Lib, importc: "sqlite3_bind_parameter_index".}
+    mylib, importc: "sqlite3_bind_parameter_index".}
 proc clear_bindings*(para1: PStmt): int32 {.cdecl,
-    dynlib: Lib, importc: "sqlite3_clear_bindings".}
-proc column_count*(PStmt: PStmt): int32{.cdecl, dynlib: Lib,
+    mylib, importc: "sqlite3_clear_bindings".}
+proc column_count*(PStmt: PStmt): int32{.cdecl, mylib,
     importc: "sqlite3_column_count".}
-proc column_name*(para1: PStmt, para2: int32): cstring{.cdecl, dynlib: Lib,
+proc column_name*(para1: PStmt, para2: int32): cstring{.cdecl, mylib,
     importc: "sqlite3_column_name".}
-proc column_table_name*(para1: PStmt; para2: int32): cstring{.cdecl, dynlib: Lib,
+proc column_table_name*(para1: PStmt; para2: int32): cstring{.cdecl, mylib,
     importc: "sqlite3_column_table_name".}
-proc column_name16*(para1: PStmt, para2: int32): pointer{.cdecl, dynlib: Lib,
+proc column_name16*(para1: PStmt, para2: int32): pointer{.cdecl, mylib,
     importc: "sqlite3_column_name16".}
-proc column_decltype*(para1: PStmt, i: int32): cstring{.cdecl, dynlib: Lib,
+proc column_decltype*(para1: PStmt, i: int32): cstring{.cdecl, mylib,
     importc: "sqlite3_column_decltype".}
 proc column_decltype16*(para1: PStmt, para2: int32): pointer{.cdecl,
-    dynlib: Lib, importc: "sqlite3_column_decltype16".}
-proc step*(para1: PStmt): int32{.cdecl, dynlib: Lib, importc: "sqlite3_step".}
-proc data_count*(PStmt: PStmt): int32{.cdecl, dynlib: Lib,
+    mylib, importc: "sqlite3_column_decltype16".}
+proc step*(para1: PStmt): int32{.cdecl, mylib, importc: "sqlite3_step".}
+proc data_count*(PStmt: PStmt): int32{.cdecl, mylib,
                                        importc: "sqlite3_data_count".}
-proc column_blob*(para1: PStmt, iCol: int32): pointer{.cdecl, dynlib: Lib,
+proc column_blob*(para1: PStmt, iCol: int32): pointer{.cdecl, mylib,
     importc: "sqlite3_column_blob".}
-proc column_bytes*(para1: PStmt, iCol: int32): int32{.cdecl, dynlib: Lib,
+proc column_bytes*(para1: PStmt, iCol: int32): int32{.cdecl, mylib,
     importc: "sqlite3_column_bytes".}
-proc column_bytes16*(para1: PStmt, iCol: int32): int32{.cdecl, dynlib: Lib,
+proc column_bytes16*(para1: PStmt, iCol: int32): int32{.cdecl, mylib,
     importc: "sqlite3_column_bytes16".}
-proc column_double*(para1: PStmt, iCol: int32): float64{.cdecl, dynlib: Lib,
+proc column_double*(para1: PStmt, iCol: int32): float64{.cdecl, mylib,
     importc: "sqlite3_column_double".}
-proc column_int*(para1: PStmt, iCol: int32): int32{.cdecl, dynlib: Lib,
+proc column_int*(para1: PStmt, iCol: int32): int32{.cdecl, mylib,
     importc: "sqlite3_column_int".}
-proc column_int64*(para1: PStmt, iCol: int32): int64{.cdecl, dynlib: Lib,
+proc column_int64*(para1: PStmt, iCol: int32): int64{.cdecl, mylib,
     importc: "sqlite3_column_int64".}
-proc column_text*(para1: PStmt, iCol: int32): cstring{.cdecl, dynlib: Lib,
+proc column_text*(para1: PStmt, iCol: int32): cstring{.cdecl, mylib,
     importc: "sqlite3_column_text".}
-proc column_text16*(para1: PStmt, iCol: int32): pointer{.cdecl, dynlib: Lib,
+proc column_text16*(para1: PStmt, iCol: int32): pointer{.cdecl, mylib,
     importc: "sqlite3_column_text16".}
-proc column_type*(para1: PStmt, iCol: int32): int32{.cdecl, dynlib: Lib,
+proc column_type*(para1: PStmt, iCol: int32): int32{.cdecl, mylib,
     importc: "sqlite3_column_type".}
-proc finalize*(PStmt: PStmt): int32{.cdecl, dynlib: Lib,
+proc finalize*(PStmt: PStmt): int32{.cdecl, mylib,
                                      importc: "sqlite3_finalize".}
-proc reset*(PStmt: PStmt): int32{.cdecl, dynlib: Lib, importc: "sqlite3_reset".}
+proc reset*(PStmt: PStmt): int32{.cdecl, mylib, importc: "sqlite3_reset".}
 proc create_function*(para1: PSqlite3, zFunctionName: cstring, nArg: int32,
                       eTextRep: int32, para5: pointer,
                       xFunc: Create_function_func_func,
                       xStep: Create_function_step_func,
                       xFinal: Create_function_final_func): int32{.cdecl,
-    dynlib: Lib, importc: "sqlite3_create_function".}
+    mylib, importc: "sqlite3_create_function".}
 proc create_function16*(para1: PSqlite3, zFunctionName: pointer, nArg: int32,
                         eTextRep: int32, para5: pointer,
                         xFunc: Create_function_func_func,
                         xStep: Create_function_step_func,
                         xFinal: Create_function_final_func): int32{.cdecl,
-    dynlib: Lib, importc: "sqlite3_create_function16".}
-proc aggregate_count*(para1: Pcontext): int32{.cdecl, dynlib: Lib,
+    mylib, importc: "sqlite3_create_function16".}
+proc aggregate_count*(para1: Pcontext): int32{.cdecl, mylib,
     importc: "sqlite3_aggregate_count".}
-proc value_blob*(para1: PValue): pointer{.cdecl, dynlib: Lib,
+proc value_blob*(para1: PValue): pointer{.cdecl, mylib,
     importc: "sqlite3_value_blob".}
-proc value_bytes*(para1: PValue): int32{.cdecl, dynlib: Lib,
+proc value_bytes*(para1: PValue): int32{.cdecl, mylib,
     importc: "sqlite3_value_bytes".}
-proc value_bytes16*(para1: PValue): int32{.cdecl, dynlib: Lib,
+proc value_bytes16*(para1: PValue): int32{.cdecl, mylib,
     importc: "sqlite3_value_bytes16".}
-proc value_double*(para1: PValue): float64{.cdecl, dynlib: Lib,
+proc value_double*(para1: PValue): float64{.cdecl, mylib,
     importc: "sqlite3_value_double".}
-proc value_int*(para1: PValue): int32{.cdecl, dynlib: Lib,
+proc value_int*(para1: PValue): int32{.cdecl, mylib,
                                        importc: "sqlite3_value_int".}
-proc value_int64*(para1: PValue): int64{.cdecl, dynlib: Lib,
+proc value_int64*(para1: PValue): int64{.cdecl, mylib,
     importc: "sqlite3_value_int64".}
-proc value_text*(para1: PValue): cstring{.cdecl, dynlib: Lib,
+proc value_text*(para1: PValue): cstring{.cdecl, mylib,
     importc: "sqlite3_value_text".}
-proc value_text16*(para1: PValue): pointer{.cdecl, dynlib: Lib,
+proc value_text16*(para1: PValue): pointer{.cdecl, mylib,
     importc: "sqlite3_value_text16".}
-proc value_text16le*(para1: PValue): pointer{.cdecl, dynlib: Lib,
+proc value_text16le*(para1: PValue): pointer{.cdecl, mylib,
     importc: "sqlite3_value_text16le".}
-proc value_text16be*(para1: PValue): pointer{.cdecl, dynlib: Lib,
+proc value_text16be*(para1: PValue): pointer{.cdecl, mylib,
     importc: "sqlite3_value_text16be".}
-proc value_type*(para1: PValue): int32{.cdecl, dynlib: Lib,
+proc value_type*(para1: PValue): int32{.cdecl, mylib,
                                         importc: "sqlite3_value_type".}
 proc aggregate_context*(para1: Pcontext, nBytes: int32): pointer{.cdecl,
-    dynlib: Lib, importc: "sqlite3_aggregate_context".}
-proc user_data*(para1: Pcontext): pointer{.cdecl, dynlib: Lib,
+    mylib, importc: "sqlite3_aggregate_context".}
+proc user_data*(para1: Pcontext): pointer{.cdecl, mylib,
     importc: "sqlite3_user_data".}
-proc get_auxdata*(para1: Pcontext, para2: int32): pointer{.cdecl, dynlib: Lib,
+proc get_auxdata*(para1: Pcontext, para2: int32): pointer{.cdecl, mylib,
     importc: "sqlite3_get_auxdata".}
 proc set_auxdata*(para1: Pcontext, para2: int32, para3: pointer,
-                  para4: proc (para1: pointer){.cdecl.}){.cdecl, dynlib: Lib,
+                  para4: proc (para1: pointer){.cdecl.}){.cdecl, mylib,
     importc: "sqlite3_set_auxdata".}
 proc result_blob*(para1: Pcontext, para2: pointer, para3: int32,
-                  para4: Result_func){.cdecl, dynlib: Lib,
+                  para4: Result_func){.cdecl, mylib,
                                         importc: "sqlite3_result_blob".}
-proc result_double*(para1: Pcontext, para2: float64){.cdecl, dynlib: Lib,
+proc result_double*(para1: Pcontext, para2: float64){.cdecl, mylib,
     importc: "sqlite3_result_double".}
 proc result_error*(para1: Pcontext, para2: cstring, para3: int32){.cdecl,
-    dynlib: Lib, importc: "sqlite3_result_error".}
+    mylib, importc: "sqlite3_result_error".}
 proc result_error16*(para1: Pcontext, para2: pointer, para3: int32){.cdecl,
-    dynlib: Lib, importc: "sqlite3_result_error16".}
-proc result_int*(para1: Pcontext, para2: int32){.cdecl, dynlib: Lib,
+    mylib, importc: "sqlite3_result_error16".}
+proc result_int*(para1: Pcontext, para2: int32){.cdecl, mylib,
     importc: "sqlite3_result_int".}
-proc result_int64*(para1: Pcontext, para2: int64){.cdecl, dynlib: Lib,
+proc result_int64*(para1: Pcontext, para2: int64){.cdecl, mylib,
     importc: "sqlite3_result_int64".}
-proc result_null*(para1: Pcontext){.cdecl, dynlib: Lib,
+proc result_null*(para1: Pcontext){.cdecl, mylib,
                                     importc: "sqlite3_result_null".}
 proc result_text*(para1: Pcontext, para2: cstring, para3: int32,
-                  para4: Result_func){.cdecl, dynlib: Lib,
+                  para4: Result_func){.cdecl, mylib,
                                         importc: "sqlite3_result_text".}
 proc result_text16*(para1: Pcontext, para2: pointer, para3: int32,
-                    para4: Result_func){.cdecl, dynlib: Lib,
+                    para4: Result_func){.cdecl, mylib,
     importc: "sqlite3_result_text16".}
 proc result_text16le*(para1: Pcontext, para2: pointer, para3: int32,
-                      para4: Result_func){.cdecl, dynlib: Lib,
+                      para4: Result_func){.cdecl, mylib,
     importc: "sqlite3_result_text16le".}
 proc result_text16be*(para1: Pcontext, para2: pointer, para3: int32,
-                      para4: Result_func){.cdecl, dynlib: Lib,
+                      para4: Result_func){.cdecl, mylib,
     importc: "sqlite3_result_text16be".}
-proc result_value*(para1: Pcontext, para2: PValue){.cdecl, dynlib: Lib,
+proc result_value*(para1: Pcontext, para2: PValue){.cdecl, mylib,
     importc: "sqlite3_result_value".}
 proc create_collation*(para1: PSqlite3, zName: cstring, eTextRep: int32,
                        para4: pointer, xCompare: Create_collation_func): int32{.
-    cdecl, dynlib: Lib, importc: "sqlite3_create_collation".}
+    cdecl, mylib, importc: "sqlite3_create_collation".}
 proc create_collation16*(para1: PSqlite3, zName: cstring, eTextRep: int32,
                          para4: pointer, xCompare: Create_collation_func): int32{.
-    cdecl, dynlib: Lib, importc: "sqlite3_create_collation16".}
+    cdecl, mylib, importc: "sqlite3_create_collation16".}
 proc collation_needed*(para1: PSqlite3, para2: pointer, para3: Collation_needed_func): int32{.
-    cdecl, dynlib: Lib, importc: "sqlite3_collation_needed".}
+    cdecl, mylib, importc: "sqlite3_collation_needed".}
 proc collation_needed16*(para1: PSqlite3, para2: pointer, para3: Collation_needed_func): int32{.
-    cdecl, dynlib: Lib, importc: "sqlite3_collation_needed16".}
-proc libversion*(): cstring{.cdecl, dynlib: Lib, importc: "sqlite3_libversion".}
+    cdecl, mylib, importc: "sqlite3_collation_needed16".}
+proc libversion*(): cstring{.cdecl, mylib, importc: "sqlite3_libversion".}
   #Alias for allowing better code portability (win32 is not working with external variables)
-proc version*(): cstring{.cdecl, dynlib: Lib, importc: "sqlite3_libversion".}
+proc version*(): cstring{.cdecl, mylib, importc: "sqlite3_libversion".}
   # Not published functions
-proc libversion_number*(): int32{.cdecl, dynlib: Lib,
+proc libversion_number*(): int32{.cdecl, mylib,
                                   importc: "sqlite3_libversion_number".}
   #function sqlite3_key(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external Sqlite3Lib name 'sqlite3_key';
   #function sqlite3_rekey(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external Sqlite3Lib name 'sqlite3_rekey';
diff --git a/nimsuggest/tests/ttemplate_highlight.nim b/nimsuggest/tests/disabled_ttemplate_highlight.nim
index 2cbac3be5..2cbac3be5 100644
--- a/nimsuggest/tests/ttemplate_highlight.nim
+++ b/nimsuggest/tests/disabled_ttemplate_highlight.nim
diff --git a/testament/categories.nim b/testament/categories.nim
index d5cf79e3a..6e885966e 100644
--- a/testament/categories.nim
+++ b/testament/categories.nim
@@ -658,7 +658,8 @@ proc processCategory(r: var TResults, cat: Category,
       compileRodFiles(r, cat, options)
       runRodFiles(r, cat, options)
   of "ic":
-    icTests(r, testsDir, cat, options)
+    when false:
+      icTests(r, testsDir, cat, options)
   of "js":
     # only run the JS tests on Windows or Linux because Travis is bad
     # and other OSes like Haiku might lack nodejs:
diff --git a/testament/important_packages.nim b/testament/important_packages.nim
index 6317139d1..0b21547c3 100644
--- a/testament/important_packages.nim
+++ b/testament/important_packages.nim
@@ -7,7 +7,7 @@ var packages*: seq[tuple[name, cmd: string; hasDeps: bool; url: string]] = @[]
 
 pkg "argparse"
 pkg "arraymancer", "nim c -r src/arraymancer.nim", true
-pkg "ast_pattern_matching", "nim c -r --useVersion=0.19 tests/test1.nim"
+pkg "ast_pattern_matching", "nim c -r --oldgensym:on tests/test1.nim"
 pkg "bigints"
 pkg "binaryheap", "nim c -r binaryheap.nim"
 pkg "blscurve", "", true
@@ -62,7 +62,7 @@ pkg "npeg"
 pkg "ormin", "nim c -o:orminn ormin.nim", true
 pkg "parsetoml"
 pkg "patty"
-pkg "plotly", "nim c --useVersion:0.19 examples/all.nim", true
+pkg "plotly", "nim c --oldgensym:on examples/all.nim", true
 pkg "protobuf", "nim c -o:protobuff -r src/protobuf.nim", true
 pkg "regex", "nim c src/regex", true
 pkg "result", "nim c -r result.nim"
@@ -72,7 +72,7 @@ pkg "sdl2_nim", "nim c -r sdl2/sdl.nim"
 pkg "snip", "", false, "https://github.com/genotrance/snip"
 pkg "stint", "nim c -o:stintt -r stint.nim"
 pkg "strunicode", "nim c -r src/strunicode.nim", true
-pkg "telebot", "nim c -o:tbot --useVersion:0.19 -r telebot.nim", true
+pkg "telebot", "nim c -o:tbot --oldgensym:on -r telebot.nim", true
 pkg "tiny_sqlite"
 pkg "unicodedb"
 pkg "unicodeplus", "", true
diff --git a/testament/testament.nim b/testament/testament.nim
index 5d0213ce5..41dca39ae 100644
--- a/testament/testament.nim
+++ b/testament/testament.nim
@@ -332,8 +332,7 @@ proc generatedFile(test: TTest, target: TTarget): string =
   else:
     let (_, name, _) = test.name.splitFile
     let ext = targetToExt[target]
-    result = nimcacheDir(test.name, test.options, target) /
-              name.replace("_", "__").changeFileExt(ext)
+    result = nimcacheDir(test.name, test.options, target) / name.changeFileExt(ext)
 
 proc needsCodegenCheck(spec: TSpec): bool =
   result = spec.maxCodeSize > 0 or spec.ccodeCheck.len > 0
diff --git a/tests/arithm/tarithm.nim b/tests/arithm/tarithm.nim
index a79f897a7..4625a5ecf 100644
--- a/tests/arithm/tarithm.nim
+++ b/tests/arithm/tarithm.nim
@@ -54,6 +54,7 @@ block tcast:
   crossCheck(uint16, uint16.high + 5'u16)
   crossCheck(uint32, uint32.high + 5'u32)
   crossCheck(uint64, 0xFFFFFFFFFFFFFFFF'u64 + 5'u64)
+  crossCheck(uint64, uint64.high + 5'u64)
 
   doAssert $sub1(0'u8) == "255"
   doAssert $sub1(0'u16) == "65535"
diff --git a/tests/cpp/mexportc.nim b/tests/cpp/mexportc.nim
new file mode 100644
index 000000000..dee51f157
--- /dev/null
+++ b/tests/cpp/mexportc.nim
@@ -0,0 +1,9 @@
+{.used.} # ideally, would not be needed
+
+var fun0 {.exportc.} = 10
+proc fun1() {.exportc.} = discard
+proc fun2() {.exportc: "$1".} = discard
+proc fun3() {.exportc: "fun3Bis".} = discard
+
+when defined cpp:
+  proc funx1() {.exportcpp.} = discard
diff --git a/tests/cpp/texportc.nim b/tests/cpp/texportc.nim
new file mode 100644
index 000000000..3a2fa8748
--- /dev/null
+++ b/tests/cpp/texportc.nim
@@ -0,0 +1,22 @@
+discard """
+  targets: "c cpp"
+"""
+
+var fun0 {.importc.}: int
+proc fun1() {.importc.}
+proc fun2() {.importc: "$1".}
+proc fun3() {.importc: "fun3Bis".}
+
+when defined cpp:
+  # proc funx1() {.importcpp.} # this does not work yet
+  proc funx1() {.importc: "_Z5funx1v".}
+
+doAssert fun0 == 10
+fun1()
+fun2()
+fun3()
+
+when defined cpp:
+  funx1()
+
+import ./mexportc
diff --git a/tests/errmsgs/tnnodeadd.nim b/tests/errmsgs/tnnodeadd.nim
new file mode 100644
index 000000000..61921883e
--- /dev/null
+++ b/tests/errmsgs/tnnodeadd.nim
@@ -0,0 +1,8 @@
+discard """
+  errormsg: "cannot add to node kind: nnkInt8Lit"
+  line: 7
+"""
+import macros
+macro t(x: untyped): untyped =
+  x.add(newEmptyNode())
+t(38'i8)
diff --git a/tests/errmsgs/tnnodeindex.nim b/tests/errmsgs/tnnodeindex.nim
new file mode 100644
index 000000000..5e37e7977
--- /dev/null
+++ b/tests/errmsgs/tnnodeindex.nim
@@ -0,0 +1,8 @@
+discard """
+  errormsg: "index 5 not in 0 .. 2"
+  line: 7
+"""
+import macros
+macro t(x: untyped): untyped =
+  result = x[5]
+t([1, 2, 3])
diff --git a/tests/errmsgs/tnnodeindexkind.nim b/tests/errmsgs/tnnodeindexkind.nim
new file mode 100644
index 000000000..9ea045e66
--- /dev/null
+++ b/tests/errmsgs/tnnodeindexkind.nim
@@ -0,0 +1,8 @@
+discard """
+  errormsg: "cannot set child of node kind: nnkStrLit"
+  line: 7
+"""
+import macros
+macro t(x: untyped): untyped =
+  x[0] = newEmptyNode()
+t("abc")
diff --git a/tests/gc/gcbench.nim b/tests/gc/gcbench.nim
index fc5d6864f..335e44095 100644
--- a/tests/gc/gcbench.nim
+++ b/tests/gc/gcbench.nim
@@ -97,8 +97,8 @@ proc makeTree(iDepth: int): PNode =
     return newNode(makeTree(iDepth-1), makeTree(iDepth-1))
 
 proc printDiagnostics() =
-  echo("Total memory available: " & $getTotalMem() & " bytes")
-  echo("Free memory: " & $getFreeMem() & " bytes")
+  echo("Total memory available: " & formatSize(getTotalMem()) & " bytes")
+  echo("Free memory: " & formatSize(getFreeMem()) & " bytes")
 
 proc timeConstruction(depth: int) =
   var
diff --git a/tests/gensym/tgensymgeneric.nim b/tests/gensym/tgensymgeneric.nim
index 9963ba808..c17a0715f 100644
--- a/tests/gensym/tgensymgeneric.nim
+++ b/tests/gensym/tgensymgeneric.nim
@@ -40,15 +40,15 @@ doAssert y.x == "abc"
 import macros
 
 static:
-  let sym1   = genSym()
-  let sym2   = genSym()
-  let sym3   = sym1
+  let sym1 = genSym()
+  let sym2 = genSym()
+  let sym3 = sym1
   let nimsym = sym1.symbol
-  doAssert sym1        == sym1
-  doAssert sym2        != sym3
+  doAssert sym1 == sym1
+  doAssert sym2 != sym3
   doAssert sym2.symbol != sym3.symbol
-  doAssert sym3        == sym1
+  doAssert sym3 == sym1
   doAssert sym1.symbol == sym1.symbol
-  doAssert nimsym      == nimsym
+  doAssert nimsym == nimsym
 
 echo "true"
diff --git a/tests/misc/tlowhigh.nim b/tests/misc/tlowhigh.nim
index 76f298a4a..6ae871255 100644
--- a/tests/misc/tlowhigh.nim
+++ b/tests/misc/tlowhigh.nim
@@ -1,5 +1,12 @@
 discard """
     action: run
+    output: '''
+18446744073709551615
+9223372036854775807
+4294967295
+0
+0
+'''
 """
 
 var x: range[-1'f32..1'f32]
@@ -16,3 +23,10 @@ doAssert y.type.high == 1'f64
 # bug #11972
 var num: uint8
 doAssert num.high.float == 255.0
+
+echo high(uint64)
+echo high(int64)
+echo high(uint32)
+
+echo low(uint64)
+echo low(uint32)
diff --git a/tests/niminaction/Chapter8/sdl/sdl.nim b/tests/niminaction/Chapter8/sdl/sdl.nim
index a1b30281b..14fa59c85 100644
--- a/tests/niminaction/Chapter8/sdl/sdl.nim
+++ b/tests/niminaction/Chapter8/sdl/sdl.nim
@@ -1,9 +1,13 @@
 when defined(Windows):
   const libName* = "SDL2.dll"
-elif defined(Linux):
+elif defined(Linux) or defined(freebsd):
   const libName* = "libSDL2.so"
 elif defined(MacOsX):
   const libName* = "libSDL2.dylib"
+elif defined(openbsd):
+  const libName* = "libSDL2.so.0.6"
+else:
+  {.error: "SDL library name not set for this platform".}
 
 type
   SdlWindow = object
diff --git a/tests/range/tcompiletime_range_checks.nim b/tests/range/tcompiletime_range_checks.nim
new file mode 100644
index 000000000..37095e0b7
--- /dev/null
+++ b/tests/range/tcompiletime_range_checks.nim
@@ -0,0 +1,52 @@
+discard """
+  cmd: "nim check --hint[Processing]:off --hint[Conf]:off $file"
+  errormsg: "18446744073709551615 can't be converted to int8"
+  nimout: '''tcompiletime_range_checks.nim(36, 21) Error: 2147483648 can't be converted to int32
+tcompiletime_range_checks.nim(37, 23) Error: -1 can't be converted to uint64
+tcompiletime_range_checks.nim(38, 34) Error: 255 can't be converted to FullNegativeRange
+tcompiletime_range_checks.nim(39, 34) Error: 18446744073709551615 can't be converted to HalfNegativeRange
+tcompiletime_range_checks.nim(40, 34) Error: 300 can't be converted to FullPositiveRange
+tcompiletime_range_checks.nim(41, 30) Error: 101 can't be converted to UnsignedRange
+tcompiletime_range_checks.nim(42, 32) Error: -9223372036854775808 can't be converted to SemiOutOfBounds
+tcompiletime_range_checks.nim(44, 22) Error: nan can't be converted to int32
+tcompiletime_range_checks.nim(46, 23) Error: 1e+100 can't be converted to uint64
+tcompiletime_range_checks.nim(49, 22) Error: 18446744073709551615 can't be converted to int64
+tcompiletime_range_checks.nim(50, 22) Error: 18446744073709551615 can't be converted to int32
+tcompiletime_range_checks.nim(51, 22) Error: 18446744073709551615 can't be converted to int16
+tcompiletime_range_checks.nim(52, 21) Error: 18446744073709551615 can't be converted to int8
+  '''
+"""
+
+type
+  UnsignedRange* = range[0'u64 .. 100'u64]
+  SemiOutOfBounds* = range[0x7ffffffffffffe00'u64 .. 0x8000000000000100'u64]
+  FullOutOfBounds* = range[0x8000000000000000'u64 .. 0x8000000000000200'u64]
+
+  FullNegativeRange* = range[-200 .. -100]
+  HalfNegativeRange* = range[-50 .. 50]
+  FullPositiveRange* = range[100 .. 200]
+
+let acceptA* = int32(0x7fffffff'i64)
+let acceptB* = (uint64(0'i64))
+let acceptD* = (HalfNegativeRange(25'u64))
+let acceptE* = (UnsignedRange(50'u64))
+let acceptF* = (SemiOutOfBounds(0x7ffffffffffffe00'i64))
+let acceptH* = (SemiOutOfBounds(0x8000000000000000'u64))
+
+let rejectA* = int32(0x80000000'i64)
+let rejectB* = (uint64(-1'i64))
+let rejectC* = (FullNegativeRange(0xff'u32))
+let rejectD* = (HalfNegativeRange(0xffffffffffffffff'u64)) # internal `intVal` is `-1` which would be in range.
+let rejectE* = (FullPositiveRange(300'u64))
+let rejectF* = (UnsignedRange(101'u64))
+let rejectG* = (SemiOutOfBounds(0x8000000000000000'i64))  #
+
+let rejectH* = (int32(NaN))
+let rejectI* = (int64(1e100))
+let rejectJ* = (uint64(1e100))
+
+# removed cross checks from tarithm.nim
+let rejectK* = (int64(0xFFFFFFFFFFFFFFFF'u64))
+let rejectL* = (int32(0xFFFFFFFFFFFFFFFF'u64))
+let rejectM* = (int16(0xFFFFFFFFFFFFFFFF'u64))
+let rejectN* = (int8(0xFFFFFFFFFFFFFFFF'u64))
diff --git a/tests/stdlib/tbitops.nim b/tests/stdlib/tbitops.nim
index b2393b755..e4461345e 100644
--- a/tests/stdlib/tbitops.nim
+++ b/tests/stdlib/tbitops.nim
@@ -211,15 +211,15 @@ proc main() =
 
     proc testReverseBitsPerType(x, reversed: uint64) =
       doAssert reverseBits(x) == reversed
-      doAssert reverseBits(uint32(x)) == uint32(reversed shr 32)
-      doAssert reverseBits(uint32(x shr 16)) == uint32(reversed shr 16)
-      doAssert reverseBits(uint16(x)) == uint16(reversed shr 48)
-      doAssert reverseBits(uint8(x)) == uint8(reversed shr 56)
+      doAssert reverseBits(cast[uint32](x)) == cast[uint32](reversed shr 32)
+      doAssert reverseBits(cast[uint32](x shr 16)) == cast[uint32](reversed shr 16)
+      doAssert reverseBits(cast[uint16](x)) == cast[uint16](reversed shr 48)
+      doAssert reverseBits(cast[uint8](x)) == cast[uint8](reversed shr 56)
 
       testReverseBitsInvo(x)
-      testReverseBitsInvo(uint32(x))
-      testReverseBitsInvo(uint16(x))
-      testReverseBitsInvo(uint8(x))
+      testReverseBitsInvo(cast[uint32](x))
+      testReverseBitsInvo(cast[uint16](x))
+      testReverseBitsInvo(cast[uint8](x))
 
     proc testReverseBitsRefl(x, reversed: uint64) =
       testReverseBitsPerType(x, reversed)
diff --git a/tests/stdlib/thtmlparser.nim b/tests/stdlib/thtmlparser.nim
index 0457585d0..ccf2f6202 100644
--- a/tests/stdlib/thtmlparser.nim
+++ b/tests/stdlib/thtmlparser.nim
@@ -2,6 +2,9 @@ discard """
   output: '''
 @[]
 true
+https://example.com/test?format=jpg&name=orig##
+https://example.com/test?format=jpg&name=orig##text
+https://example.com/test?format=jpg##text
 '''
 """
 import htmlparser
@@ -136,3 +139,20 @@ block t6154:
   doAssert ps[6].attr("quux") == ""
   doAssert ps[6].attr("whatever") == ""
   doassert ps[6].len == 0
+
+# bug #11713, #1034
+var content = """
+# with &
+<img src="https://example.com/test?format=jpg&name=orig" alt="">
+<img src="https://example.com/test?format=jpg&name=orig" alt="text">
+
+# without &
+<img src="https://example.com/test?format=jpg" alt="text">
+"""
+
+var
+  stream = newStringStream(content)
+  body = parseHtml(stream)
+
+for y in body.findAll("img"):
+  echo y.attr("src"), "##", y.attr("alt")
diff --git a/tests/template/mtempl5.nim b/tests/template/mtempl5.nim
index 3c2881764..2cc6f91bc 100644
--- a/tests/template/mtempl5.nim
+++ b/tests/template/mtempl5.nim
@@ -7,4 +7,18 @@ template templ*(): int =
   bind gx, gy
   gx + gy
 
+import json
+
+const
+  codeField = "foobar"
+  messageField = "more"
+
+template trap*(path: string, body: untyped): untyped =
+  #bind codeField, messageField
+  try:
+    body
+  except:
+    let msg = getCurrentExceptionMsg()
+    #debug "Error occurred within RPC ", path = path, errorMessage = msg
+    result = %*{codeField: "SERVER_ERROR", messageField: msg}
 
diff --git a/tests/template/template_issues.nim b/tests/template/template_issues.nim
index b7dd2a1a7..e56d44480 100644
--- a/tests/template/template_issues.nim
+++ b/tests/template/template_issues.nim
@@ -7,6 +7,7 @@ a
 hi
 Hello, World!
 (e: 42)
+hey
 '''
 """
 
@@ -235,3 +236,12 @@ var
   x = X.fails(42)
 
 echo x
+
+import mtempl5
+
+
+proc foo(): auto =
+  trap "foo":
+    echo "hey"
+
+discard foo()
diff --git a/tests/template/tparams_gensymed.nim b/tests/template/tparams_gensymed.nim
index fe5608add..a35d878d5 100644
--- a/tests/template/tparams_gensymed.nim
+++ b/tests/template/tparams_gensymed.nim
@@ -14,6 +14,7 @@ wth
 1
 0
 (total: 6)
+S1
 '''
 """
 # bug #1915
@@ -164,3 +165,33 @@ template baz(): untyped =
   echo (total: bar2(3))
 
 baz()
+
+# bug #12121
+macro state_machine_enum(states: varargs[untyped]) =
+  result = nnkTypeSection.newTree(
+    nnkTypeDef.newTree(
+      nnkPragmaExpr.newTree(ident("State"), nnkPragma.newTree(ident("pure"))),
+      newEmptyNode(),
+      nnkEnumTy.newTree(newEmptyNode())
+    )
+  )
+
+  for s in states:
+    expectKind(s, nnkIdent)
+    result[0][2].add s
+
+template mystate_machine(body: untyped) =
+  state_machine_enum(S1, S2, S3)
+  var state_stack: seq[State]
+  template state_current(): State {.inject, used.} =
+    state_stack[^1]
+  template state_push(state_name) {.inject, used.} =
+    state_stack.add State.state_name
+  template state_pop(n = 1) {.inject, used.} =
+    state_stack.setLen(state_stack.len - n)
+  body
+
+mystate_machine:
+  state_push(S1)
+  echo state_current()
+  state_pop()
diff --git a/tests/vm/tcompiletimetable.nim b/tests/vm/tcompiletimetable.nim
index e78c06536..ece2ddfe9 100644
--- a/tests/vm/tcompiletimetable.nim
+++ b/tests/vm/tcompiletimetable.nim
@@ -3,7 +3,10 @@ discard """
 3
 4:2
 Got Hi
-Got Hey'''
+Got Hey
+a
+b
+c'''
 """
 
 # bug #404
@@ -47,3 +50,9 @@ addStuff("Hey"): echo "Hey"
 addStuff("Hi"): echo "Hi"
 dump()
 
+# ensure .compileTime vars can be used at runtime:
+import macros
+
+var xzzzz {.compileTime.}: array[3, string] = ["a", "b", "c"]
+
+for i in 0..high(xzzzz): echo xzzzz[i]
diff --git a/tests/vm/ttouintconv.nim b/tests/vm/ttouintconv.nim
index 403de8f41..ff2187a36 100644
--- a/tests/vm/ttouintconv.nim
+++ b/tests/vm/ttouintconv.nim
@@ -69,8 +69,8 @@ macro foo2() =
   echo zz
 
   var ww = -9
-  var vv = ww.uint
-  var kk = vv.uint32
+  var vv = cast[uint](ww)
+  var kk = cast[uint32](vv)
   echo kk
 
 foo()
diff --git a/tests/vm/tzero_extend.nim b/tests/vm/tzero_extend.nim
index 76aa9ee67..1fed5d419 100644
--- a/tests/vm/tzero_extend.nim
+++ b/tests/vm/tzero_extend.nim
@@ -18,9 +18,9 @@ proc get_values(): (seq[int8], seq[int16], seq[int32]) =
     let i32 = -(1'i64 shl 33) + offset
 
     # higher bits are masked. these should be exactly equal to offset.
-    result[0].add cast[int8 ](uint8 cast[uint64](i8 ))
-    result[1].add cast[int16](uint16 cast[uint64](i16))
-    result[2].add cast[int32](uint32 cast[uint64](i32))
+    result[0].add cast[int8](cast[uint64](i8))
+    result[1].add cast[int16](cast[uint64](i16))
+    result[2].add cast[int32](cast[uint64](i32))
 
 
 # these values this computed by VM