summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelog.md1
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/ccgexprs.nim2
-rw-r--r--compiler/condsyms.nim1
-rw-r--r--compiler/jsgen.nim1
-rw-r--r--compiler/lineinfos.nim6
-rw-r--r--compiler/rodutils.nim21
-rw-r--r--compiler/sem.nim3
-rw-r--r--compiler/semfold.nim8
-rw-r--r--compiler/sigmatch.nim4
-rw-r--r--compiler/vm.nim3
-rw-r--r--compiler/vmdef.nim3
-rw-r--r--compiler/vmgen.nim1
-rw-r--r--lib/pure/collections/sequtils.nim33
-rw-r--r--lib/pure/math.nim82
-rw-r--r--lib/system.nim23
-rw-r--r--lib/system/gc_common.nim22
-rw-r--r--lib/windows/winlean.nim2
-rw-r--r--tests/arithm/tashr.nim46
-rw-r--r--tests/concepts/t3330.nim12
20 files changed, 224 insertions, 52 deletions
diff --git a/changelog.md b/changelog.md
index 56830628a..9ab7a0b72 100644
--- a/changelog.md
+++ b/changelog.md
@@ -95,6 +95,7 @@
 - Added the proc ``flush`` for memory mapped files.
 - Added the ``MemMapFileStream``.
 - Added ``macros.copyLineInfo`` to copy lineInfo from other node.
+- Added ``system.ashr`` an arithmetic right shift for integers.
 
 ### Library changes
 
diff --git a/compiler/ast.nim b/compiler/ast.nim
index dbf1151a9..ef12e1184 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -591,7 +591,7 @@ type
     mAddI, mSubI, mMulI, mDivI, mModI,
     mSucc, mPred,
     mAddF64, mSubF64, mMulF64, mDivF64,
-    mShrI, mShlI, mBitandI, mBitorI, mBitxorI,
+    mShrI, mShlI, mAshrI, mBitandI, mBitorI, mBitxorI,
     mMinI, mMaxI,
     mMinF64, mMaxF64,
     mAddU, mSubU, mMulU, mDivU, mModU,
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 3bcf2c29b..6803a9478 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -552,9 +552,9 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       "(($4)($1) - ($4)($2))", # SubF64
       "(($4)($1) * ($4)($2))", # MulF64
       "(($4)($1) / ($4)($2))", # DivF64
-
       "($4)((NU$5)($1) >> (NU$3)($2))", # ShrI
       "($4)((NU$3)($1) << (NU$3)($2))", # ShlI
+      "($4)((NI$3)($1) >> (NU$3)($2))", # AshrI
       "($4)($1 & $2)",      # BitandI
       "($4)($1 | $2)",      # BitorI
       "($4)($1 ^ $2)",      # BitxorI
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 9dfe69442..5a62b46ad 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -73,3 +73,4 @@ proc initDefines*(symbols: StringTableRef) =
   defineSymbol("nimNotNil")
   defineSymbol("nimVmExportFixed")
   defineSymbol("nimIncrSeqV3")
+  defineSymbol("nimAshr")
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index ef54841ae..63100a68d 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -379,6 +379,7 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
     ["", "", "($1 / $2)", "($1 / $2)"], # DivF64
     ["", "", "", ""], # ShrI
     ["", "", "($1 << $2)", "($1 << $2)"], # ShlI
+    ["", "", "($1 >> $2)", "($1 >> $2)"], # AshrI
     ["", "", "($1 & $2)", "($1 & $2)"], # BitandI
     ["", "", "($1 | $2)", "($1 | $2)"], # BitorI
     ["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI
diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim
index 261dcb44e..4f0c3a778 100644
--- a/compiler/lineinfos.nim
+++ b/compiler/lineinfos.nim
@@ -92,7 +92,7 @@ const
     warnResultShadowed: "Special variable 'result' is shadowed.",
     warnInconsistentSpacing: "Number of spaces around '$#' is not consistent",
     warnUser: "$1",
-    hintSuccess: "operation successful",
+    hintSuccess: "operation successful: $#",
     hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)",
     hintCC: "CC: \'$1\'", # unused
     hintLineTooLong: "line too long",
@@ -169,8 +169,8 @@ proc computeNotesVerbosity(): array[0..3, TNoteKinds] =
     result[1] = result[2] - {warnShadowIdent, warnProveField, warnProveIndex,
       warnGcUnsafe, hintPath, hintDependency, hintCodeBegin, hintCodeEnd,
       hintSource, hintGlobalVar, hintGCStats}
-    result[0] = result[1] - {hintSuccessX, hintConf, hintProcessing,
-      hintPattern, hintExecuting, hintLinking}
+    result[0] = result[1] - {hintSuccessX, hintSuccess, hintConf,
+      hintProcessing, hintPattern, hintExecuting, hintLinking}
 
 const
   NotesVerbosity* = computeNotesVerbosity()
diff --git a/compiler/rodutils.nim b/compiler/rodutils.nim
index 66d7f63c2..a774cdba7 100644
--- a/compiler/rodutils.nim
+++ b/compiler/rodutils.nim
@@ -10,6 +10,27 @@
 ## Serialization utilities for the compiler.
 import strutils, math
 
+# MSVC prior to 2013 doesn't have C99 functions
+when defined(windows) and (defined(vcc) or defined(bcc)):
+  {.emit: """#if defined(_MSC_VER) && _MSC_VER < 1900
+  #include <stdarg.h>
+  static int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
+    int count = -1;
+    if (size != 0) count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
+    if (count == -1) count = _vscprintf(format, ap);
+    return count;
+  }
+  int snprintf(char *outBuf, size_t size, const char *format, ...) {
+    int count;
+    va_list ap;
+    va_start(ap, format);
+    count = c99_vsnprintf(outBuf, size, format, ap);
+    va_end(ap);
+    return count;
+  }
+  #endif
+  """.}
+
 proc c_snprintf(s: cstring; n:uint; frmt: cstring): cint {.importc: "snprintf", header: "<stdio.h>", nodecl, varargs.}
 
 proc toStrMaxPrecision*(f: BiggestFloat, literalPostfix = ""): string =
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 68a0a7094..427b44e04 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -621,7 +621,8 @@ proc testExamples(c: PContext) =
   if os.execShellCmd(os.getAppFilename() & " " & backend & " --nimcache:" & nimcache & " -r " & outp) != 0:
     quit "[Examples] failed: see " & outp
   else:
-    removeFile(outp)
+    # keep generated source file `outp` to allow inspection.
+    rawMessage(c.config, hintSuccess, ["runnableExamples: " & outp])
     removeFile(outp.changeFileExt(ExeExt))
     try:
       removeDir(nimcache)
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index d2abfac13..a6c185fdc 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -268,6 +268,14 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
     of tyInt64, tyInt, tyUInt..tyUInt64:
       result = newIntNodeT(`shr`(getInt(a), getInt(b)), n, g)
     else: internalError(g.config, n.info, "constant folding for shr")
+  of mAshrI:
+    case skipTypes(n.typ, abstractRange).kind
+    of tyInt8: result = newIntNodeT(ashr(int8(getInt(a)), int8(getInt(b))), n, g)
+    of tyInt16: result = newIntNodeT(ashr(int16(getInt(a)), int16(getInt(b))), n, g)
+    of tyInt32: result = newIntNodeT(ashr(int32(getInt(a)), int32(getInt(b))), n, g)
+    of tyInt64, tyInt:
+      result = newIntNodeT(ashr(getInt(a), getInt(b)), n, g)
+    else: internalError(g.config, n.info, "constant folding for ashr")
   of mDivI: result = foldDiv(getInt(a), getInt(b), n, g)
   of mModI: result = foldMod(getInt(a), getInt(b), n, g)
   of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n, g)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 29f16b808..5afa1b031 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -858,6 +858,10 @@ proc inferStaticParam*(c: var TCandidate, lhs: PNode, rhs: BiggestInt): bool =
       if lhs[2].kind == nkIntLit:
         return inferStaticParam(c, lhs[1], rhs shl lhs[2].intVal)
 
+    of mAshrI:
+      if lhs[2].kind == nkIntLit:
+        return inferStaticParam(c, lhs[1], ashr(rhs, lhs[2].intVal))
+
     of mUnaryMinusI:
       return inferStaticParam(c, lhs[1], -rhs)
 
diff --git a/compiler/vm.nim b/compiler/vm.nim
index d4b041dea..c49b66b82 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -752,6 +752,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcShlInt:
       decodeBC(rkInt)
       regs[ra].intVal = regs[rb].intVal shl regs[rc].intVal
+    of opcAshrInt:
+      decodeBC(rkInt)
+      regs[ra].intVal = ashr(regs[rb].intVal, regs[rc].intVal)
     of opcBitandInt:
       decodeBC(rkInt)
       regs[ra].intVal = regs[rb].intVal and regs[rc].intVal
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index a4489513a..50235c95f 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -57,7 +57,8 @@ type
     opcLenStr,
 
     opcIncl, opcInclRange, opcExcl, opcCard, opcMulInt, opcDivInt, opcModInt,
-    opcAddFloat, opcSubFloat, opcMulFloat, opcDivFloat, opcShrInt, opcShlInt,
+    opcAddFloat, opcSubFloat, opcMulFloat, opcDivFloat,
+    opcShrInt, opcShlInt, opcAshrInt,
     opcBitandInt, opcBitorInt, opcBitxorInt, opcAddu, opcSubu, opcMulu,
     opcDivu, opcModu, opcEqInt, opcLeInt, opcLtInt, opcEqFloat,
     opcLeFloat, opcLtFloat, opcLeu, opcLtu,
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 965c75485..a36f559ca 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -939,6 +939,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
     c.freeTemp(tmp2)
 
   of mShlI: genBinaryABCnarrowU(c, n, dest, opcShlInt)
+  of mAshrI: genBinaryABCnarrow(c, n, dest, opcAshrInt)
   of mBitandI: genBinaryABCnarrowU(c, n, dest, opcBitandInt)
   of mBitorI: genBinaryABCnarrowU(c, n, dest, opcBitorInt)
   of mBitxorI: genBinaryABCnarrowU(c, n, dest, opcBitxorInt)
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index db33e41af..8f81fe4f5 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -635,6 +635,28 @@ template mapIt*(s, typ, op: untyped): untyped =
     result.add(op)
   result
 
+# This is needed in order not to break the bootstrap, the fallback
+# implementation is a "dumb" let that won't work in some cases (eg. when `exp`
+# is an openArray)
+when declared(macros.symKind):
+  macro evalOnce(v, exp: untyped): untyped =
+    expectKind(v, nnkIdent)
+    var val = exp
+
+    result = newStmtList()
+
+    # Not a parameter we can pass as-is, evaluate and store in a temporary
+    # variable
+    if exp.kind != nnkSym or exp.symKind != nskParam:
+      val = genSym()
+      result.add(newLetStmt(val, exp))
+
+    result.add(
+      newProc(name = genSym(nskTemplate, $v), params = [getType(untyped)],
+        body = val, procType = nnkTemplateDef))
+else:
+  macro evalOnce(v, exp: untyped): untyped =
+    result = newLetStmt(v, exp)
 
 template mapIt*(s, op: untyped): untyped =
   ## Convenience template around the ``map`` proc to reduce typing.
@@ -654,8 +676,8 @@ template mapIt*(s, op: untyped): untyped =
       var it{.inject.}: type(items(s));
       op))
   var result: seq[outType]
-  when compiles(s.len):
-    let t = s
+  evalOnce(t, s)
+  when compiles(t.len):
     var i = 0
     result = newSeq[outType](t.len)
     for it {.inject.} in t:
@@ -663,7 +685,7 @@ template mapIt*(s, op: untyped): untyped =
       i += 1
   else:
     result = @[]
-    for it {.inject.} in s:
+    for it {.inject.} in t:
       result.add(op)
   result
 
@@ -1044,5 +1066,10 @@ when isMainModule:
     doAssert mapLiterals((1, ("abc"), 2), float, nested=false) == (float(1), "abc", float(2))
     doAssert mapLiterals(([1], ("abc"), 2), `$`, nested=true) == (["1"], "abc", "2")
 
+  block: # mapIt with openArray
+    when declared(macros.symKind):
+      proc foo(x: openArray[int]): seq[int] = x.mapIt(it + 1)
+      doAssert foo([1,2,3]) == @[2,3,4]
+
   when not defined(testing):
     echo "Finished doc tests"
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index b921b1841..eb09bf4a7 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -162,9 +162,6 @@ when not defined(JS): # C
   proc log10*(x: float32): float32 {.importc: "log10f", header: "<math.h>".}
   proc log10*(x: float64): float64 {.importc: "log10", header: "<math.h>".}
     ## Computes the common logarithm (base 10) of `x`
-  proc log2*(x: float32): float32 {.importc: "log2f", header: "<math.h>".}
-  proc log2*(x: float64): float64 {.importc: "log2", header: "<math.h>".}
-    ## Computes the binary logarithm (base 2) of `x`
   proc exp*(x: float32): float32 {.importc: "expf", header: "<math.h>".}
   proc exp*(x: float64): float64 {.importc: "exp", header: "<math.h>".}
     ## Computes the exponential function of `x` (pow(E, x))
@@ -268,6 +265,8 @@ proc arcsech*[T: float32|float64](x: T): T = arccosh(1.0 / x)
 proc arccsch*[T: float32|float64](x: T): T = arcsinh(1.0 / x)
   ## Computes the inverse hyperbolic cosecant of `x`
 
+const windowsCC89 = defined(windows) and (defined(vcc) or defined(bcc))
+
 when not defined(JS): # C
   proc hypot*(x, y: float32): float32 {.importc: "hypotf", header: "<math.h>".}
   proc hypot*(x, y: float64): float64 {.importc: "hypot", header: "<math.h>".}
@@ -280,25 +279,27 @@ when not defined(JS): # C
     ##
     ## To compute power between integers, use `^` e.g. 2 ^ 6
 
-  proc erf*(x: float32): float32 {.importc: "erff", header: "<math.h>".}
-  proc erf*(x: float64): float64 {.importc: "erf", header: "<math.h>".}
-    ## The error function
-  proc erfc*(x: float32): float32 {.importc: "erfcf", header: "<math.h>".}
-  proc erfc*(x: float64): float64 {.importc: "erfc", header: "<math.h>".}
-    ## The complementary error function
-
-  proc gamma*(x: float32): float32 {.importc: "tgammaf", header: "<math.h>".}
-  proc gamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".}
-    ## The gamma function
-  proc tgamma*(x: float32): float32
-    {.deprecated: "use gamma instead", importc: "tgammaf", header: "<math.h>".}
-  proc tgamma*(x: float64): float64
-    {.deprecated: "use gamma instead", importc: "tgamma", header: "<math.h>".}
-    ## The gamma function
-    ## **Deprecated since version 0.19.0**: Use ``gamma`` instead.
-  proc lgamma*(x: float32): float32 {.importc: "lgammaf", header: "<math.h>".}
-  proc lgamma*(x: float64): float64 {.importc: "lgamma", header: "<math.h>".}
-    ## Natural log of the gamma function
+  # TODO: add C89 version on windows
+  when not windowsCC89:
+    proc erf*(x: float32): float32 {.importc: "erff", header: "<math.h>".}
+    proc erf*(x: float64): float64 {.importc: "erf", header: "<math.h>".}
+      ## The error function
+    proc erfc*(x: float32): float32 {.importc: "erfcf", header: "<math.h>".}
+    proc erfc*(x: float64): float64 {.importc: "erfc", header: "<math.h>".}
+      ## The complementary error function
+
+    proc gamma*(x: float32): float32 {.importc: "tgammaf", header: "<math.h>".}
+    proc gamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".}
+      ## The gamma function
+    proc tgamma*(x: float32): float32
+      {.deprecated: "use gamma instead", importc: "tgammaf", header: "<math.h>".}
+    proc tgamma*(x: float64): float64
+      {.deprecated: "use gamma instead", importc: "tgamma", header: "<math.h>".}
+      ## The gamma function
+      ## **Deprecated since version 0.19.0**: Use ``gamma`` instead.
+    proc lgamma*(x: float32): float32 {.importc: "lgammaf", header: "<math.h>".}
+    proc lgamma*(x: float64): float64 {.importc: "lgamma", header: "<math.h>".}
+      ## Natural log of the gamma function
 
   proc floor*(x: float32): float32 {.importc: "floorf", header: "<math.h>".}
   proc floor*(x: float64): float64 {.importc: "floor", header: "<math.h>".}
@@ -314,7 +315,7 @@ when not defined(JS): # C
     ## .. code-block:: nim
     ##  echo ceil(-2.1) ## -2.0
 
-  when defined(windows) and (defined(vcc) or defined(bcc)):
+  when windowsCC89:
     # MSVC 2010 don't have trunc/truncf
     # this implementation was inspired by Go-lang Math.Trunc
     proc truncImpl(f: float64): float64 =
@@ -452,6 +453,28 @@ when not defined(JS):
     var exp: int32
     result = c_frexp(x, exp)
     exponent = exp
+
+  when windowsCC89:
+    # taken from Go-lang Math.Log2
+    const ln2 = 0.693147180559945309417232121458176568075500134360255254120680009
+    template log2Impl[T](x: T): T =
+      var exp: int32
+      var frac = frexp(x, exp)
+      # Make sure exact powers of two give an exact answer.
+      # Don't depend on Log(0.5)*(1/Ln2)+exp being exactly exp-1.
+      if frac == 0.5: return T(exp - 1)
+      log10(frac)*(1/ln2) + T(exp)
+
+    proc log2*(x: float32): float32 = log2Impl(x)
+    proc log2*(x: float64): float64 = log2Impl(x)
+      ## Log2 returns the binary logarithm of x.
+      ## The special cases are the same as for Log.
+
+  else:
+    proc log2*(x: float32): float32 {.importc: "log2f", header: "<math.h>".}
+    proc log2*(x: float64): float64 {.importc: "log2", header: "<math.h>".}
+      ## Computes the binary logarithm (base 2) of `x`
+
 else:
   proc frexp*[T: float32|float64](x: T, exponent: var int): T =
     if x == 0.0:
@@ -564,7 +587,7 @@ proc lcm*[T](x, y: T): T =
   ## Computes the least common multiple of ``x`` and ``y``.
   x div gcd(x, y) * y
 
-when isMainModule and not defined(JS):
+when isMainModule and not defined(JS) and not windowsCC89:
   # Check for no side effect annotation
   proc mySqrt(num: float): float {.noSideEffect.} =
     return sqrt(num)
@@ -692,3 +715,14 @@ when isMainModule:
 
   block: # log
     doAssert log(4.0, 3.0) == ln(4.0) / ln(3.0)
+    doAssert log2(8.0'f64) == 3.0'f64
+    doAssert log2(4.0'f64) == 2.0'f64
+    doAssert log2(2.0'f64) == 1.0'f64
+    doAssert log2(1.0'f64) == 0.0'f64
+    doAssert classify(log2(0.0'f64)) == fcNegInf
+
+    doAssert log2(8.0'f32) == 3.0'f32
+    doAssert log2(4.0'f32) == 2.0'f32
+    doAssert log2(2.0'f32) == 1.0'f32
+    doAssert log2(1.0'f32) == 0.0'f32
+    doAssert classify(log2(0.0'f32)) == fcNegInf
diff --git a/lib/system.nim b/lib/system.nim
index 0cfa39e19..53605f9fd 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -971,6 +971,23 @@ else:
   proc `shl`*(x, y: int32): int32 {.magic: "ShlI", noSideEffect.}
   proc `shl`*(x, y: int64): int64 {.magic: "ShlI", noSideEffect.}
 
+when defined(nimAshr):
+  proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.}
+  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.}
+    ## Shifts right by pushing copies of the leftmost bit in from the left,
+    ## and let the rightmost bits fall off.
+    ##
+    ## .. code-block:: Nim
+    ##   0b0001_0000'i8 shr 2 == 0b0000_0100'i8
+    ##   0b1000_0000'i8 shr 8 == 0b1111_1111'i8
+    ##   0b1000_0000'i8 shr 1 == 0b1100_0000'i8
+else:
+  # used for bootstrapping the compiler
+  proc ashr*[T](x: T, y: SomeInteger): T = discard
+
 proc `and`*(x, y: int): int {.magic: "BitandI", noSideEffect.}
 proc `and`*(x, y: int8): int8 {.magic: "BitandI", noSideEffect.}
 proc `and`*(x, y: int16): int16 {.magic: "BitandI", noSideEffect.}
@@ -1978,7 +1995,7 @@ when sizeof(int) <= 2:
 else:
   type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16|enum
 
-iterator countdown*[T](a, b: T, step = 1): T {.inline.} =
+iterator countdown*[T](a, b: T, step: Positive = 1): T {.inline.} =
   ## Counts from ordinal value `a` down to `b` (inclusive) with the given
   ## step count. `T` may be any ordinal type, `step` may only
   ## be positive. **Note**: This fails to count to ``low(int)`` if T = int for
@@ -2001,7 +2018,7 @@ iterator countdown*[T](a, b: T, step = 1): T {.inline.} =
       dec(res, step)
 
 when defined(nimNewRoof):
-  iterator countup*[T](a, b: T, step = 1): T {.inline.} =
+  iterator countup*[T](a, b: T, step: Positive = 1): T {.inline.} =
     ## Counts from ordinal value `a` up to `b` (inclusive) with the given
     ## step count. `S`, `T` may be any ordinal type, `step` may only
     ## be positive. **Note**: This fails to count to ``high(int)`` if T = int for
@@ -2018,7 +2035,7 @@ when defined(nimNewRoof):
         inc(res, step)
 
   iterator `..`*[T](a, b: T): T {.inline.} =
-    ## An alias for `countup`.
+    ## An alias for `countup(a, b, 1)`.
     when T is IntLikeForCount:
       var res = int(a)
       while res <= int(b):
diff --git a/lib/system/gc_common.nim b/lib/system/gc_common.nim
index dcea0c4cc..88e150cd1 100644
--- a/lib/system/gc_common.nim
+++ b/lib/system/gc_common.nim
@@ -37,22 +37,28 @@ when defined(nimTypeNames):
         a[j] = v
       if h == 1: break
 
-  proc dumpNumberOfInstances* =
-    # also add the allocated strings to the list of known types:
+  iterator dumpHeapInstances*(): tuple[name: cstring; count: int; sizes: int] =
+    ## Iterate over summaries of types on heaps.
+    ## This data may be inaccurate if allocations
+    ## are made by the iterator body.
     if strDesc.nextType == nil:
       strDesc.nextType = nimTypeRoot
       strDesc.name = "string"
       nimTypeRoot = addr strDesc
+    var it = nimTypeRoot
+    while it != nil:
+      if (it.instances > 0 or it.sizes != 0):
+        yield (it.name, it.instances, it.sizes)
+      it = it.nextType
+
+  proc dumpNumberOfInstances* =
     var a: InstancesInfo
     var n = 0
-    var it = nimTypeRoot
     var totalAllocated = 0
-    while it != nil:
-      if (it.instances > 0 or it.sizes != 0) and n < a.len:
-        a[n] = (it.name, it.instances, it.sizes)
-        inc n
+    for it in dumpHeapInstances():
+      a[n] = it
+      inc n
       inc totalAllocated, it.sizes
-      it = it.nextType
     sortInstances(a, n)
     for i in 0 .. n-1:
       c_fprintf(stdout, "[Heap] %s: #%ld; bytes: %ld\n", a[i][0], a[i][1], a[i][2])
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index 3263f1d37..60a6e5d9b 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -396,7 +396,7 @@ else:
 
   proc moveFileA*(lpExistingFileName, lpNewFileName: cstring): WINBOOL {.
     importc: "MoveFileA", stdcall, dynlib: "kernel32".}
-  proc moveFileExA*(lpExistingFileName, lpNewFileName: WideCString,
+  proc moveFileExA*(lpExistingFileName, lpNewFileName: cstring,
                     flags: DWORD): WINBOOL {.
     importc: "MoveFileExA", stdcall, dynlib: "kernel32".}
 
diff --git a/tests/arithm/tashr.nim b/tests/arithm/tashr.nim
new file mode 100644
index 000000000..aeb3b6843
--- /dev/null
+++ b/tests/arithm/tashr.nim
@@ -0,0 +1,46 @@
+discard """
+  output: ''''''
+  targets: '''c js'''
+"""
+
+# issue #6255, feature request
+# arithmetic right shift
+
+var x1 = -123'i8
+var x2 = -123'i16
+var x3 = -123'i32
+var x4 = -123'i64
+var x5 = -123
+
+block codegen_test:
+  doAssert ashr(x1, 1) == -62
+  doAssert ashr(x2, 1) == -62
+  doAssert ashr(x3, 1) == -62
+  doAssert ashr(x4, 1) == -62
+  doAssert ashr(x5, 1) == -62
+
+block semfold_test:
+  doAssert ashr(-123'i8 , 1) == -62
+  doAssert ashr(-123'i16, 1) == -62
+  doAssert ashr(-123'i32, 1) == -62
+  doAssert ashr(-123'i64, 1) == -62
+  doAssert ashr(-123    , 1) == -62
+
+static: # VM test
+  doAssert ashr(-123'i8 , 1) == -62
+  doAssert ashr(-123'i16, 1) == -62
+  doAssert ashr(-123'i32, 1) == -62
+  doAssert ashr(-123'i64, 1) == -62
+  doAssert ashr(-123    , 1) == -62
+
+  var y1 = -123'i8
+  var y2 = -123'i16
+  var y3 = -123'i32
+  var y4 = -123'i64
+  var y5 = -123
+
+  doAssert ashr(y1, 1) == -62
+  doAssert ashr(y2, 1) == -62
+  doAssert ashr(y3, 1) == -62
+  doAssert ashr(y4, 1) == -62
+  doAssert ashr(y5, 1) == -62
diff --git a/tests/concepts/t3330.nim b/tests/concepts/t3330.nim
index 78dd876e2..8021db827 100644
--- a/tests/concepts/t3330.nim
+++ b/tests/concepts/t3330.nim
@@ -13,15 +13,11 @@ proc add(result: var string; x: float)
   first type mismatch at position: 1
   required type: var string
   but expression 'k' is of type: Alias
-proc add(x: var string; y: cstring)
-  first type mismatch at position: 1
-  required type: var string
-  but expression 'k' is of type: Alias
-proc add(x: var string; y: char)
+proc add(x: var string; y: string)
   first type mismatch at position: 1
   required type: var string
   but expression 'k' is of type: Alias
-proc add(x: var string; y: string)
+proc add(x: var string; y: cstring)
   first type mismatch at position: 1
   required type: var string
   but expression 'k' is of type: Alias
@@ -33,6 +29,10 @@ proc add(result: var string; x: int64)
   first type mismatch at position: 1
   required type: var string
   but expression 'k' is of type: Alias
+proc add(x: var string; y: char)
+  first type mismatch at position: 1
+  required type: var string
+  but expression 'k' is of type: Alias
 
 t3330.nim(48, 8) template/generic instantiation from here
 t3330.nim(55, 6) Foo: 'bar.value' cannot be assigned to