summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2021-02-17 00:32:36 -0800
committerGitHub <noreply@github.com>2021-02-17 09:32:36 +0100
commitb9994925f5051a55bb13bd3115d60c92c52c3c09 (patch)
tree944f2d01d894afbffb4f4a561837f2b90744743a
parente463a67c74801da832e8659065c162b37f549d64 (diff)
downloadNim-b9994925f5051a55bb13bd3115d60c92c52c3c09.tar.gz
remove all uses of condsyms symbols defined prior to bootstrap nim 0.20.0 (#16918)
* nimNoArrayToCstringConversion deadcode
* nimbabel deadcode
* nimHasalignOf deadcode
* nimvarargstyped deadcode
* nimhygiene deadcode
* nimNewTypedesc deadcode
* nimlocks deadcode
* nimHasCppDefine deadcode
* nimHasRunnableExamples deadcode
* nimHasNilChecks deadcode
* nimSymKind deadcode
* minor macros refactoring
* nimVmEqIdent deadcode
* nimNoNil deadcode
* nimNoZeroTerminator deadcode
* nimHasSymOwnerInMacro deadcode
* nimVmExportFixed deadcode
* nimNewRuntime deadcode
* nimAshr deadcode
* nimUncheckedArrayTyp deadcode
* nimHasTypeof deadcode
* nimErrorProcCanHaveBody deadcode
* nimHasHotCodeReloading deadcode
* nimHasSignatureHashInMacro deadcode
* nimHasDefault deadcode
* nimMacrosSizealignof deadcode
-rw-r--r--compiler/ccgexprs.nim11
-rw-r--r--compiler/ccgmerge.nim3
-rw-r--r--compiler/condsyms.nim94
-rw-r--r--config/config.nims5
-rw-r--r--config/nim.cfg16
-rw-r--r--lib/core/macros.nim185
-rw-r--r--lib/impure/re.nim3
-rw-r--r--lib/pure/bitops.nim589
-rw-r--r--lib/pure/collections/hashcommon.nim5
-rw-r--r--lib/pure/collections/lists.nim3
-rw-r--r--lib/pure/collections/sequtils.nim24
-rw-r--r--lib/pure/collections/sets.nim3
-rw-r--r--lib/pure/os.nim7
-rw-r--r--lib/pure/pegs.nim3
-rw-r--r--lib/pure/strutils.nim15
-rw-r--r--lib/system.nim352
-rw-r--r--lib/system/ansi_c.nim2
-rw-r--r--lib/system/arithmetics.nim40
-rw-r--r--lib/system/comparisons.nim12
-rw-r--r--lib/system/dyncalls.nim5
-rw-r--r--lib/system/excpt.nim9
-rw-r--r--lib/system/inclrtl.nim5
-rw-r--r--lib/system/memory.nim3
-rw-r--r--lib/system/repr.nim11
-rw-r--r--lib/system/strmantle.nim6
-rw-r--r--testament/specs.nim3
-rw-r--r--tests/destructor/t7346.nim3
27 files changed, 619 insertions, 798 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 938df2968..e3cc93d4b 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -997,14 +997,9 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
   if ty.kind in {tyRef, tyPtr}:
     ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check:
   if optBoundsCheck in p.options:
-    if ty.kind == tyString and not defined(nimNoZeroTerminator):
-      linefmt(p, cpsStmts,
-              "if ((NU)($1) > (NU)$2){ #raiseIndexError2($1,$2); $3}$n",
-              [rdLoc(b), lenExpr(p, a), raiseInstr(p)])
-    else:
-      linefmt(p, cpsStmts,
-              "if ((NU)($1) >= (NU)$2){ #raiseIndexError2($1,$2-1); $3}$n",
-              [rdLoc(b), lenExpr(p, a), raiseInstr(p)])
+    linefmt(p, cpsStmts,
+            "if ((NU)($1) >= (NU)$2){ #raiseIndexError2($1,$2-1); $3}$n",
+            [rdLoc(b), lenExpr(p, a), raiseInstr(p)])
   if d.k == locNone: d.storage = OnHeap
   if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
     a.r = ropecg(p.module, "(*$1)", [a.r])
diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim
index 40833a64e..c7d19da7a 100644
--- a/compiler/ccgmerge.nim
+++ b/compiler/ccgmerge.nim
@@ -218,9 +218,6 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) =
       m.flags = cast[set[CodegenFlag]](decodeVInt(L.buf, L.bufpos) != 0)
     else: doAssert(false, "ccgmerge: unknown key: " & k)
 
-when not defined(nimhygiene):
-  {.pragma: inject.}
-
 template withCFile(cfilename: AbsoluteFile, body: untyped) =
   var s = llStreamOpen(cfilename, fmRead)
   if s == nil: return
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index df216fb45..45cc55e94 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -34,55 +34,57 @@ proc countDefinedSymbols*(symbols: StringTableRef): int =
 proc initDefines*(symbols: StringTableRef) =
   # for bootstrapping purposes and old code:
   template defineSymbol(s) = symbols.defineSymbol(s)
-  defineSymbol("nimhygiene")
-  defineSymbol("niminheritable")
-  defineSymbol("nimmixin")
-  defineSymbol("nimeffects")
-  defineSymbol("nimbabel")
-  defineSymbol("nimcomputedgoto")
-  defineSymbol("nimunion")
-  defineSymbol("nimnewshared")
-  defineSymbol("nimNewTypedesc")
-  defineSymbol("nimrequiresnimframe")
-  defineSymbol("nimparsebiggestfloatmagic")
-  defineSymbol("nimalias")
-  defineSymbol("nimlocks")
-  defineSymbol("nimnode")
-  defineSymbol("nimvarargstyped")
-  defineSymbol("nimtypedescfixed")
-  defineSymbol("nimKnowsNimvm")
-  defineSymbol("nimArrIdx")
-  defineSymbol("nimHasalignOf")
-  defineSymbol("nimDistros")
-  defineSymbol("nimHasCppDefine")
-  defineSymbol("nimGenericInOutFlags")
-  when false: defineSymbol("nimHasOpt")
-  defineSymbol("nimNoArrayToCstringConversion")
-  defineSymbol("nimHasRunnableExamples")
-  defineSymbol("nimNewDot")
-  defineSymbol("nimHasNilChecks")
-  defineSymbol("nimSymKind")
-  defineSymbol("nimVmEqIdent")
-  defineSymbol("nimNoNil")
-  defineSymbol("nimNoZeroTerminator")
-  defineSymbol("nimNotNil")
-  defineSymbol("nimVmExportFixed")
-  defineSymbol("nimHasSymOwnerInMacro")
-  defineSymbol("nimNewRuntime")
-  defineSymbol("nimIncrSeqV3")
-  defineSymbol("nimAshr")
+  defineSymbol("nimhygiene") # deadcode
+  defineSymbol("niminheritable") # deadcode
+  defineSymbol("nimmixin") # deadcode
+  defineSymbol("nimeffects") # deadcode
+  defineSymbol("nimbabel") # deadcode
+  defineSymbol("nimcomputedgoto") # deadcode
+  defineSymbol("nimunion") # deadcode
+  defineSymbol("nimnewshared") # deadcode
+  defineSymbol("nimNewTypedesc") # deadcode
+  defineSymbol("nimrequiresnimframe") # deadcode
+  defineSymbol("nimparsebiggestfloatmagic") # deadcode
+  defineSymbol("nimalias") # deadcode
+  defineSymbol("nimlocks") # deadcode
+  defineSymbol("nimnode") # deadcode pending tests/deps/opengl-1.1.0/opengl.nim
+  defineSymbol("nimvarargstyped") # deadcode
+  defineSymbol("nimtypedescfixed") # deadcode
+  defineSymbol("nimKnowsNimvm") # deadcode
+  defineSymbol("nimArrIdx") # deadcode
+  defineSymbol("nimHasalignOf") # deadcode
+  defineSymbol("nimDistros") # deadcode
+  defineSymbol("nimHasCppDefine") # deadcode
+  defineSymbol("nimGenericInOutFlags") # deadcode
+  when false: defineSymbol("nimHasOpt") # deadcode
+  defineSymbol("nimNoArrayToCstringConversion") # deadcode
+  defineSymbol("nimHasRunnableExamples") # deadcode
+  defineSymbol("nimNewDot") # deadcode
+  defineSymbol("nimHasNilChecks") # deadcode
+  defineSymbol("nimSymKind") # deadcode
+  defineSymbol("nimVmEqIdent") # deadcode
+  defineSymbol("nimNoNil") # deadcode
+  defineSymbol("nimNoZeroTerminator") # deadcode
+  defineSymbol("nimNotNil") # deadcode
+  defineSymbol("nimVmExportFixed") # deadcode
+  defineSymbol("nimHasSymOwnerInMacro") # deadcode
+  defineSymbol("nimNewRuntime") # deadcode
+  defineSymbol("nimIncrSeqV3") # xxx: turn this into deadcode
+  defineSymbol("nimAshr") # deadcode
   defineSymbol("nimNoNilSeqs") # deadcode
   defineSymbol("nimNoNilSeqs2") # deadcode
   defineSymbol("nimHasUserErrors") # deadcode
-  defineSymbol("nimUncheckedArrayTyp")
-  defineSymbol("nimHasTypeof")
-  defineSymbol("nimErrorProcCanHaveBody")
-  defineSymbol("nimHasInstantiationOfInMacro")
-  defineSymbol("nimHasHotCodeReloading")
-  defineSymbol("nimHasNilSeqs")
-  defineSymbol("nimHasSignatureHashInMacro")
-  defineSymbol("nimHasDefault")
-  defineSymbol("nimMacrosSizealignof")
+  defineSymbol("nimUncheckedArrayTyp") # deadcode
+  defineSymbol("nimHasTypeof") # deadcode
+  defineSymbol("nimErrorProcCanHaveBody") # deadcode
+  defineSymbol("nimHasInstantiationOfInMacro") # deadcode
+  defineSymbol("nimHasHotCodeReloading") # deadcode
+  defineSymbol("nimHasNilSeqs") # deadcode
+  defineSymbol("nimHasSignatureHashInMacro") # deadcode
+  defineSymbol("nimHasDefault") # deadcode
+  defineSymbol("nimMacrosSizealignof") # deadcode
+
+  # > 0.20.0
   defineSymbol("nimNoZeroExtendMagic")
   defineSymbol("nimMacrosGetNodeId")
   for f in Feature:
diff --git a/config/config.nims b/config/config.nims
index 24c790168..f17f2e30b 100644
--- a/config/config.nims
+++ b/config/config.nims
@@ -1,5 +1,4 @@
 # this config.nims also needs to exist to prevent future regressions, see #9990
 
-when defined(nimHasCppDefine):
-  cppDefine "errno"
-  cppDefine "unix"
+cppDefine "errno"
+cppDefine "unix"
diff --git a/config/nim.cfg b/config/nim.cfg
index 3e7362a36..d5c3e7612 100644
--- a/config/nim.cfg
+++ b/config/nim.cfg
@@ -43,14 +43,12 @@ path="$lib/arch"
 path="$lib/core"
 path="$lib/pure"
 
-@if nimbabel:
-  @if not windows:
-    nimblepath="/opt/nimble/pkgs/"
-  @else:
-    # TODO:
-  @end
-  nimblepath="$home/.nimble/pkgs/"
+@if not windows:
+  nimblepath="/opt/nimble/pkgs/"
+@else:
+  # TODO:
 @end
+nimblepath="$home/.nimble/pkgs/"
 
 @if danger or quick:
   obj_checks:off
@@ -64,9 +62,7 @@ path="$lib/pure"
   debugger:off
   line_dir:off
   dead_code_elim:on
-  @if nimHasNilChecks:
-    nilchecks:off
-  @end
+  nilchecks:off
 @end
 
 @if release or danger:
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 57cdf0ccd..fb23954c0 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -229,7 +229,17 @@ proc intVal*(n: NimNode): BiggestInt {.magic: "NIntVal", noSideEffect.}
 proc floatVal*(n: NimNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
   ## Returns a float from any floating point literal.
 
-{.push warnings: off.}
+
+proc symKind*(symbol: NimNode): NimSymKind {.magic: "NSymKind", noSideEffect.}
+proc getImpl*(symbol: NimNode): NimNode {.magic: "GetImpl", noSideEffect.}
+  ## Returns a copy of the declaration of a symbol or `nil`.
+proc strVal*(n: NimNode): string  {.magic: "NStrVal", noSideEffect.}
+  ## Returns the string value of an identifier, symbol, comment, or string literal.
+  ##
+  ## See also:
+  ## * `strVal= proc<#strVal=,NimNode,string>`_ for setting the string value.
+
+{.push warnings: off.} # silence `deprecated`
 
 proc ident*(n: NimNode): NimIdent {.magic: "NIdent", noSideEffect, deprecated:
   "Deprecated since version 0.18.1; All functionality is defined on 'NimNode'.".}
@@ -239,41 +249,13 @@ proc symbol*(n: NimNode): NimSym {.magic: "NSymbol", noSideEffect, deprecated:
 
 proc getImpl*(s: NimSym): NimNode {.magic: "GetImpl", noSideEffect, deprecated: "use `getImpl: NimNode -> NimNode` instead".}
 
-when defined(nimSymKind):
-  proc symKind*(symbol: NimNode): NimSymKind {.magic: "NSymKind", noSideEffect.}
-  proc getImpl*(symbol: NimNode): NimNode {.magic: "GetImpl", noSideEffect.}
-    ## Returns a copy of the declaration of a symbol or `nil`.
-  proc strVal*(n: NimNode): string  {.magic: "NStrVal", noSideEffect.}
-    ## Returns the string value of an identifier, symbol, comment, or string literal.
-    ##
-    ## See also:
-    ## * `strVal= proc<#strVal=,NimNode,string>`_ for setting the string value.
-
-  proc `$`*(i: NimIdent): string {.magic: "NStrVal", noSideEffect, deprecated:
-    "Deprecated since version 0.18.1; Use 'strVal' instead.".}
-    ## Converts a Nim identifier to a string.
-
-  proc `$`*(s: NimSym): string {.magic: "NStrVal", noSideEffect, deprecated:
-    "Deprecated since version 0.18.1; Use 'strVal' instead.".}
-    ## Converts a Nim symbol to a string.
-
-else: # bootstrapping substitute
-  proc getImpl*(symbol: NimNode): NimNode =
-    symbol.symbol.getImpl
-
-  proc strValOld(n: NimNode): string {.magic: "NStrVal", noSideEffect.}
-
-  proc `$`*(s: NimSym): string {.magic: "IdentToStr", noSideEffect.}
+proc `$`*(i: NimIdent): string {.magic: "NStrVal", noSideEffect, deprecated:
+  "Deprecated since version 0.18.1; Use 'strVal' instead.".}
+  ## Converts a Nim identifier to a string.
 
-  proc `$`*(i: NimIdent): string {.magic: "IdentToStr", noSideEffect.}
-
-  proc strVal*(n: NimNode): string =
-    if n.kind == nnkIdent:
-      $n.ident
-    elif n.kind == nnkSym:
-      $n.symbol
-    else:
-      n.strValOld
+proc `$`*(s: NimSym): string {.magic: "NStrVal", noSideEffect, deprecated:
+  "Deprecated since version 0.18.1; Use 'strVal' instead.".}
+  ## Converts a Nim symbol to a string.
 
 {.pop.}
 
@@ -284,23 +266,21 @@ when (NimMajor, NimMinor, NimPatch) >= (1, 3, 5) or defined(nimSymImplTransform)
     ## note that code transformations are implementation dependent and subject to change.
     ## See an example in `tests/macros/tmacros_various.nim`.
 
-when defined(nimHasSymOwnerInMacro):
-  proc owner*(sym: NimNode): NimNode {.magic: "SymOwner", noSideEffect.}
-    ## Accepts a node of kind `nnkSym` and returns its owner's symbol.
-    ## The meaning of 'owner' depends on `sym`'s `NimSymKind` and declaration
-    ## context. For top level declarations this is an `nskModule` symbol,
-    ## for proc local variables an `nskProc` symbol, for enum/object fields an
-    ## `nskType` symbol, etc. For symbols without an owner, `nil` is returned.
-    ##
-    ## See also:
-    ## * `symKind proc<#symKind,NimNode>`_ to get the kind of a symbol
-    ## * `getImpl proc<#getImpl,NimNode>`_ to get the declaration of a symbol
-
-when defined(nimHasInstantiationOfInMacro):
-  proc isInstantiationOf*(instanceProcSym, genProcSym: NimNode): bool {.magic: "SymIsInstantiationOf", noSideEffect.}
-    ## Checks if a proc symbol is an instance of the generic proc symbol.
-    ## Useful to check proc symbols against generic symbols
-    ## returned by `bindSym`.
+proc owner*(sym: NimNode): NimNode {.magic: "SymOwner", noSideEffect.}
+  ## Accepts a node of kind `nnkSym` and returns its owner's symbol.
+  ## The meaning of 'owner' depends on `sym`'s `NimSymKind` and declaration
+  ## context. For top level declarations this is an `nskModule` symbol,
+  ## for proc local variables an `nskProc` symbol, for enum/object fields an
+  ## `nskType` symbol, etc. For symbols without an owner, `nil` is returned.
+  ##
+  ## See also:
+  ## * `symKind proc<#symKind,NimNode>`_ to get the kind of a symbol
+  ## * `getImpl proc<#getImpl,NimNode>`_ to get the declaration of a symbol
+
+proc isInstantiationOf*(instanceProcSym, genProcSym: NimNode): bool {.magic: "SymIsInstantiationOf", noSideEffect.}
+  ## Checks if a proc symbol is an instance of the generic proc symbol.
+  ## Useful to check proc symbols against generic symbols
+  ## returned by `bindSym`.
 
 proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
   ## With 'getType' you can access the node's `type`:idx:. A Nim type is
@@ -362,12 +342,11 @@ object
     doAssert(dumpTypeImpl(b) == t)
     doAssert(dumpTypeImpl(c) == t)
 
-when defined(nimHasSignatureHashInMacro):
-  proc signatureHash*(n: NimNode): string {.magic: "NSigHash", noSideEffect.}
-    ## Returns a stable identifier derived from the signature of a symbol.
-    ## The signature combines many factors such as the type of the symbol,
-    ## the owning module of the symbol and others. The same identifier is
-    ## used in the back-end to produce the mangled symbol name.
+proc signatureHash*(n: NimNode): string {.magic: "NSigHash", noSideEffect.}
+  ## Returns a stable identifier derived from the signature of a symbol.
+  ## The signature combines many factors such as the type of the symbol,
+  ## the owning module of the symbol and others. The same identifier is
+  ## used in the back-end to produce the mangled symbol name.
 
 proc symBodyHash*(s: NimNode): string {.noSideEffect.} =
   ## Returns a stable digest for symbols derived not only from type signature
@@ -1414,45 +1393,26 @@ proc copy*(node: NimNode): NimNode {.compileTime.} =
   ## An alias for `copyNimTree<#copyNimTree,NimNode>`_.
   return node.copyNimTree()
 
-when defined(nimVmEqIdent):
-  proc eqIdent*(a: string; b: string): bool {.magic: "EqIdent", noSideEffect.}
-    ## Style insensitive comparison.
-
-  proc eqIdent*(a: NimNode; b: string): bool {.magic: "EqIdent", noSideEffect.}
-    ## Style insensitive comparison.  ``a`` can be an identifier or a
-    ## symbol. ``a`` may be wrapped in an export marker
-    ## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
-    ## these nodes will be unwrapped.
-
-  proc eqIdent*(a: string; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
-    ## Style insensitive comparison.  ``b`` can be an identifier or a
-    ## symbol. ``b`` may be wrapped in an export marker
-    ## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
-    ## these nodes will be unwrapped.
-
-  proc eqIdent*(a: NimNode; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
-    ## Style insensitive comparison.  ``a`` and ``b`` can be an
-    ## identifier or a symbol. Both may be wrapped in an export marker
-    ## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
-    ## these nodes will be unwrapped.
-
-else:
-  from std/private/strimpl import cmpNimIdentifier
-
-  proc eqIdent*(a, b: string): bool = cmpNimIdentifier(a, b) == 0
-    ## Check if two idents are equal.
-
-  proc eqIdent*(node: NimNode; s: string): bool {.compileTime.} =
-    ## Check if node is some identifier node (``nnkIdent``, ``nnkSym``, etc.)
-    ## is the same as ``s``. Note that this is the preferred way to check! Most
-    ## other ways like ``node.ident`` are much more error-prone, unfortunately.
-    case node.kind
-    of nnkSym, nnkIdent:
-      result = eqIdent(node.strVal, s)
-    of nnkOpenSymChoice, nnkClosedSymChoice:
-      result = eqIdent($node[0], s)
-    else:
-      result = false
+proc eqIdent*(a: string; b: string): bool {.magic: "EqIdent", noSideEffect.}
+  ## Style insensitive comparison.
+
+proc eqIdent*(a: NimNode; b: string): bool {.magic: "EqIdent", noSideEffect.}
+  ## Style insensitive comparison.  ``a`` can be an identifier or a
+  ## symbol. ``a`` may be wrapped in an export marker
+  ## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
+  ## these nodes will be unwrapped.
+
+proc eqIdent*(a: string; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
+  ## Style insensitive comparison.  ``b`` can be an identifier or a
+  ## symbol. ``b`` may be wrapped in an export marker
+  ## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
+  ## these nodes will be unwrapped.
+
+proc eqIdent*(a: NimNode; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
+  ## Style insensitive comparison.  ``a`` and ``b`` can be an
+  ## identifier or a symbol. Both may be wrapped in an export marker
+  ## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
+  ## these nodes will be unwrapped.
 
 proc expectIdent*(n: NimNode, name: string) {.compileTime, since: (1,1).} =
   ## Check that ``eqIdent(n,name)`` holds true. If this is not the
@@ -1672,22 +1632,21 @@ proc getProjectPath*(): string = discard
   ## See also:
   ## * `getCurrentDir proc <os.html#getCurrentDir>`_
 
-when defined(nimMacrosSizealignof):
-  proc getSize*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
-    ## Returns the same result as ``system.sizeof`` if the size is
-    ## known by the Nim compiler. Returns a negative value if the Nim
-    ## compiler does not know the size.
-  proc getAlign*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
-    ## Returns the same result as ``system.alignof`` if the alignment
-    ## is known by the Nim compiler. It works on ``NimNode`` for use
-    ## in macro context. Returns a negative value if the Nim compiler
-    ## does not know the alignment.
-  proc getOffset*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
-    ## Returns the same result as ``system.offsetof`` if the offset is
-    ## known by the Nim compiler. It expects a resolved symbol node
-    ## from a field of a type. Therefore it only requires one argument
-    ## instead of two. Returns a negative value if the Nim compiler
-    ## does not know the offset.
+proc getSize*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
+  ## Returns the same result as ``system.sizeof`` if the size is
+  ## known by the Nim compiler. Returns a negative value if the Nim
+  ## compiler does not know the size.
+proc getAlign*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
+  ## Returns the same result as ``system.alignof`` if the alignment
+  ## is known by the Nim compiler. It works on ``NimNode`` for use
+  ## in macro context. Returns a negative value if the Nim compiler
+  ## does not know the alignment.
+proc getOffset*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
+  ## Returns the same result as ``system.offsetof`` if the offset is
+  ## known by the Nim compiler. It expects a resolved symbol node
+  ## from a field of a type. Therefore it only requires one argument
+  ## instead of two. Returns a negative value if the Nim compiler
+  ## does not know the offset.
 
 proc isExported*(n: NimNode): bool {.noSideEffect.} =
   ## Returns whether the symbol is exported or not.
diff --git a/lib/impure/re.nim b/lib/impure/re.nim
index de75aa063..20dee2ecd 100644
--- a/lib/impure/re.nim
+++ b/lib/impure/re.nim
@@ -386,9 +386,6 @@ proc findAll*(s: string, pattern: Regex, start = 0): seq[string] {.inline.} =
   result = @[]
   for x in findAll(s, pattern, start): result.add x
 
-when not defined(nimhygiene):
-  {.pragma: inject.}
-
 template `=~` *(s: string, pattern: Regex): untyped =
   ## This calls ``match`` with an implicit declared ``matches`` array that
   ## can be used in the scope of the ``=~`` call:
diff --git a/lib/pure/bitops.nim b/lib/pure/bitops.nim
index 2f1fc1814..b75b0cf9a 100644
--- a/lib/pure/bitops.nim
+++ b/lib/pure/bitops.nim
@@ -87,301 +87,300 @@ template forwardImpl(impl, arg) {.dirty.} =
     else:
       impl(x.uint64)
 
-when defined(nimHasalignOf):
-  type BitsRange*[T] = range[0..sizeof(T)*8-1]
-    ## A range with all bit positions for type `T`.
-
-  func bitsliced*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
-    ## Returns an extracted (and shifted) slice of bits from `v`.
-    runnableExamples:
-      doAssert 0b10111.bitsliced(2 .. 4) == 0b101
-      doAssert 0b11100.bitsliced(0 .. 2) == 0b100
-      doAssert 0b11100.bitsliced(0 ..< 3) == 0b100
-
-    let
-      upmost = sizeof(T) * 8 - 1
-      uv     = when v is SomeUnsignedInt: v else: v.toUnsigned
-    (uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
-
-  proc bitslice*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
-    ## Mutates `v` into an extracted (and shifted) slice of bits from `v`.
-    runnableExamples:
-      var x = 0b101110
-      x.bitslice(2 .. 4)
-      doAssert x == 0b011
-
-    let
-      upmost = sizeof(T) * 8 - 1
-      uv     = when v is SomeUnsignedInt: v else: v.toUnsigned
-    v = (uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
-
-  func toMask*[T: SomeInteger](slice: Slice[int]): T {.inline, since: (1, 3).} =
-    ## Creates a bitmask based on a slice of bits.
-    runnableExamples:
-      doAssert toMask[int32](1 .. 3) == 0b1110'i32
-      doAssert toMask[int32](0 .. 3) == 0b1111'i32
-
-    let
-      upmost = sizeof(T) * 8 - 1
-      bitmask = when T is SomeUnsignedInt:
-                  bitnot(0.T)
-                else:
-                  bitnot(0.T).toUnsigned
-    (bitmask shl (upmost - slice.b + slice.a) shr (upmost - slice.b)).T
-
-  proc masked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
-    ## Returns `v`, with only the `1` bits from `mask` matching those of
-    ## `v` set to 1.
-    ##
-    ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      let v = 0b0000_0011'u8
-      doAssert v.masked(0b0000_1010'u8) == 0b0000_0010'u8
-
-    bitand(v, mask)
-
-  func masked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
-    ## Returns `v`, with only the `1` bits in the range of `slice`
-    ## matching those of `v` set to 1.
-    ##
-    ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      let v = 0b0000_1011'u8
-      doAssert v.masked(1 .. 3) == 0b0000_1010'u8
-
-    bitand(v, toMask[T](slice))
-
-  proc mask*[T: SomeInteger](v: var T; mask: T) {.inline, since: (1, 3).} =
-    ## Mutates `v`, with only the `1` bits from `mask` matching those of
-    ## `v` set to 1.
-    ##
-    ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.mask(0b0000_1010'u8)
-      doAssert v == 0b0000_0010'u8
-
-    v = bitand(v, mask)
-
-  proc mask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
-    ## Mutates `v`, with only the `1` bits in the range of `slice`
-    ## matching those of `v` set to 1.
-    ##
-    ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      var v = 0b0000_1011'u8
-      v.mask(1 .. 3)
-      doAssert v == 0b0000_1010'u8
-
-    v = bitand(v, toMask[T](slice))
-
-  func setMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
-    ## Returns `v`, with all the `1` bits from `mask` set to 1.
-    ##
-    ## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      let v = 0b0000_0011'u8
-      doAssert v.setMasked(0b0000_1010'u8) == 0b0000_1011'u8
-
-    bitor(v, mask)
-
-  func setMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
-    ## Returns `v`, with all the `1` bits in the range of `slice` set to 1.
-    ##
-    ## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      let v = 0b0000_0011'u8
-      doAssert v.setMasked(2 .. 3) == 0b0000_1111'u8
-
-    bitor(v, toMask[T](slice))
-
-  proc setMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
-    ## Mutates `v`, with all the `1` bits from `mask` set to 1.
-    ##
-    ## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.setMask(0b0000_1010'u8)
-      doAssert v == 0b0000_1011'u8
-
-    v = bitor(v, mask)
-
-  proc setMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
-    ## Mutates `v`, with all the `1` bits in the range of `slice` set to 1.
-    ##
-    ## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.setMask(2 .. 3)
-      doAssert v == 0b0000_1111'u8
-
-    v = bitor(v, toMask[T](slice))
-
-  func clearMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
-    ## Returns `v`, with all the `1` bits from `mask` set to 0.
-    ##
-    ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
-    ## with an *inverted mask*.
-    runnableExamples:
-      let v = 0b0000_0011'u8
-      doAssert v.clearMasked(0b0000_1010'u8) == 0b0000_0001'u8
-
-    bitand(v, bitnot(mask))
-
-  func clearMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
-    ## Returns `v`, with all the `1` bits in the range of `slice` set to 0.
-    ##
-    ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
-    ## with an *inverted mask*.
-    runnableExamples:
-      let v = 0b0000_0011'u8
-      doAssert v.clearMasked(1 .. 3) == 0b0000_0001'u8
-
-    bitand(v, bitnot(toMask[T](slice)))
-
-  proc clearMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
-    ## Mutates `v`, with all the `1` bits from `mask` set to 0.
-    ##
-    ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
-    ## with an *inverted mask*.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.clearMask(0b0000_1010'u8)
-      doAssert v == 0b0000_0001'u8
-
-    v = bitand(v, bitnot(mask))
-
-  proc clearMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
-    ## Mutates `v`, with all the `1` bits in the range of `slice` set to 0.
-    ##
-    ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
-    ## with an *inverted mask*.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.clearMask(1 .. 3)
-      doAssert v == 0b0000_0001'u8
-
-    v = bitand(v, bitnot(toMask[T](slice)))
-
-  func flipMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
-    ## Returns `v`, with all the `1` bits from `mask` flipped.
-    ##
-    ## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      let v = 0b0000_0011'u8
-      doAssert v.flipMasked(0b0000_1010'u8) == 0b0000_1001'u8
-
-    bitxor(v, mask)
-
-  func flipMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
-    ## Returns `v`, with all the `1` bits in the range of `slice` flipped.
-    ##
-    ## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      let v = 0b0000_0011'u8
-      doAssert v.flipMasked(1 .. 3) == 0b0000_1101'u8
-
-    bitxor(v, toMask[T](slice))
-
-  proc flipMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
-    ## Mutates `v`, with all the `1` bits from `mask` flipped.
-    ##
-    ## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.flipMask(0b0000_1010'u8)
-      doAssert v == 0b0000_1001'u8
-
-    v = bitxor(v, mask)
-
-  proc flipMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
-    ## Mutates `v`, with all the `1` bits in the range of `slice` flipped.
-    ##
-    ## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.flipMask(1 .. 3)
-      doAssert v == 0b0000_1101'u8
-
-    v = bitxor(v, toMask[T](slice))
-
-  proc setBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
-    ## Mutates `v`, with the bit at position `bit` set to 1.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.setBit(5'u8)
-      doAssert v == 0b0010_0011'u8
-
-    v.setMask(1.T shl bit)
-
-  proc clearBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
-    ## Mutates `v`, with the bit at position `bit` set to 0.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.clearBit(1'u8)
-      doAssert v == 0b0000_0001'u8
-
-    v.clearMask(1.T shl bit)
-
-  proc flipBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
-    ## Mutates `v`, with the bit at position `bit` flipped.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.flipBit(1'u8)
-      doAssert v == 0b0000_0001'u8
-
-      v = 0b0000_0011'u8
-      v.flipBit(2'u8)
-      doAssert v == 0b0000_0111'u8
-
-    v.flipMask(1.T shl bit)
-
-  macro setBits*(v: typed; bits: varargs[typed]): untyped =
-    ## Mutates `v`, with the bits at positions `bits` set to 1.
-    runnableExamples:
-      var v = 0b0000_0011'u8
-      v.setBits(3, 5, 7)
-      doAssert v == 0b1010_1011'u8
-
-    bits.expectKind(nnkBracket)
-    result = newStmtList()
-    for bit in bits:
-      result.add newCall("setBit", v, bit)
-
-  macro clearBits*(v: typed; bits: varargs[typed]): untyped =
-    ## Mutates `v`, with the bits at positions `bits` set to 0.
-    runnableExamples:
-      var v = 0b1111_1111'u8
-      v.clearBits(1, 3, 5, 7)
-      doAssert v == 0b0101_0101'u8
-
-    bits.expectKind(nnkBracket)
-    result = newStmtList()
-    for bit in bits:
-      result.add newCall("clearBit", v, bit)
-
-  macro flipBits*(v: typed; bits: varargs[typed]): untyped =
-    ## Mutates `v`, with the bits at positions `bits` set to 0.
-    runnableExamples:
-      var v = 0b0000_1111'u8
-      v.flipBits(1, 3, 5, 7)
-      doAssert v == 0b1010_0101'u8
-
-    bits.expectKind(nnkBracket)
-    result = newStmtList()
-    for bit in bits:
-      result.add newCall("flipBit", v, bit)
-
-
-  proc testBit*[T: SomeInteger](v: T; bit: BitsRange[T]): bool {.inline.} =
-    ## Returns true if the bit in `v` at positions `bit` is set to 1.
-    runnableExamples:
-      let v = 0b0000_1111'u8
-      doAssert v.testBit(0)
-      doAssert not v.testBit(7)
-
-    let mask = 1.T shl bit
-    return (v and mask) == mask
+type BitsRange*[T] = range[0..sizeof(T)*8-1]
+  ## A range with all bit positions for type `T`.
+
+func bitsliced*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
+  ## Returns an extracted (and shifted) slice of bits from `v`.
+  runnableExamples:
+    doAssert 0b10111.bitsliced(2 .. 4) == 0b101
+    doAssert 0b11100.bitsliced(0 .. 2) == 0b100
+    doAssert 0b11100.bitsliced(0 ..< 3) == 0b100
+
+  let
+    upmost = sizeof(T) * 8 - 1
+    uv     = when v is SomeUnsignedInt: v else: v.toUnsigned
+  (uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
+
+proc bitslice*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
+  ## Mutates `v` into an extracted (and shifted) slice of bits from `v`.
+  runnableExamples:
+    var x = 0b101110
+    x.bitslice(2 .. 4)
+    doAssert x == 0b011
+
+  let
+    upmost = sizeof(T) * 8 - 1
+    uv     = when v is SomeUnsignedInt: v else: v.toUnsigned
+  v = (uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
+
+func toMask*[T: SomeInteger](slice: Slice[int]): T {.inline, since: (1, 3).} =
+  ## Creates a bitmask based on a slice of bits.
+  runnableExamples:
+    doAssert toMask[int32](1 .. 3) == 0b1110'i32
+    doAssert toMask[int32](0 .. 3) == 0b1111'i32
+
+  let
+    upmost = sizeof(T) * 8 - 1
+    bitmask = when T is SomeUnsignedInt:
+                bitnot(0.T)
+              else:
+                bitnot(0.T).toUnsigned
+  (bitmask shl (upmost - slice.b + slice.a) shr (upmost - slice.b)).T
+
+proc masked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
+  ## Returns `v`, with only the `1` bits from `mask` matching those of
+  ## `v` set to 1.
+  ##
+  ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    let v = 0b0000_0011'u8
+    doAssert v.masked(0b0000_1010'u8) == 0b0000_0010'u8
+
+  bitand(v, mask)
+
+func masked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
+  ## Returns `v`, with only the `1` bits in the range of `slice`
+  ## matching those of `v` set to 1.
+  ##
+  ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    let v = 0b0000_1011'u8
+    doAssert v.masked(1 .. 3) == 0b0000_1010'u8
+
+  bitand(v, toMask[T](slice))
+
+proc mask*[T: SomeInteger](v: var T; mask: T) {.inline, since: (1, 3).} =
+  ## Mutates `v`, with only the `1` bits from `mask` matching those of
+  ## `v` set to 1.
+  ##
+  ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.mask(0b0000_1010'u8)
+    doAssert v == 0b0000_0010'u8
+
+  v = bitand(v, mask)
+
+proc mask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
+  ## Mutates `v`, with only the `1` bits in the range of `slice`
+  ## matching those of `v` set to 1.
+  ##
+  ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    var v = 0b0000_1011'u8
+    v.mask(1 .. 3)
+    doAssert v == 0b0000_1010'u8
+
+  v = bitand(v, toMask[T](slice))
+
+func setMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
+  ## Returns `v`, with all the `1` bits from `mask` set to 1.
+  ##
+  ## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    let v = 0b0000_0011'u8
+    doAssert v.setMasked(0b0000_1010'u8) == 0b0000_1011'u8
+
+  bitor(v, mask)
+
+func setMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
+  ## Returns `v`, with all the `1` bits in the range of `slice` set to 1.
+  ##
+  ## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    let v = 0b0000_0011'u8
+    doAssert v.setMasked(2 .. 3) == 0b0000_1111'u8
+
+  bitor(v, toMask[T](slice))
+
+proc setMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
+  ## Mutates `v`, with all the `1` bits from `mask` set to 1.
+  ##
+  ## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.setMask(0b0000_1010'u8)
+    doAssert v == 0b0000_1011'u8
+
+  v = bitor(v, mask)
+
+proc setMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
+  ## Mutates `v`, with all the `1` bits in the range of `slice` set to 1.
+  ##
+  ## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.setMask(2 .. 3)
+    doAssert v == 0b0000_1111'u8
+
+  v = bitor(v, toMask[T](slice))
+
+func clearMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
+  ## Returns `v`, with all the `1` bits from `mask` set to 0.
+  ##
+  ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
+  ## with an *inverted mask*.
+  runnableExamples:
+    let v = 0b0000_0011'u8
+    doAssert v.clearMasked(0b0000_1010'u8) == 0b0000_0001'u8
+
+  bitand(v, bitnot(mask))
+
+func clearMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
+  ## Returns `v`, with all the `1` bits in the range of `slice` set to 0.
+  ##
+  ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
+  ## with an *inverted mask*.
+  runnableExamples:
+    let v = 0b0000_0011'u8
+    doAssert v.clearMasked(1 .. 3) == 0b0000_0001'u8
+
+  bitand(v, bitnot(toMask[T](slice)))
+
+proc clearMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
+  ## Mutates `v`, with all the `1` bits from `mask` set to 0.
+  ##
+  ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
+  ## with an *inverted mask*.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.clearMask(0b0000_1010'u8)
+    doAssert v == 0b0000_0001'u8
+
+  v = bitand(v, bitnot(mask))
+
+proc clearMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
+  ## Mutates `v`, with all the `1` bits in the range of `slice` set to 0.
+  ##
+  ## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
+  ## with an *inverted mask*.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.clearMask(1 .. 3)
+    doAssert v == 0b0000_0001'u8
+
+  v = bitand(v, bitnot(toMask[T](slice)))
+
+func flipMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
+  ## Returns `v`, with all the `1` bits from `mask` flipped.
+  ##
+  ## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    let v = 0b0000_0011'u8
+    doAssert v.flipMasked(0b0000_1010'u8) == 0b0000_1001'u8
+
+  bitxor(v, mask)
+
+func flipMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
+  ## Returns `v`, with all the `1` bits in the range of `slice` flipped.
+  ##
+  ## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    let v = 0b0000_0011'u8
+    doAssert v.flipMasked(1 .. 3) == 0b0000_1101'u8
+
+  bitxor(v, toMask[T](slice))
+
+proc flipMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
+  ## Mutates `v`, with all the `1` bits from `mask` flipped.
+  ##
+  ## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.flipMask(0b0000_1010'u8)
+    doAssert v == 0b0000_1001'u8
+
+  v = bitxor(v, mask)
+
+proc flipMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
+  ## Mutates `v`, with all the `1` bits in the range of `slice` flipped.
+  ##
+  ## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.flipMask(1 .. 3)
+    doAssert v == 0b0000_1101'u8
+
+  v = bitxor(v, toMask[T](slice))
+
+proc setBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
+  ## Mutates `v`, with the bit at position `bit` set to 1.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.setBit(5'u8)
+    doAssert v == 0b0010_0011'u8
+
+  v.setMask(1.T shl bit)
+
+proc clearBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
+  ## Mutates `v`, with the bit at position `bit` set to 0.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.clearBit(1'u8)
+    doAssert v == 0b0000_0001'u8
+
+  v.clearMask(1.T shl bit)
+
+proc flipBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
+  ## Mutates `v`, with the bit at position `bit` flipped.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.flipBit(1'u8)
+    doAssert v == 0b0000_0001'u8
+
+    v = 0b0000_0011'u8
+    v.flipBit(2'u8)
+    doAssert v == 0b0000_0111'u8
+
+  v.flipMask(1.T shl bit)
+
+macro setBits*(v: typed; bits: varargs[typed]): untyped =
+  ## Mutates `v`, with the bits at positions `bits` set to 1.
+  runnableExamples:
+    var v = 0b0000_0011'u8
+    v.setBits(3, 5, 7)
+    doAssert v == 0b1010_1011'u8
+
+  bits.expectKind(nnkBracket)
+  result = newStmtList()
+  for bit in bits:
+    result.add newCall("setBit", v, bit)
+
+macro clearBits*(v: typed; bits: varargs[typed]): untyped =
+  ## Mutates `v`, with the bits at positions `bits` set to 0.
+  runnableExamples:
+    var v = 0b1111_1111'u8
+    v.clearBits(1, 3, 5, 7)
+    doAssert v == 0b0101_0101'u8
+
+  bits.expectKind(nnkBracket)
+  result = newStmtList()
+  for bit in bits:
+    result.add newCall("clearBit", v, bit)
+
+macro flipBits*(v: typed; bits: varargs[typed]): untyped =
+  ## Mutates `v`, with the bits at positions `bits` set to 0.
+  runnableExamples:
+    var v = 0b0000_1111'u8
+    v.flipBits(1, 3, 5, 7)
+    doAssert v == 0b1010_0101'u8
+
+  bits.expectKind(nnkBracket)
+  result = newStmtList()
+  for bit in bits:
+    result.add newCall("flipBit", v, bit)
+
+
+proc testBit*[T: SomeInteger](v: T; bit: BitsRange[T]): bool {.inline.} =
+  ## Returns true if the bit in `v` at positions `bit` is set to 1.
+  runnableExamples:
+    let v = 0b0000_1111'u8
+    doAssert v.testBit(0)
+    doAssert not v.testBit(7)
+
+  let mask = 1.T shl bit
+  return (v and mask) == mask
 
 # #### Pure Nim version ####
 
diff --git a/lib/pure/collections/hashcommon.nim b/lib/pure/collections/hashcommon.nim
index 1496a49e0..452b5e1bb 100644
--- a/lib/pure/collections/hashcommon.nim
+++ b/lib/pure/collections/hashcommon.nim
@@ -13,11 +13,6 @@
 const
   growthFactor = 2
 
-when not defined(nimHasDefault):
-  template default[T](t: typedesc[T]): T =
-    var v: T
-    v
-
 # hcode for real keys cannot be zero.  hcode==0 signifies an empty slot.  These
 # two procs retain clarity of that encoding without the space cost of an enum.
 proc isEmpty(hcode: Hash): bool {.inline.} =
diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim
index bf8a0e8da..e1c3808b2 100644
--- a/lib/pure/collections/lists.nim
+++ b/lib/pure/collections/lists.nim
@@ -60,9 +60,6 @@ runnableExamples:
 
 import std/private/since
 
-when not defined(nimhygiene):
-  {.pragma: dirty.}
-
 when not defined(nimHasCursor):
   {.pragma: cursor.}
 
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index 9945e1951..70ecff493 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -84,10 +84,6 @@ import std/private/since
 
 import macros
 
-when not defined(nimhygiene):
-  {.pragma: dirty.}
-
-
 macro evalOnceAs(expAlias, exp: untyped,
                  letAssigneable: static[bool]): untyped =
   ## Injects `expAlias` in caller scope, to avoid bugs involving multiple
@@ -956,16 +952,10 @@ template mapIt*(s: typed, op: untyped): untyped =
       strings = nums.mapIt($(4 * it))
     assert strings == @["4", "8", "12", "16"]
 
-  when defined(nimHasTypeof):
-    type OutType = typeof((
-      block:
-        var it{.inject.}: typeof(items(s), typeOfIter);
-        op), typeOfProc)
-  else:
-    type OutType = typeof((
-      block:
-        var it{.inject.}: typeof(items(s));
-        op))
+  type OutType = typeof((
+    block:
+      var it{.inject.}: typeof(items(s), typeOfIter);
+      op), typeOfProc)
   when OutType is not (proc):
     # Here, we avoid to create closures in loops.
     # This avoids https://github.com/nim-lang/Nim/issues/12625
@@ -996,11 +986,7 @@ template mapIt*(s: typed, op: untyped): untyped =
     # With this fallback, above code can be simplified to:
     #   [1, 2].mapIt((x: int) => it + x)
     # In this case, `mapIt` is just syntax sugar for `map`.
-
-    when defined(nimHasTypeof):
-      type InType = typeof(items(s), typeOfIter)
-    else:
-      type InType = typeof(items(s))
+    type InType = typeof(items(s), typeOfIter)
     # Use a help proc `f` to create closures for each element in `s`
     let f = proc (x: InType): OutType =
               let it {.inject.} = x
diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim
index 42f8aa031..5febef5d8 100644
--- a/lib/pure/collections/sets.nim
+++ b/lib/pure/collections/sets.nim
@@ -51,9 +51,6 @@ import
   hashes, math
 
 {.pragma: myShallow.}
-when not defined(nimhygiene):
-  {.pragma: dirty.}
-
 # For "integer-like A" that are too big for intsets/bit-vectors to be practical,
 # it would be best to shrink hcode to the same size as the integer.  Larger
 # codes should never be needed, and this can pack more entries per cache-line.
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 58a565c7a..a65186410 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -74,7 +74,7 @@ elif defined(posix):
 else:
   {.error: "OS module not ported to your operating system!".}
 
-when weirdTarget and defined(nimErrorProcCanHaveBody):
+when weirdTarget:
   {.pragma: noWeirdTarget, error: "this proc is not available on the NimScript/js target".}
 else:
   {.pragma: noWeirdTarget.}
@@ -2262,10 +2262,7 @@ iterator walkDir*(dir: string; relative = false, checkDir = false):
         while true:
           var x = readdir(d)
           if x == nil: break
-          when defined(nimNoArrayToCstringConversion):
-            var y = $cstring(addr x.d_name)
-          else:
-            var y = $x.d_name.cstring
+          var y = $cstring(addr x.d_name)
           if y != "." and y != "..":
             var s: Stat
             let path = dir / y
diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim
index 54ca4e3c5..fd22cb165 100644
--- a/lib/pure/pegs.nim
+++ b/lib/pure/pegs.nim
@@ -1158,9 +1158,6 @@ proc findAll*(s: string, pattern: Peg, start = 0): seq[string] {.
   result = @[]
   for it in findAll(s, pattern, start): result.add it
 
-when not defined(nimhygiene):
-  {.pragma: inject.}
-
 template `=~`*(s: string, pattern: Peg): bool =
   ## This calls ``match`` with an implicit declared ``matches`` array that
   ## can be used in the scope of the ``=~`` call:
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index a25df9e42..5d04b5300 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -75,9 +75,8 @@ from math import pow, floor, log10
 from algorithm import reverse
 import std/enumutils
 
-when defined(nimVmExportFixed):
-  from unicode import toLower, toUpper
-  export toLower, toUpper
+from unicode import toLower, toUpper
+export toLower, toUpper
 
 include "system/inclrtl"
 import std/private/since
@@ -2341,17 +2340,11 @@ func formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault,
       frmtstr[3] = '*'
       frmtstr[4] = floatFormatToChar[format]
       frmtstr[5] = '\0'
-      when defined(nimNoArrayToCstringConversion):
-        L = c_sprintf(addr buf, addr frmtstr, precision, f)
-      else:
-        L = c_sprintf(buf, frmtstr, precision, f)
+      L = c_sprintf(addr buf, addr frmtstr, precision, f)
     else:
       frmtstr[1] = floatFormatToChar[format]
       frmtstr[2] = '\0'
-      when defined(nimNoArrayToCstringConversion):
-        L = c_sprintf(addr buf, addr frmtstr, f)
-      else:
-        L = c_sprintf(buf, frmtstr, f)
+      L = c_sprintf(addr buf, addr frmtstr, f)
     result = newString(L)
     for i in 0 ..< L:
       # Depending on the locale either dot or comma is produced,
diff --git a/lib/system.nim b/lib/system.nim
index 09a7faca9..823412fd2 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -135,39 +135,35 @@ else:
     OrdinalImpl[T] {.magic: Ordinal.}
     Ordinal* = OrdinalImpl | uint | uint64
 
-when defined(nimHasRunnableExamples):
-  proc runnableExamples*(rdoccmd = "", body: untyped) {.magic: "RunnableExamples".}
-    ## A section you should use to mark `runnable example`:idx: code with.
-    ##
-    ## - In normal debug and release builds code within
-    ##   a `runnableExamples` section is ignored.
-    ## - The documentation generator is aware of these examples and considers them
-    ##   part of the `##` doc comment. As the last step of documentation
-    ##   generation each runnableExample is put in its own file `$file_examples$i.nim`,
-    ##   compiled and tested. The collected examples are
-    ##   put into their own module to ensure the examples do not refer to
-    ##   non-exported symbols.
-    ##
-    ## Usage:
-    ##
-    ## .. code-block:: Nim
-    ##   proc double*(x: int): int =
-    ##     ## This proc doubles a number.
-    ##     runnableExamples:
-    ##       ## at module scope
-    ##       assert double(5) == 10
-    ##       block: ## at block scope
-    ##         defer: echo "done"
-    ##     result = 2 * x
-    ##     runnableExamples "-d:foo -b:cpp":
-    ##       import std/compilesettings
-    ##       doAssert querySetting(backend) == "cpp"
-    ##     runnableExamples "-r:off": ## this one is only compiled
-    ##        import std/browsers
-    ##        openDefaultBrowser "https://forum.nim-lang.org/"
-else:
-  template runnableExamples*(doccmd = "", body: untyped) =
-    discard
+proc runnableExamples*(rdoccmd = "", body: untyped) {.magic: "RunnableExamples".}
+  ## A section you should use to mark `runnable example`:idx: code with.
+  ##
+  ## - In normal debug and release builds code within
+  ##   a `runnableExamples` section is ignored.
+  ## - The documentation generator is aware of these examples and considers them
+  ##   part of the `##` doc comment. As the last step of documentation
+  ##   generation each runnableExample is put in its own file `$file_examples$i.nim`,
+  ##   compiled and tested. The collected examples are
+  ##   put into their own module to ensure the examples do not refer to
+  ##   non-exported symbols.
+  ##
+  ## Usage:
+  ##
+  ## .. code-block:: Nim
+  ##   proc double*(x: int): int =
+  ##     ## This proc doubles a number.
+  ##     runnableExamples:
+  ##       ## at module scope
+  ##       assert double(5) == 10
+  ##       block: ## at block scope
+  ##         defer: echo "done"
+  ##     result = 2 * x
+  ##     runnableExamples "-d:foo -b:cpp":
+  ##       import std/compilesettings
+  ##       doAssert querySetting(backend) == "cpp"
+  ##     runnableExamples "-r:off": ## this one is only compiled
+  ##        import std/browsers
+  ##        openDefaultBrowser "https://forum.nim-lang.org/"
 
 when defined(nimHasDeclaredMagic):
   proc declared*(x: untyped): bool {.magic: "Declared", noSideEffect, compileTime.}
@@ -222,52 +218,45 @@ proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} =
   ## Cannot be overloaded.
   discard
 
-when defined(nimNewTypedesc):
-  type
-    `static`*[T] {.magic: "Static".}
-      ## Meta type representing all values that can be evaluated at compile-time.
-      ##
-      ## The type coercion `static(x)` can be used to force the compile-time
-      ## evaluation of the given expression `x`.
+type
+  `static`*[T] {.magic: "Static".}
+    ## Meta type representing all values that can be evaluated at compile-time.
+    ##
+    ## The type coercion `static(x)` can be used to force the compile-time
+    ## evaluation of the given expression `x`.
 
-    `type`*[T] {.magic: "Type".}
-      ## Meta type representing the type of all type values.
-      ##
-      ## The coercion `type(x)` can be used to obtain the type of the given
-      ## expression `x`.
-else:
-  proc `type`*(x: untyped): typedesc {.magic: "TypeOf", noSideEffect, compileTime.} =
-    ## Builtin `type` operator for accessing the type of an expression.
-    ## Cannot be overloaded.
-    discard
+  `type`*[T] {.magic: "Type".}
+    ## Meta type representing the type of all type values.
+    ##
+    ## The coercion `type(x)` can be used to obtain the type of the given
+    ## expression `x`.
 
-when defined(nimHasTypeof):
-  type
-    TypeOfMode* = enum ## Possible modes of `typeof`.
-      typeOfProc,      ## Prefer the interpretation that means `x` is a proc call.
-      typeOfIter       ## Prefer the interpretation that means `x` is an iterator call.
-
-  proc typeof*(x: untyped; mode = typeOfIter): typedesc {.
-    magic: "TypeOf", noSideEffect, compileTime.} =
-    ## Builtin `typeof` operation for accessing the type of an expression.
-    ## Since version 0.20.0.
-    runnableExamples:
-      proc myFoo(): float = 0.0
-      iterator myFoo(): string = yield "abc"
-      iterator myFoo2(): string = yield "abc"
-      iterator myFoo3(): string {.closure.} = yield "abc"
-      doAssert type(myFoo()) is string
-      doAssert typeof(myFoo()) is string
-      doAssert typeof(myFoo(), typeOfIter) is string
-      doAssert typeof(myFoo3) is "iterator"
-
-      doAssert typeof(myFoo(), typeOfProc) is float
-      doAssert typeof(0.0, typeOfProc) is float
-      doAssert typeof(myFoo3, typeOfProc) is "iterator"
-      doAssert not compiles(typeof(myFoo2(), typeOfProc))
-        # this would give: Error: attempting to call routine: 'myFoo2'
-        # since `typeOfProc` expects a typed expression and `myFoo2()` can
-        # only be used in a `for` context.
+type
+  TypeOfMode* = enum ## Possible modes of `typeof`.
+    typeOfProc,      ## Prefer the interpretation that means `x` is a proc call.
+    typeOfIter       ## Prefer the interpretation that means `x` is an iterator call.
+
+proc typeof*(x: untyped; mode = typeOfIter): typedesc {.
+  magic: "TypeOf", noSideEffect, compileTime.} =
+  ## Builtin `typeof` operation for accessing the type of an expression.
+  ## Since version 0.20.0.
+  runnableExamples:
+    proc myFoo(): float = 0.0
+    iterator myFoo(): string = yield "abc"
+    iterator myFoo2(): string = yield "abc"
+    iterator myFoo3(): string {.closure.} = yield "abc"
+    doAssert type(myFoo()) is string
+    doAssert typeof(myFoo()) is string
+    doAssert typeof(myFoo(), typeOfIter) is string
+    doAssert typeof(myFoo3) is "iterator"
+
+    doAssert typeof(myFoo(), typeOfProc) is float
+    doAssert typeof(0.0, typeOfProc) is float
+    doAssert typeof(myFoo3, typeOfProc) is "iterator"
+    doAssert not compiles(typeof(myFoo2(), typeOfProc))
+      # this would give: Error: attempting to call routine: 'myFoo2'
+      # since `typeOfProc` expects a typed expression and `myFoo2()` can
+      # only be used in a `for` context.
 
 const ThisIsSystem = true
 
@@ -310,14 +299,9 @@ type
   seq*[T]{.magic: "Seq".}             ## Generic type to construct sequences.
   set*[T]{.magic: "Set".}             ## Generic type to construct bit sets.
 
-when defined(nimUncheckedArrayTyp):
-  type
-    UncheckedArray*[T]{.magic: "UncheckedArray".}
-    ## Array with no bounds checking.
-else:
-  type
-    UncheckedArray*[T]{.unchecked.} = array[0,T]
-    ## Array with no bounds checking.
+type
+  UncheckedArray*[T]{.magic: "UncheckedArray".}
+  ## Array with no bounds checking.
 
 type sink*[T]{.magic: "BuiltinType".}
 type lent*[T]{.magic: "BuiltinType".}
@@ -476,25 +460,24 @@ proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".}
   ## There is a reason why the default assignment does a deep copy of sequences
   ## and strings.
 
-when defined(nimArrIdx):
-  # :array|openArray|string|seq|cstring|tuple
-  proc `[]`*[I: Ordinal;T](a: T; i: I): T {.
-    noSideEffect, magic: "ArrGet".}
-  proc `[]=`*[I: Ordinal;T,S](a: T; i: I;
-    x: sink S) {.noSideEffect, magic: "ArrPut".}
-  proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
-
-  proc arrGet[I: Ordinal;T](a: T; i: I): T {.
-    noSideEffect, magic: "ArrGet".}
-  proc arrPut[I: Ordinal;T,S](a: T; i: I;
-    x: S) {.noSideEffect, magic: "ArrPut".}
-
-  proc `=destroy`*[T](x: var T) {.inline, magic: "Destroy".} =
-    ## Generic `destructor`:idx: implementation that can be overridden.
-    discard
-  proc `=sink`*[T](x: var T; y: T) {.inline, magic: "Asgn".} =
-    ## Generic `sink`:idx: implementation that can be overridden.
-    shallowCopy(x, y)
+# :array|openArray|string|seq|cstring|tuple
+proc `[]`*[I: Ordinal;T](a: T; i: I): T {.
+  noSideEffect, magic: "ArrGet".}
+proc `[]=`*[I: Ordinal;T,S](a: T; i: I;
+  x: sink S) {.noSideEffect, magic: "ArrPut".}
+proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
+
+proc arrGet[I: Ordinal;T](a: T; i: I): T {.
+  noSideEffect, magic: "ArrGet".}
+proc arrPut[I: Ordinal;T,S](a: T; i: I;
+  x: S) {.noSideEffect, magic: "ArrPut".}
+
+proc `=destroy`*[T](x: var T) {.inline, magic: "Destroy".} =
+  ## Generic `destructor`:idx: implementation that can be overridden.
+  discard
+proc `=sink`*[T](x: var T; y: T) {.inline, magic: "Asgn".} =
+  ## Generic `sink`:idx: implementation that can be overridden.
+  shallowCopy(x, y)
 
 type
   HSlice*[T, U] = object   ## "Heterogeneous" slice type.
@@ -522,12 +505,6 @@ proc `..`*[T](b: sink T): HSlice[int, T] {.noSideEffect, inline, magic: "DotDot"
   ##   echo a[.. 2] # @[10, 20, 30]
   result = HSlice[int, T](a: 0, b: b)
 
-when not defined(niminheritable):
-  {.pragma: inheritable.}
-when not defined(nimunion):
-  {.pragma: unchecked.}
-when not defined(nimHasHotCodeReloading):
-  {.pragma: nonReloadable.}
 when defined(hotCodeReloading):
   {.pragma: hcrInline, inline.}
 else:
@@ -631,23 +608,21 @@ proc sizeof*[T](x: T): int {.magic: "SizeOf", noSideEffect.}
   ##  sizeof('A') # => 1
   ##  sizeof(2) # => 8
 
-when defined(nimHasalignOf):
-  proc alignof*[T](x: T): int {.magic: "AlignOf", noSideEffect.}
-  proc alignof*(x: typedesc): int {.magic: "AlignOf", noSideEffect.}
+proc alignof*[T](x: T): int {.magic: "AlignOf", noSideEffect.}
+proc alignof*(x: typedesc): int {.magic: "AlignOf", noSideEffect.}
 
-  proc offsetOfDotExpr(typeAccess: typed): int {.magic: "OffsetOf", noSideEffect, compileTime.}
+proc offsetOfDotExpr(typeAccess: typed): int {.magic: "OffsetOf", noSideEffect, compileTime.}
 
-  template offsetOf*[T](t: typedesc[T]; member: untyped): int =
-    var tmp {.noinit.}: ptr T
-    offsetOfDotExpr(tmp[].member)
+template offsetOf*[T](t: typedesc[T]; member: untyped): int =
+  var tmp {.noinit.}: ptr T
+  offsetOfDotExpr(tmp[].member)
 
-  template offsetOf*[T](value: T; member: untyped): int =
-    offsetOfDotExpr(value.member)
+template offsetOf*[T](value: T; member: untyped): int =
+  offsetOfDotExpr(value.member)
 
-  #proc offsetOf*(memberaccess: typed): int {.magic: "OffsetOf", noSideEffect.}
+#proc offsetOf*(memberaccess: typed): int {.magic: "OffsetOf", noSideEffect.}
 
-when defined(nimtypedescfixed):
-  proc sizeof*(x: typedesc): int {.magic: "SizeOf", noSideEffect.}
+proc sizeof*(x: typedesc): int {.magic: "SizeOf", noSideEffect.}
 
 
 proc newSeq*[T](s: var seq[T], len: Natural) {.magic: "NewSeq", noSideEffect.}
@@ -969,52 +944,42 @@ proc cmp*(x, y: string): int {.noSideEffect.}
   ## **Note**: The precise result values depend on the used C runtime library and
   ## can differ between operating systems!
 
-when defined(nimHasDefault):
-  proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.
-    magic: "ArrToSeq", noSideEffect.}
-    ## Turns an array into a sequence.
-    ##
-    ## This most often useful for constructing
-    ## sequences with the array constructor: `@[1, 2, 3]` has the type
-    ## `seq[int]`, while `[1, 2, 3]` has the type `array[0..2, int]`.
-    ##
-    ## .. code-block:: Nim
-    ##   let
-    ##     a = [1, 3, 5]
-    ##     b = "foo"
-    ##
-    ##   echo @a # => @[1, 3, 5]
-    ##   echo @b # => @['f', 'o', 'o']
-
-  proc default*(T: typedesc): T {.magic: "Default", noSideEffect.} =
-    ## returns the default value of the type `T`.
-    runnableExamples:
-      assert (int, float).default == (0, 0.0)
-      # note: `var a = default(T)` is usually the same as `var a: T` and (currently) generates
-      # a value whose binary representation is all 0, regardless of whether this
-      # would violate type constraints such as `range`, `not nil`, etc. This
-      # property is required to implement certain algorithms efficiently which
-      # may require intermediate invalid states.
-      type Foo = object
-        a: range[2..6]
-      var a1: range[2..6] # currently, this compiles
-      # var a2: Foo # currently, this errors: Error: The Foo type doesn't have a default value.
-      # var a3 = Foo() # ditto
-      var a3 = Foo.default # this works, but generates a `UnsafeDefault` warning.
-    # note: the doc comment also explains why `default` can't be implemented
-    # via: `template default*[T](t: typedesc[T]): T = (var v: T; v)`
-
-  proc reset*[T](obj: var T) {.noSideEffect.} =
-    ## Resets an object `obj` to its default value.
-    obj = default(typeof(obj))
+proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: "ArrToSeq", noSideEffect.}
+  ## Turns an array into a sequence.
+  ##
+  ## This most often useful for constructing
+  ## sequences with the array constructor: `@[1, 2, 3]` has the type
+  ## `seq[int]`, while `[1, 2, 3]` has the type `array[0..2, int]`.
+  ##
+  ## .. code-block:: Nim
+  ##   let
+  ##     a = [1, 3, 5]
+  ##     b = "foo"
+  ##
+  ##   echo @a # => @[1, 3, 5]
+  ##   echo @b # => @['f', 'o', 'o']
 
-else:
-  proc `@`* [IDX, T](a: array[IDX, T]): seq[T] {.
-    magic: "ArrToSeq", noSideEffect.}
-  when defined(nimV2):
-    proc reset*[T](obj: var T) {.magic: "Destroy", noSideEffect.}
-  else:
-    proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.}
+proc default*(T: typedesc): T {.magic: "Default", noSideEffect.} =
+  ## returns the default value of the type `T`.
+  runnableExamples:
+    assert (int, float).default == (0, 0.0)
+    # note: `var a = default(T)` is usually the same as `var a: T` and (currently) generates
+    # a value whose binary representation is all 0, regardless of whether this
+    # would violate type constraints such as `range`, `not nil`, etc. This
+    # property is required to implement certain algorithms efficiently which
+    # may require intermediate invalid states.
+    type Foo = object
+      a: range[2..6]
+    var a1: range[2..6] # currently, this compiles
+    # var a2: Foo # currently, this errors: Error: The Foo type doesn't have a default value.
+    # var a3 = Foo() # ditto
+    var a3 = Foo.default # this works, but generates a `UnsafeDefault` warning.
+  # note: the doc comment also explains why `default` can't be implemented
+  # via: `template default*[T](t: typedesc[T]): T = (var v: T; v)`
+
+proc reset*[T](obj: var T) {.noSideEffect.} =
+  ## Resets an object `obj` to its default value.
+  obj = default(typeof(obj))
 
 proc setLen*[T](s: var seq[T], newlen: Natural) {.
   magic: "SetLengthSeq", noSideEffect.}
@@ -2065,34 +2030,28 @@ elif hasAlloc:
         inc(i)
   {.pop.}
 
-when defined(nimvarargstyped):
-  proc echo*(x: varargs[typed, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
-    benign, sideEffect.}
-    ## Writes and flushes the parameters to the standard output.
-    ##
-    ## Special built-in that takes a variable number of arguments. Each argument
-    ## is converted to a string via `$`, so it works for user-defined
-    ## types that have an overloaded `$` operator.
-    ## It is roughly equivalent to `writeLine(stdout, x); flushFile(stdout)`, but
-    ## available for the JavaScript target too.
-    ##
-    ## Unlike other IO operations this is guaranteed to be thread-safe as
-    ## `echo` is very often used for debugging convenience. If you want to use
-    ## `echo` inside a `proc without side effects
-    ## <manual.html#pragmas-nosideeffect-pragma>`_ you can use `debugEcho
-    ## <#debugEcho,varargs[typed,]>`_ instead.
-
-  proc debugEcho*(x: varargs[typed, `$`]) {.magic: "Echo", noSideEffect,
-                                            tags: [], raises: [].}
-    ## Same as `echo <#echo,varargs[typed,]>`_, but as a special semantic rule,
-    ## `debugEcho` pretends to be free of side effects, so that it can be used
-    ## for debugging routines marked as `noSideEffect
-    ## <manual.html#pragmas-nosideeffect-pragma>`_.
-else:
-  proc echo*(x: varargs[untyped, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
-    benign, sideEffect.}
-  proc debugEcho*(x: varargs[untyped, `$`]) {.magic: "Echo", noSideEffect,
-                                             tags: [], raises: [].}
+proc echo*(x: varargs[typed, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
+  benign, sideEffect.}
+  ## Writes and flushes the parameters to the standard output.
+  ##
+  ## Special built-in that takes a variable number of arguments. Each argument
+  ## is converted to a string via `$`, so it works for user-defined
+  ## types that have an overloaded `$` operator.
+  ## It is roughly equivalent to `writeLine(stdout, x); flushFile(stdout)`, but
+  ## available for the JavaScript target too.
+  ##
+  ## Unlike other IO operations this is guaranteed to be thread-safe as
+  ## `echo` is very often used for debugging convenience. If you want to use
+  ## `echo` inside a `proc without side effects
+  ## <manual.html#pragmas-nosideeffect-pragma>`_ you can use `debugEcho
+  ## <#debugEcho,varargs[typed,]>`_ instead.
+
+proc debugEcho*(x: varargs[typed, `$`]) {.magic: "Echo", noSideEffect,
+                                          tags: [], raises: [].}
+  ## Same as `echo <#echo,varargs[typed,]>`_, but as a special semantic rule,
+  ## `debugEcho` pretends to be free of side effects, so that it can be used
+  ## for debugging routines marked as `noSideEffect
+  ## <manual.html#pragmas-nosideeffect-pragma>`_.
 
 template newException*(exceptn: typedesc, message: string;
                        parentException: ref Exception = nil): untyped =
@@ -2796,9 +2755,6 @@ when compileOption("rangechecks"):
 else:
   template rangeCheck*(cond) = discard
 
-when not defined(nimhygiene):
-  {.pragma: inject.}
-
 proc shallow*[T](s: var seq[T]) {.noSideEffect, inline.} =
   ## Marks a sequence `s` as `shallow`:idx:. Subsequent assignments will not
   ## perform deep copies of `s`.
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim
index 4839407c1..68d3eb9b5 100644
--- a/lib/system/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -12,8 +12,6 @@
 # All symbols are prefixed with 'c_' to avoid ambiguities
 
 {.push hints:off, stack_trace: off, profiler: off.}
-when not defined(nimHasHotCodeReloading):
-  {.pragma: nonReloadable.}
 
 proc c_memchr*(s: pointer, c: cint, n: csize_t): pointer {.
   importc: "memchr", header: "<string.h>".}
diff --git a/lib/system/arithmetics.nim b/lib/system/arithmetics.nim
index 4242cd1e3..d33401d1a 100644
--- a/lib/system/arithmetics.nim
+++ b/lib/system/arithmetics.nim
@@ -227,7 +227,7 @@ proc `mod`*(x, y: int16): int16 {.magic: "ModI", noSideEffect.}
 proc `mod`*(x, y: int32): int32 {.magic: "ModI", noSideEffect.}
 proc `mod`*(x, y: int64): int64 {.magic: "ModI", noSideEffect.}
 
-when defined(nimOldShiftRight) or not defined(nimAshr):
+when defined(nimOldShiftRight):
   const shrDepMessage = "`shr` will become sign preserving."
   proc `shr`*(x: int, y: SomeInteger): int {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
   proc `shr`*(x: int8, y: SomeInteger): int8 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
@@ -271,27 +271,23 @@ proc `shl`*(x: int16, y: SomeInteger): int16 {.magic: "ShlI", noSideEffect.}
 proc `shl`*(x: int32, y: SomeInteger): int32 {.magic: "ShlI", noSideEffect.}
 proc `shl`*(x: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.}
 
-when defined(nimAshr):
-  proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
-    ## Shifts right by pushing copies of the leftmost bit in from the left,
-    ## and let the rightmost bits fall off.
-    ##
-    ## Note that `ashr` is not an operator so use the normal function
-    ## call syntax for it.
-    ##
-    ## See also:
-    ## * `shr func<#shr,int,SomeInteger>`_
-    runnableExamples:
-      assert ashr(0b0001_0000'i8, 2) == 0b0000_0100'i8
-      assert ashr(0b1000_0000'i8, 8) == 0b1111_1111'i8
-      assert ashr(0b1000_0000'i8, 1) == 0b1100_0000'i8
-  proc ashr*(x: int8, y: SomeInteger): int8 {.magic: "AshrI", noSideEffect.}
-  proc ashr*(x: int16, y: SomeInteger): int16 {.magic: "AshrI", noSideEffect.}
-  proc ashr*(x: int32, y: SomeInteger): int32 {.magic: "AshrI", noSideEffect.}
-  proc ashr*(x: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
-else:
-  # used for bootstrapping the compiler
-  proc ashr*[T](x: T, y: SomeInteger): T = discard
+proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
+  ## Shifts right by pushing copies of the leftmost bit in from the left,
+  ## and let the rightmost bits fall off.
+  ##
+  ## Note that `ashr` is not an operator so use the normal function
+  ## call syntax for it.
+  ##
+  ## See also:
+  ## * `shr func<#shr,int,SomeInteger>`_
+  runnableExamples:
+    assert ashr(0b0001_0000'i8, 2) == 0b0000_0100'i8
+    assert ashr(0b1000_0000'i8, 8) == 0b1111_1111'i8
+    assert ashr(0b1000_0000'i8, 1) == 0b1100_0000'i8
+proc ashr*(x: int8, y: SomeInteger): int8 {.magic: "AshrI", noSideEffect.}
+proc ashr*(x: int16, y: SomeInteger): int16 {.magic: "AshrI", noSideEffect.}
+proc ashr*(x: int32, y: SomeInteger): int32 {.magic: "AshrI", noSideEffect.}
+proc ashr*(x: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
 
 proc `and`*(x, y: int): int {.magic: "BitandI", noSideEffect.} =
   ## Computes the `bitwise and` of numbers `x` and `y`.
diff --git a/lib/system/comparisons.nim b/lib/system/comparisons.nim
index c57cfa965..9d70f84cc 100644
--- a/lib/system/comparisons.nim
+++ b/lib/system/comparisons.nim
@@ -282,12 +282,8 @@ proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} =
   ## Generic equals operator for sequences: relies on a equals operator for
   ## the element type `T`.
   when nimvm:
-    when not defined(nimNoNil):
-      if x.isNil and y.isNil:
-        return true
-    else:
-      if x.len == 0 and y.len == 0:
-        return true
+    if x.len == 0 and y.len == 0:
+      return true
   else:
     when not defined(js):
       proc seqToPtr[T](x: seq[T]): pointer {.inline, noSideEffect.} =
@@ -303,10 +299,6 @@ proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} =
       asm """`sameObject` = `x` === `y`"""
       if sameObject: return true
 
-  when not defined(nimNoNil):
-    if x.isNil or y.isNil:
-      return false
-
   if x.len != y.len:
     return false
 
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim
index 1b0a3e64c..b0f326bb5 100644
--- a/lib/system/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -161,10 +161,7 @@ elif defined(windows) or defined(dos):
         dec(m)
         k = k div 10
         if k == 0: break
-      when defined(nimNoArrayToCstringConversion):
-        result = getProcAddress(cast[THINSTANCE](lib), addr decorated)
-      else:
-        result = getProcAddress(cast[THINSTANCE](lib), decorated)
+      result = getProcAddress(cast[THINSTANCE](lib), addr decorated)
       if result != nil: return
     procAddrError(name)
 
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 186757f99..95dbfe3af 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -393,15 +393,10 @@ proc reportUnhandledErrorAux(e: ref Exception) {.nodestroy.} =
     add(buf, " [")
     xadd(buf, e.name, e.name.len)
     add(buf, "]\n")
-    when defined(nimNoArrayToCstringConversion):
-      template tbuf(): untyped = addr buf
-    else:
-      template tbuf(): untyped = buf
-
     if onUnhandledException != nil:
-      onUnhandledException($tbuf())
+      onUnhandledException($buf.addr)
     else:
-      showErrorMessage(tbuf(), L)
+      showErrorMessage(buf.addr, L)
 
 proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
   if unhandledExceptionHook != nil:
diff --git a/lib/system/inclrtl.nim b/lib/system/inclrtl.nim
index d80980c72..0bc51d693 100644
--- a/lib/system/inclrtl.nim
+++ b/lib/system/inclrtl.nim
@@ -44,10 +44,7 @@ else:
   {.pragma: inl, inline.}
   {.pragma: compilerRtl, compilerproc.}
 
-when defined(nimlocks):
-  {.pragma: benign, gcsafe, locks: 0.}
-else:
-  {.pragma: benign, gcsafe.}
+{.pragma: benign, gcsafe, locks: 0.}
 
 when defined(nimHasSinkInference):
   {.push sinkInference: on.}
diff --git a/lib/system/memory.nim b/lib/system/memory.nim
index 50faa3d86..ebda60d8d 100644
--- a/lib/system/memory.nim
+++ b/lib/system/memory.nim
@@ -2,9 +2,6 @@
 
 const useLibC = not defined(nimNoLibc)
 
-when not defined(nimHasHotCodeReloading):
-  {.pragma: nonReloadable.}
-
 when useLibC:
   import ansi_c
 
diff --git a/lib/system/repr.nim b/lib/system/repr.nim
index ae51a4aab..7424500eb 100644
--- a/lib/system/repr.nim
+++ b/lib/system/repr.nim
@@ -16,14 +16,9 @@ proc reprInt(x: int64): string {.compilerproc.} = return $x
 proc reprFloat(x: float): string {.compilerproc.} = return $x
 
 proc reprPointer(x: pointer): string {.compilerproc.} =
-  when defined(nimNoArrayToCstringConversion):
-    result = newString(60)
-    let n = c_sprintf(addr result[0], "%p", x)
-    setLen(result, n)
-  else:
-    var buf: array[0..59, char]
-    discard c_sprintf(buf, "%p", x)
-    return $buf
+  result = newString(60)
+  let n = c_sprintf(addr result[0], "%p", x)
+  setLen(result, n)
 
 proc reprStrAux(result: var string, s: cstring; len: int) =
   if cast[pointer](s) == nil:
diff --git a/lib/system/strmantle.nim b/lib/system/strmantle.nim
index 7553f921b..42ea9d226 100644
--- a/lib/system/strmantle.nim
+++ b/lib/system/strmantle.nim
@@ -329,11 +329,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
   t[ti-2] = ('0'.ord + absExponent mod 10).char
   absExponent = absExponent div 10
   t[ti-3] = ('0'.ord + absExponent mod 10).char
-
-  when defined(nimNoArrayToCstringConversion):
-    number = c_strtod(addr t, nil)
-  else:
-    number = c_strtod(t, nil)
+  number = c_strtod(addr t, nil)
 
 when defined(nimHasInvariant):
   {.pop.} # staticBoundChecks
diff --git a/testament/specs.nim b/testament/specs.nim
index d4c82e97e..5c57b9a94 100644
--- a/testament/specs.nim
+++ b/testament/specs.nim
@@ -209,9 +209,6 @@ proc extractSpec(filename: string; spec: var TSpec): string =
     #echo "warning: file does not contain spec: " & filename
     result = ""
 
-when not defined(nimhygiene):
-  {.pragma: inject.}
-
 proc parseTargets*(value: string): set[TTarget] =
   for v in value.normalize.splitWhitespace:
     case v
diff --git a/tests/destructor/t7346.nim b/tests/destructor/t7346.nim
index 9e5292a61..3834d39ff 100644
--- a/tests/destructor/t7346.nim
+++ b/tests/destructor/t7346.nim
@@ -2,8 +2,7 @@ discard """
 joinable: false
 """
 
-when not defined(nimNewRuntime):
-  {.error: "This bug could only be reproduced with --newruntime".}
+# This bug could only be reproduced with --newruntime
 
 type
   Obj = object