summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorOscar Campbell <oscar@campbell.nu>2015-06-07 13:16:08 +0200
committerOscar Campbell <oscar@campbell.nu>2015-06-07 13:16:08 +0200
commit858cdd0b05df4846fb40a3263f05e54438995e99 (patch)
tree939fb5e27650e4e7a24698b3c3dac5acada396b1
parent87a6d08e95c940775577c8f2bc5a74408c956a89 (diff)
parentbbb1bdb4a939aa43ed981acc2f96bce918be7d21 (diff)
downloadNim-858cdd0b05df4846fb40a3263f05e54438995e99.tar.gz
Merge remote-tracking branch 'upstream/devel' into devel
-rwxr-xr-x[-rw-r--r--]bootstrap.sh0
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/ccgexprs.nim2
-rw-r--r--compiler/cgen.nim2
-rw-r--r--compiler/msgs.nim6
-rw-r--r--compiler/semcall.nim5
-rw-r--r--compiler/sempass2.nim10
-rw-r--r--lib/core/typeinfo.nim2
-rw-r--r--lib/pure/algorithm.nim24
-rw-r--r--lib/pure/asyncnet.nim6
-rw-r--r--lib/pure/concurrency/cpuload.nim10
-rw-r--r--lib/pure/fsmonitor.nim8
-rw-r--r--lib/pure/net.nim6
-rw-r--r--lib/system/arithm.nim176
-rw-r--r--lib/wrappers/libffi/libffi.nim2
-rw-r--r--lib/wrappers/readline/readline.nim44
-rw-r--r--lib/wrappers/sdl/sdl.nim56
-rw-r--r--tests/enum/tenumitems.nim2
-rw-r--r--tests/misc/tissue710.nim2
-rw-r--r--tests/misc/tnoop.nim2
-rw-r--r--tests/modules/topaque.nim8
-rw-r--r--tests/parallel/tptr_to_ref.nim26
-rw-r--r--tests/tuples/twrongtupleaccess.nim2
-rw-r--r--tests/vm/tconstobj.nim14
-rw-r--r--tools/niminst/niminst.nim2
25 files changed, 278 insertions, 141 deletions
diff --git a/bootstrap.sh b/bootstrap.sh
index ade74a9aa..ade74a9aa 100644..100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
diff --git a/compiler/ast.nim b/compiler/ast.nim
index c349f81ed..c141352cb 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -1346,7 +1346,7 @@ proc propagateToOwner*(owner, elem: PType) =
       owner.flags.incl tfHasAsgn
 
   if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
-                       tyGenericInvocation}:
+                       tyGenericInvocation, tyPtr}:
     let elemB = elem.skipTypes({tyGenericInst})
     if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
       # for simplicity, we propagate this flag even to generics. We then
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 05a3602d1..64902c3fc 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -2150,7 +2150,7 @@ proc genNamedConstExpr(p: BProc, n: PNode): Rope =
 proc genConstSimpleList(p: BProc, n: PNode): Rope =
   var length = sonsLen(n)
   result = rope("{")
-  for i in countup(0, length - 2):
+  for i in countup(ord(n.kind == nkObjConstr), length - 2):
     addf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])])
   if length > 0: add(result, genNamedConstExpr(p, n.sons[length - 1]))
   addf(result, "}$n", [])
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 4b0bac28a..91877833a 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -721,6 +721,8 @@ proc genProcPrototype(m: BModule, sym: PSym) =
                         getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
   elif not containsOrIncl(m.declaredProtos, sym.id):
     var header = genProcHeader(m, sym)
+    if sfNoReturn in sym.flags and hasDeclspec in extccomp.CC[cCompiler].props:
+      header = "__declspec(noreturn) " & header
     if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
       header = "extern \"C\" " & header
     if sfPure in sym.flags and hasAttribute in CC[cCompiler].props:
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index e97032db4..81a62371e 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -34,7 +34,9 @@ type
     errNoneSpeedOrSizeExpectedButXFound, errGuiConsoleOrLibExpectedButXFound,
     errUnknownOS, errUnknownCPU, errGenOutExpectedButXFound,
     errArgsNeedRunOption, errInvalidMultipleAsgn, errColonOrEqualsExpected,
-    errExprExpected, errUndeclaredIdentifier, errUseQualifier, errTypeExpected,
+    errExprExpected, errUndeclaredIdentifier, errUndeclaredField,
+    errUndeclaredRoutine, errUseQualifier,
+    errTypeExpected,
     errSystemNeeds, errExecutionOfProgramFailed, errNotOverloadable,
     errInvalidArgForX, errStmtHasNoEffect, errXExpectsTypeOrValue,
     errXExpectsArrayType, errIteratorCannotBeInstantiated, errExprXAmbiguous,
@@ -190,6 +192,8 @@ const
     errColonOrEqualsExpected: "\':\' or \'=\' expected, but found \'$1\'",
     errExprExpected: "expression expected, but found \'$1\'",
     errUndeclaredIdentifier: "undeclared identifier: \'$1\'",
+    errUndeclaredField: "undeclared field: \'$1\'",
+    errUndeclaredRoutine: "attempting to call undeclared routine: \'$1\'",
     errUseQualifier: "ambiguous identifier: \'$1\' -- use a qualifier",
     errTypeExpected: "type expected",
     errSystemNeeds: "system module needs \'$1\'",
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index c48e761e3..571504c3a 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -209,7 +209,10 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
       pickBest(callOp)
 
     if overloadsState == csEmpty and result.state == csEmpty:
-      localError(n.info, errUndeclaredIdentifier, considerQuotedIdent(f).s)
+      if nfDotField in n.flags and nfExplicitCall notin n.flags:
+        localError(n.info, errUndeclaredField, considerQuotedIdent(f).s)
+      else:
+        localError(n.info, errUndeclaredRoutine, considerQuotedIdent(f).s)
       return
     elif result.state != csMatch:
       if nfExprCall in n.flags:
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index adf03be64..12c4a7c7b 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -207,9 +207,9 @@ proc markGcUnsafe(a: PEffects; reason: PNode) =
       a.owner.gcUnsafetyReason = newSym(skUnknown, getIdent("<unknown>"),
                                         a.owner, reason.info)
 
-proc listGcUnsafety(s: PSym; onlyWarning: bool) =
+proc listGcUnsafety(s: PSym; onlyWarning: bool; cycleCheck: var IntSet) =
   let u = s.gcUnsafetyReason
-  if u != nil:
+  if u != nil and not cycleCheck.containsOrIncl(u.id):
     let msgKind = if onlyWarning: warnGcUnsafe2 else: errGenerated
     if u.kind in {skLet, skVar}:
       message(s.info, msgKind,
@@ -218,7 +218,7 @@ proc listGcUnsafety(s: PSym; onlyWarning: bool) =
     elif u.kind in routineKinds:
       # recursive call *always* produces only a warning so the full error
       # message is printed:
-      listGcUnsafety(u, true)
+      listGcUnsafety(u, true, cycleCheck)
       message(s.info, msgKind,
         "'$#' is not GC-safe as it calls '$#'" %
         [s.name.s, u.name.s])
@@ -227,6 +227,10 @@ proc listGcUnsafety(s: PSym; onlyWarning: bool) =
       message(u.info, msgKind,
         "'$#' is not GC-safe as it performs an indirect call here" % s.name.s)
 
+proc listGcUnsafety(s: PSym; onlyWarning: bool) =
+  var cycleCheck = initIntSet()
+  listGcUnsafety(s, onlyWarning, cycleCheck)
+
 proc useVar(a: PEffects, n: PNode) =
   let s = n.sym
   if isLocalVar(a, s):
diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim
index d7fa2ec9b..ab150b2a4 100644
--- a/lib/core/typeinfo.nim
+++ b/lib/core/typeinfo.nim
@@ -340,6 +340,8 @@ proc `[]`*(x: Any, fieldName: string): Any =
   if n != nil:
     result.value = x.value +!! n.offset
     result.rawType = n.typ
+  elif x.rawType.kind == tyObject and x.rawType.base != nil:
+    return `[]`(TAny(value: x.value, rawType: x.rawType.base), fieldName)
   else:
     raise newException(ValueError, "invalid field name: " & fieldName)
 
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index 0eafb316a..c9f779018 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -99,16 +99,13 @@ proc lowerBound*[T](a: openArray[T], key: T, cmp: proc(x,y: T): int {.closure.})
   ##   arr.insert(4, arr.lowerBound(4))
   ## `after running the above arr is `[1,2,3,4,5,6,7,8,9]`
   result = a.low
-  var pos = result
-  var count, step: int
-  count = a.high - a.low + 1
+  var count = a.high - a.low + 1
+  var step, pos: int
   while count != 0:
-    pos = result
     step = count div 2
-    pos += step
+    pos = result + step
     if cmp(a[pos], key) < 0:
-      pos.inc
-      result = pos
+      result = pos + 1
       count -= step + 1
     else:
       count = step
@@ -331,3 +328,16 @@ proc prevPermutation*[T](x: var openarray[T]): bool {.discardable.} =
   swap x[i-1], x[j]
 
   result = true
+
+when isMainModule:
+  # Tests for lowerBound
+  var arr = @[1,2,3,5,6,7,8,9]
+  assert arr.lowerBound(0) == 0
+  assert arr.lowerBound(4) == 3
+  assert arr.lowerBound(5) == 3
+  assert arr.lowerBound(10) == 8
+  arr = @[1,5,10]
+  assert arr.lowerBound(4) == 1
+  assert arr.lowerBound(5) == 1
+  assert arr.lowerBound(6) == 2
+
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim
index d44e5d31f..01c28a13a 100644
--- a/lib/pure/asyncnet.nim
+++ b/lib/pure/asyncnet.nim
@@ -91,13 +91,13 @@ type
 
 # TODO: Save AF, domain etc info and reuse it in procs which need it like connect.
 
-proc newAsyncSocket*(fd: AsyncFD, isBuff: bool): AsyncSocket =
+proc newAsyncSocket*(fd: AsyncFD, buffered = true): AsyncSocket =
   ## Creates a new ``AsyncSocket`` based on the supplied params.
   assert fd != osInvalidSocket.AsyncFD
   new(result)
   result.fd = fd.SocketHandle
-  result.isBuffered = isBuff
-  if isBuff:
+  result.isBuffered = buffered
+  if buffered:
     result.currPos = 0
 
 proc newAsyncSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM,
diff --git a/lib/pure/concurrency/cpuload.nim b/lib/pure/concurrency/cpuload.nim
index 1f3f54056..22598b5c9 100644
--- a/lib/pure/concurrency/cpuload.nim
+++ b/lib/pure/concurrency/cpuload.nim
@@ -13,7 +13,7 @@
 when defined(windows):
   import winlean, os, strutils, math
 
-  proc `-`(a, b: TFILETIME): int64 = a.rdFileTime - b.rdFileTime
+  proc `-`(a, b: FILETIME): int64 = a.rdFileTime - b.rdFileTime
 elif defined(linux):
   from cpuinfo import countProcessors
 
@@ -25,16 +25,16 @@ type
 
   ThreadPoolState* = object
     when defined(windows):
-      prevSysKernel, prevSysUser, prevProcKernel, prevProcUser: TFILETIME
+      prevSysKernel, prevSysUser, prevProcKernel, prevProcUser: FILETIME
     calls*: int
 
 proc advice*(s: var ThreadPoolState): ThreadPoolAdvice =
   when defined(windows):
     var
       sysIdle, sysKernel, sysUser,
-        procCreation, procExit, procKernel, procUser: TFILETIME
+        procCreation, procExit, procKernel, procUser: FILETIME
     if getSystemTimes(sysIdle, sysKernel, sysUser) == 0 or
-        getProcessTimes(Handle(-1), procCreation, procExit, 
+        getProcessTimes(Handle(-1), procCreation, procExit,
                         procKernel, procUser) == 0:
       return doNothing
     if s.calls > 0:
@@ -57,7 +57,7 @@ proc advice*(s: var ThreadPoolState): ThreadPoolAdvice =
     s.prevProcKernel = procKernel
     s.prevProcUser = procUser
   elif defined(linux):
-    proc fscanf(c: File, frmt: cstring) {.varargs, importc, 
+    proc fscanf(c: File, frmt: cstring) {.varargs, importc,
       header: "<stdio.h>".}
 
     var f = open("/proc/loadavg")
diff --git a/lib/pure/fsmonitor.nim b/lib/pure/fsmonitor.nim
index 83779eb9c..229df80b5 100644
--- a/lib/pure/fsmonitor.nim
+++ b/lib/pure/fsmonitor.nim
@@ -108,7 +108,7 @@ proc del*(monitor: FSMonitor, wd: cint) =
 
 proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
   result = @[]
-  let size = (sizeof(TINotifyEvent)+2000)*MaxEvents
+  let size = (sizeof(INotifyEvent)+2000)*MaxEvents
   var buffer = newString(size)
 
   let le = read(fd, addr(buffer[0]), size)
@@ -117,7 +117,7 @@ proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
 
   var i = 0
   while i < le:
-    var event = cast[ptr TINotifyEvent](addr(buffer[i]))
+    var event = cast[ptr INotifyEvent](addr(buffer[i]))
     var mev: MonitorEvent
     mev.wd = event.wd
     if event.len.int != 0:
@@ -129,7 +129,7 @@ proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
     if (event.mask.int and IN_MOVED_FROM) != 0: 
       # Moved from event, add to m's collection
       movedFrom.add(event.cookie.cint, (mev.wd, mev.name))
-      inc(i, sizeof(TINotifyEvent) + event.len.int)
+      inc(i, sizeof(INotifyEvent) + event.len.int)
       continue
     elif (event.mask.int and IN_MOVED_TO) != 0: 
       mev.kind = MonitorMoved
@@ -159,7 +159,7 @@ proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
       mev.fullname = ""
     
     result.add(mev)
-    inc(i, sizeof(TINotifyEvent) + event.len.int)
+    inc(i, sizeof(INotifyEvent) + event.len.int)
 
   # If movedFrom events have not been matched with a moveTo. File has
   # been moved to an unwatched location, emit a MonitorDelete.
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 49ca12098..9ce0669bc 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -119,13 +119,13 @@ proc toOSFlags*(socketFlags: set[SocketFlag]): cint =
       result = result or MSG_PEEK
     of SocketFlag.SafeDisconn: continue
 
-proc newSocket(fd: SocketHandle, isBuff: bool): Socket =
+proc newSocket*(fd: SocketHandle, buffered = true): Socket =
   ## Creates a new socket as specified by the params.
   assert fd != osInvalidSocket
   new(result)
   result.fd = fd
-  result.isBuffered = isBuff
-  if isBuff:
+  result.isBuffered = buffered
+  if buffered:
     result.currPos = 0
 
 proc newSocket*(domain, typ, protocol: cint, buffered = true): Socket =
diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim
index ef153417c..907907e24 100644
--- a/lib/system/arithm.nim
+++ b/lib/system/arithm.nim
@@ -17,17 +17,114 @@ proc raiseOverflow {.compilerproc, noinline.} =
 proc raiseDivByZero {.compilerproc, noinline.} =
   sysFatal(DivByZeroError, "division by zero")
 
-proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
-  result = a +% b
-  if (result xor a) >= int64(0) or (result xor b) >= int64(0):
-    return result
-  raiseOverflow()
+when defined(builtinOverflow):
+# Builtin compiler functions for improved performance
+  when sizeof(clong) == 8:
+    proc addInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
+      importc: "__builtin_saddl_overflow", nodecl, nosideeffect.}
 
-proc subInt64(a, b: int64): int64 {.compilerProc, inline.} =
-  result = a -% b
-  if (result xor a) >= int64(0) or (result xor not b) >= int64(0):
-    return result
-  raiseOverflow()
+    proc subInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
+      importc: "__builtin_ssubl_overflow", nodecl, nosideeffect.}
+
+    proc mulInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
+      importc: "__builtin_smull_overflow", nodecl, nosideeffect.}
+
+  elif sizeof(clonglong) == 8:
+    proc addInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
+      importc: "__builtin_saddll_overflow", nodecl, nosideeffect.}
+
+    proc subInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
+      importc: "__builtin_ssubll_overflow", nodecl, nosideeffect.}
+
+    proc mulInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
+      importc: "__builtin_smulll_overflow", nodecl, nosideeffect.}
+
+  when sizeof(int) == 8:
+    proc addIntOverflow(a, b: int, c: var int): bool {.inline.} =
+      addInt64Overflow(a, b, c)
+
+    proc subIntOverflow(a, b: int, c: var int): bool {.inline.} =
+      subInt64Overflow(a, b, c)
+
+    proc mulIntOverflow(a, b: int, c: var int): bool {.inline.} =
+      mulInt64Overflow(a, b, c)
+
+  elif sizeof(int) == 4 and sizeof(cint) == 4:
+    proc addIntOverflow(a, b: int, c: var int): bool {.
+      importc: "__builtin_sadd_overflow", nodecl, nosideeffect.}
+
+    proc subIntOverflow(a, b: int, c: var int): bool {.
+      importc: "__builtin_ssub_overflow", nodecl, nosideeffect.}
+
+    proc mulIntOverflow(a, b: int, c: var int): bool {.
+      importc: "__builtin_smul_overflow", nodecl, nosideeffect.}
+
+  proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
+    if addInt64Overflow(a, b, result):
+      raiseOverflow()
+
+  proc subInt64(a, b: int64): int64 {.compilerProc, inline.} =
+    if subInt64Overflow(a, b, result):
+      raiseOverflow()
+
+  proc mulInt64(a, b: int64): int64 {.compilerproc, inline.} =
+    if mulInt64Overflow(a, b, result):
+      raiseOverflow()
+else:
+  proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
+    result = a +% b
+    if (result xor a) >= int64(0) or (result xor b) >= int64(0):
+      return result
+    raiseOverflow()
+
+  proc subInt64(a, b: int64): int64 {.compilerProc, inline.} =
+    result = a -% b
+    if (result xor a) >= int64(0) or (result xor not b) >= int64(0):
+      return result
+    raiseOverflow()
+
+  #
+  # This code has been inspired by Python's source code.
+  # The native int product x*y is either exactly right or *way* off, being
+  # just the last n bits of the true product, where n is the number of bits
+  # in an int (the delivered product is the true product plus i*2**n for
+  # some integer i).
+  #
+  # The native float64 product x*y is subject to three
+  # rounding errors: on a sizeof(int)==8 box, each cast to double can lose
+  # info, and even on a sizeof(int)==4 box, the multiplication can lose info.
+  # But, unlike the native int product, it's not in *range* trouble:  even
+  # if sizeof(int)==32 (256-bit ints), the product easily fits in the
+  # dynamic range of a float64. So the leading 50 (or so) bits of the float64
+  # product are correct.
+  #
+  # We check these two ways against each other, and declare victory if they're
+  # approximately the same. Else, because the native int product is the only
+  # one that can lose catastrophic amounts of information, it's the native int
+  # product that must have overflowed.
+  #
+  proc mulInt64(a, b: int64): int64 {.compilerproc.} =
+    var
+      resAsFloat, floatProd: float64
+    result = a *% b
+    floatProd = toBiggestFloat(a) # conversion
+    floatProd = floatProd * toBiggestFloat(b)
+    resAsFloat = toBiggestFloat(result)
+
+    # Fast path for normal case: small multiplicands, and no info
+    # is lost in either method.
+    if resAsFloat == floatProd: return result
+
+    # Somebody somewhere lost info. Close enough, or way off? Note
+    # that a != 0 and b != 0 (else resAsFloat == floatProd == 0).
+    # The difference either is or isn't significant compared to the
+    # true value (of which floatProd is a good approximation).
+
+    # abs(diff)/abs(prod) <= 1/32 iff
+    #   32 * abs(diff) <= abs(prod) -- 5 good bits is "close enough"
+    if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
+      return result
+    raiseOverflow()
 
 proc negInt64(a: int64): int64 {.compilerProc, inline.} =
   if a != low(int64): return -a
@@ -51,50 +148,6 @@ proc modInt64(a, b: int64): int64 {.compilerProc, inline.} =
     raiseDivByZero()
   return a mod b
 
-#
-# This code has been inspired by Python's source code.
-# The native int product x*y is either exactly right or *way* off, being
-# just the last n bits of the true product, where n is the number of bits
-# in an int (the delivered product is the true product plus i*2**n for
-# some integer i).
-#
-# The native float64 product x*y is subject to three
-# rounding errors: on a sizeof(int)==8 box, each cast to double can lose
-# info, and even on a sizeof(int)==4 box, the multiplication can lose info.
-# But, unlike the native int product, it's not in *range* trouble:  even
-# if sizeof(int)==32 (256-bit ints), the product easily fits in the
-# dynamic range of a float64. So the leading 50 (or so) bits of the float64
-# product are correct.
-#
-# We check these two ways against each other, and declare victory if they're
-# approximately the same. Else, because the native int product is the only
-# one that can lose catastrophic amounts of information, it's the native int
-# product that must have overflowed.
-#
-proc mulInt64(a, b: int64): int64 {.compilerproc.} =
-  var
-    resAsFloat, floatProd: float64
-  result = a *% b
-  floatProd = toBiggestFloat(a) # conversion
-  floatProd = floatProd * toBiggestFloat(b)
-  resAsFloat = toBiggestFloat(result)
-
-  # Fast path for normal case: small multiplicands, and no info
-  # is lost in either method.
-  if resAsFloat == floatProd: return result
-
-  # Somebody somewhere lost info. Close enough, or way off? Note
-  # that a != 0 and b != 0 (else resAsFloat == floatProd == 0).
-  # The difference either is or isn't significant compared to the
-  # true value (of which floatProd is a good approximation).
-
-  # abs(diff)/abs(prod) <= 1/32 iff
-  #   32 * abs(diff) <= abs(prod) -- 5 good bits is "close enough"
-  if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
-    return result
-  raiseOverflow()
-
-
 proc absInt(a: int): int {.compilerProc, inline.} =
   if a != low(int):
     if a >= 0: return a
@@ -246,6 +299,21 @@ elif false: # asmVersion and (defined(gcc) or defined(llvm_gcc)):
             :"%edx"
     """
 
+when not declared(addInt) and defined(builtinOverflow):
+  proc addInt(a, b: int): int {.compilerProc, inline.} =
+    if addIntOverflow(a, b, result):
+      raiseOverflow()
+
+when not declared(subInt) and defined(builtinOverflow):
+  proc subInt(a, b: int): int {.compilerProc, inline.} =
+    if subIntOverflow(a, b, result):
+      raiseOverflow()
+
+when not declared(mulInt) and defined(builtinOverflow):
+  proc mulInt(a, b: int): int {.compilerProc, inline.} =
+    if mulIntOverflow(a, b, result):
+      raiseOverflow()
+
 # Platform independent versions of the above (slower!)
 when not declared(addInt):
   proc addInt(a, b: int): int {.compilerProc, inline.} =
diff --git a/lib/wrappers/libffi/libffi.nim b/lib/wrappers/libffi/libffi.nim
index d7e11a20c..34b91f8c7 100644
--- a/lib/wrappers/libffi/libffi.nim
+++ b/lib/wrappers/libffi/libffi.nim
@@ -60,7 +60,7 @@ else:
 type
   Arg* = int
   SArg* = int
-{deprecated: [TArg: Arg, TSArg: SArg].}
+{.deprecated: [TArg: Arg, TSArg: SArg].}
 
 when defined(windows) and defined(x86):
   type
diff --git a/lib/wrappers/readline/readline.nim b/lib/wrappers/readline/readline.nim
index 4173a0e0f..652808576 100644
--- a/lib/wrappers/readline/readline.nim
+++ b/lib/wrappers/readline/readline.nim
@@ -29,7 +29,7 @@ elif defined(macosx):
 else: 
   const 
     readlineDll* = "libreadline.so.6(|.0)"
-#  mangle "'TCommandFunc'" TCommandFunc
+#  mangle "'CommandFunc'" CommandFunc
 #  mangle TvcpFunc TvcpFunc
 
 import rltypedefs
@@ -80,7 +80,7 @@ const
 type 
   KEYMAP_ENTRY*{.pure, final.} = object 
     typ*: char
-    function*: TCommandFunc
+    function*: CommandFunc
 {.deprecated: [TKEYMAP_ENTRY: KEYMAP_ENTRY].}
 
 
@@ -243,7 +243,7 @@ when not defined(macosx):
 type 
   FUNMAP*{.pure, final.} = object 
     name*: cstring
-    function*: TCommandFunc
+    function*: CommandFunc
 {.deprecated: [TFUNMAP: FUNMAP].}
 
 
@@ -610,31 +610,31 @@ proc discard_argument*(): cint{.cdecl, importc: "rl_discard_argument",
                                 dynlib: readlineDll.}
 # Utility functions to bind keys to readline commands. 
 
-proc add_defun*(a2: cstring, a3: TCommandFunc, a4: cint): cint{.cdecl, 
+proc add_defun*(a2: cstring, a3: CommandFunc, a4: cint): cint{.cdecl, 
     importc: "rl_add_defun", dynlib: readlineDll.}
-proc bind_key*(a2: cint, a3: TCommandFunc): cint{.cdecl, 
+proc bind_key*(a2: cint, a3: CommandFunc): cint{.cdecl, 
     importc: "rl_bind_key", dynlib: readlineDll.}
-proc bind_key_in_map*(a2: cint, a3: TCommandFunc, a4: PKeymap): cint{.cdecl, 
+proc bind_key_in_map*(a2: cint, a3: CommandFunc, a4: PKeymap): cint{.cdecl, 
     importc: "rl_bind_key_in_map", dynlib: readlineDll.}
 proc unbind_key*(a2: cint): cint{.cdecl, importc: "rl_unbind_key", 
                                   dynlib: readlineDll.}
 proc unbind_key_in_map*(a2: cint, a3: PKeymap): cint{.cdecl, 
     importc: "rl_unbind_key_in_map", dynlib: readlineDll.}
-proc bind_key_if_unbound*(a2: cint, a3: TCommandFunc): cint{.cdecl, 
+proc bind_key_if_unbound*(a2: cint, a3: CommandFunc): cint{.cdecl, 
     importc: "rl_bind_key_if_unbound", dynlib: readlineDll.}
-proc bind_key_if_unbound_in_map*(a2: cint, a3: TCommandFunc, a4: PKeymap): cint{.
+proc bind_key_if_unbound_in_map*(a2: cint, a3: CommandFunc, a4: PKeymap): cint{.
     cdecl, importc: "rl_bind_key_if_unbound_in_map", dynlib: readlineDll.}
-proc unbind_function_in_map*(a2: TCommandFunc, a3: PKeymap): cint{.cdecl, 
+proc unbind_function_in_map*(a2: CommandFunc, a3: PKeymap): cint{.cdecl, 
     importc: "rl_unbind_function_in_map", dynlib: readlineDll.}
 proc unbind_command_in_map*(a2: cstring, a3: PKeymap): cint{.cdecl, 
     importc: "rl_unbind_command_in_map", dynlib: readlineDll.}
-proc bind_keyseq*(a2: cstring, a3: TCommandFunc): cint{.cdecl, 
+proc bind_keyseq*(a2: cstring, a3: CommandFunc): cint{.cdecl, 
     importc: "rl_bind_keyseq", dynlib: readlineDll.}
-proc bind_keyseq_in_map*(a2: cstring, a3: TCommandFunc, a4: PKeymap): cint{.
+proc bind_keyseq_in_map*(a2: cstring, a3: CommandFunc, a4: PKeymap): cint{.
     cdecl, importc: "rl_bind_keyseq_in_map", dynlib: readlineDll.}
-proc bind_keyseq_if_unbound*(a2: cstring, a3: TCommandFunc): cint{.cdecl, 
+proc bind_keyseq_if_unbound*(a2: cstring, a3: CommandFunc): cint{.cdecl, 
     importc: "rl_bind_keyseq_if_unbound", dynlib: readlineDll.}
-proc bind_keyseq_if_unbound_in_map*(a2: cstring, a3: TCommandFunc, 
+proc bind_keyseq_if_unbound_in_map*(a2: cstring, a3: CommandFunc, 
                                     a4: PKeymap): cint{.cdecl, 
     importc: "rl_bind_keyseq_if_unbound_in_map", dynlib: readlineDll.}
 proc generic_bind*(a2: cint, a3: cstring, a4: cstring, a5: PKeymap): cint{.
@@ -645,7 +645,7 @@ proc variable_bind*(a2: cstring, a3: cstring): cint{.cdecl,
     importc: "rl_variable_bind", dynlib: readlineDll.}
 # Backwards compatibility, use rl_bind_keyseq_in_map instead. 
 
-proc set_key*(a2: cstring, a3: TCommandFunc, a4: PKeymap): cint{.cdecl, 
+proc set_key*(a2: cstring, a3: CommandFunc, a4: PKeymap): cint{.cdecl, 
     importc: "rl_set_key", dynlib: readlineDll.}
 # Backwards compatibility, use rl_generic_bind instead. 
 
@@ -657,15 +657,15 @@ proc translate_keyseq*(a2: cstring, a3: cstring, a4: ptr cint): cint{.cdecl,
     importc: "rl_translate_keyseq", dynlib: readlineDll.}
 proc untranslate_keyseq*(a2: cint): cstring{.cdecl, 
     importc: "rl_untranslate_keyseq", dynlib: readlineDll.}
-proc named_function*(a2: cstring): TCommandFunc{.cdecl, 
+proc named_function*(a2: cstring): CommandFunc{.cdecl, 
     importc: "rl_named_function", dynlib: readlineDll.}
-proc function_of_keyseq*(a2: cstring, a3: PKeymap, a4: ptr cint): TCommandFunc{.
+proc function_of_keyseq*(a2: cstring, a3: PKeymap, a4: ptr cint): CommandFunc{.
     cdecl, importc: "rl_function_of_keyseq", dynlib: readlineDll.}
 proc list_funmap_names*(){.cdecl, importc: "rl_list_funmap_names", 
                            dynlib: readlineDll.}
-proc invoking_keyseqs_in_map*(a2: TCommandFunc, a3: PKeymap): cstringArray{.
+proc invoking_keyseqs_in_map*(a2: CommandFunc, a3: PKeymap): cstringArray{.
     cdecl, importc: "rl_invoking_keyseqs_in_map", dynlib: readlineDll.}
-proc invoking_keyseqs*(a2: TCommandFunc): cstringArray{.cdecl, 
+proc invoking_keyseqs*(a2: CommandFunc): cstringArray{.cdecl, 
     importc: "rl_invoking_keyseqs", dynlib: readlineDll.}
 proc function_dumper*(a2: cint){.cdecl, importc: "rl_function_dumper", 
                                  dynlib: readlineDll.}
@@ -688,7 +688,7 @@ proc get_keymap_name_from_edit_mode*(): cstring{.cdecl,
     importc: "rl_get_keymap_name_from_edit_mode", dynlib: readlineDll.}
 # Functions for manipulating the funmap, which maps command names to functions. 
 
-proc add_funmap_entry*(a2: cstring, a3: TCommandFunc): cint{.cdecl, 
+proc add_funmap_entry*(a2: cstring, a3: CommandFunc): cint{.cdecl, 
     importc: "rl_add_funmap_entry", dynlib: readlineDll.}
 proc funmap_names*(): cstringArray{.cdecl, importc: "rl_funmap_names", 
                                     dynlib: readlineDll.}
@@ -828,7 +828,7 @@ proc username_completion_function*(a2: cstring, a3: cint): cstring{.cdecl,
     importc: "rl_username_completion_function", dynlib: readlineDll.}
 proc filename_completion_function*(a2: cstring, a3: cint): cstring{.cdecl, 
     importc: "rl_filename_completion_function", dynlib: readlineDll.}
-proc completion_mode*(a2: TCommandFunc): cint{.cdecl, 
+proc completion_mode*(a2: CommandFunc): cint{.cdecl, 
     importc: "rl_completion_mode", dynlib: readlineDll.}
 # **************************************************************** 
 #								    
@@ -883,7 +883,7 @@ when false:
   # The current value of the numeric argument specified by the user. 
   var numeric_arg*{.importc: "rl_numeric_arg", dynlib: readlineDll.}: cint
   # The address of the last command function Readline executed. 
-  var last_func*{.importc: "rl_last_func", dynlib: readlineDll.}: TCommandFunc
+  var last_func*{.importc: "rl_last_func", dynlib: readlineDll.}: CommandFunc
   # The name of the terminal to use. 
   var terminal_name*{.importc: "rl_terminal_name", dynlib: readlineDll.}: cstring
   # The input and output streams. 
@@ -1186,7 +1186,7 @@ type
     rlstate*: cint
     done*: cint
     kmap*: PKeymap            # input state 
-    lastfunc*: TCommandFunc
+    lastfunc*: CommandFunc
     insmode*: cint
     edmode*: cint
     kseqlen*: cint
diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim
index 707c65a53..376de8e08 100644
--- a/lib/wrappers/sdl/sdl.nim
+++ b/lib/wrappers/sdl/sdl.nim
@@ -775,7 +775,7 @@ type
   Arg*{.final.} = object 
     buf*: array[0..ERR_MAX_STRLEN - 1, int8]
 
-  Perror* = ptr Terror
+  Perror* = ptr Error
   Error*{.final.} = object   # This is a numeric value corresponding to the current error
                              # SDL_rwops.h types
                              # This is the read/write operation structure -- very basic
@@ -814,7 +814,7 @@ type
     theType*: cint
     mem*: Mem
   
-  RWops* = RWops              # SDL_timer.h types
+                              # SDL_timer.h types
                               # Function prototype for the timer callback function
   TimerCallback* = proc (interval: int32): int32{.cdecl.}
   NewTimerCallback* = proc (interval: int32, param: pointer): int32{.cdecl.}
@@ -950,8 +950,8 @@ type
   EventAction* = enum        # Application visibility event structure
     ADDEVENT, PEEKEVENT, GETEVENT
 
-  PActiveEvent* = ptr ActiveEvent
-  ActiveEvent*{.final.} = object  # SDL_ACTIVEEVENT
+  PActiveEvent* = ptr TActiveEvent
+  TActiveEvent*{.final.} = object  # SDL_ACTIVEEVENT
                                    # Keyboard event structure
     kind*: EventKind
     gain*: byte              # Whether given states were gained or lost (1/0)
@@ -1032,8 +1032,8 @@ type
     w*: cint                   # New width
     h*: cint                   # New height
   
-  PUserEvent* = ptr UserEvent
-  UserEvent*{.final.} = object  # SDL_USEREVENT through SDL_NUMEVENTS-1
+  PUserEvent* = ptr TUserEvent
+  TUserEvent*{.final.} = object  # SDL_USEREVENT through SDL_NUMEVENTS-1
     kind*: EventKind
     code*: cint               # User defined event code
     data1*: pointer           # User defined data pointer
@@ -1044,7 +1044,7 @@ type
               TWrite: Write, TBool: Bool, TUInt8Array: UInt8Array,
               TGrabMode: GrabMode, Terrorcode: Errorcode, TStdio: Stdio,
               TMem: Mem, TSeek: Seek, TRead: Read, TClose: Close,
-              TTimerCallback: TimerCallback, TNewTimerCallback: NewTimerCallabck,
+              TTimerCallback: TimerCallback, TNewTimerCallback: NewTimerCallback,
               TTimerID: TimerID, TAudioSpecCallback: AudioSpecCallback,
               TAudioSpec: AudioSpec, TAudioCVTFilter: AudioCVTFilter,
               TAudioCVTFilterArray: AudioCVTFilterArray, TAudioCVT: AudioCVT,
@@ -1053,16 +1053,19 @@ type
               TJoystick: Joystick, TJoyAxisEvent: JoyAxisEvent, TRWops: RWops,
               TJoyBallEvent: JoyBallEvent, TJoyHatEvent: JoyHatEvent,
               TJoyButtonEvent: JoyButtonEvent, TBallDelta: BallDelta,
-              Tversion: Version, TMod: Mod, TActiveEvent: ActiveEvent,
+              Tversion: Version, TMod: Mod,
+              # TActiveEvent: ActiveEvent, # Naming conflict when we drop the `T`
               TMouseMotionEvent: MouseMotionEvent, TMouseButtonEvent: MouseButtonEvent,
-              TResizeEvent: ResizeEvent, TUserEvent: UserEvent].}
+              TResizeEvent: ResizeEvent,
+              # TUserEvent: UserEvent # Naming conflict when we drop the `T`
+              ].}
 
-when defined(Unix): 
+when defined(Unix):
   type                        #These are the various supported subsystems under UNIX
     SysWm* = enum 
       SYSWM_X11
   {.deprecated: [TSysWm: SysWm].}
-when defined(WINDOWS): 
+when defined(WINDOWS):
   type 
     PSysWMmsg* = ptr SysWMmsg
     SysWMmsg*{.final.} = object 
@@ -1136,8 +1139,8 @@ else:
   {.deprecated: [TSysWMinfo: SysWMinfo].}
 
 type 
-  PSysWMEvent* = ptr SysWMEvent
-  SysWMEvent*{.final.} = object 
+  PSysWMEvent* = ptr TSysWMEvent
+  TSysWMEvent*{.final.} = object 
     kind*: EventKind
     msg*: PSysWMmsg
 
@@ -1172,12 +1175,12 @@ type
 
   PColorArray* = ptr ColorArray
   ColorArray* = array[0..65000, Color]
-  PPalette* = ptr TPalette
+  PPalette* = ptr Palette
   Palette*{.final.} = object  # Everything in the pixel format structure is read-only
     ncolors*: int
     colors*: PColorArray
 
-  PPixelFormat* = ptr TPixelFormat
+  PPixelFormat* = ptr PixelFormat
   PixelFormat*{.final.} = object  # The structure passed to the low level blit functions
     palette*: PPalette
     bitsPerPixel*: byte
@@ -1254,10 +1257,10 @@ type
     hwOverlay*: int32    # This will be set to 1 if the overlay is hardware accelerated.
   
   GLAttr* = enum 
-    GL_RED_SIZE, GL_GREEN_SIZE, GL_BLUE_SIZE, GL_ALPHA_SIZE, GL_BUFFER_SIZE, 
-    GL_DOUBLEBUFFER, GL_DEPTH_SIZE, GL_STENCIL_SIZE, GL_ACCUM_RED_SIZE, 
-    GL_ACCUM_GREEN_SIZE, GL_ACCUM_BLUE_SIZE, GL_ACCUM_ALPHA_SIZE, GL_STEREO, 
-    GL_MULTISAMPLEBUFFERS, GL_MULTISAMPLESAMPLES, GL_ACCELERATED_VISUAL, 
+    GL_RED_SIZE, GL_GREEN_SIZE, GL_BLUE_SIZE, GL_ALPHA_SIZE, GL_BUFFER_SIZE,
+    GL_DOUBLEBUFFER, GL_DEPTH_SIZE, GL_STENCIL_SIZE, GL_ACCUM_RED_SIZE,
+    GL_ACCUM_GREEN_SIZE, GL_ACCUM_BLUE_SIZE, GL_ACCUM_ALPHA_SIZE, GL_STEREO,
+    GL_MULTISAMPLEBUFFERS, GL_MULTISAMPLESAMPLES, GL_ACCELERATED_VISUAL,
     GL_SWAP_CONTROL
   PCursor* = ptr Cursor
   Cursor*{.final.} = object  # SDL_mutex.h types
@@ -1269,7 +1272,8 @@ type
     wmCursor*: pointer       # Window-manager cursor
 {.deprecated: [TRect: Rect, TSurface: Surface, TEvent: Event, TColor: Color,
               TEventFilter: EventFilter, TColorArray: ColorArray,
-              TSysWMEvent: SysWMEvent, TExposeEvent: ExposeEvent,
+              # TSysWMEvent: SysWMEvent, # Naming conflict when we drop the `T`
+              TExposeEvent: ExposeEvent,
               TQuitEvent: QuitEvent, TPalette: Palette, TPixelFormat: PixelFormat,
               TBlitInfo: BlitInfo, TBlit: Blit, TVideoInfo: VideoInfo,
               TOverlay: Overlay, TGLAttr: GLAttr, TCursor: Cursor].}
@@ -1285,11 +1289,11 @@ type
   Cond*{.final.} = object    # SDL_thread.h types
 {.deprecated: [TCond: Cond, TSem: Sem, TMutex: Mutex, Tsemaphore: Semaphore].}
 
-when defined(WINDOWS): 
+when defined(WINDOWS):
   type 
     SYS_ThreadHandle* = Handle
   {.deprecated: [TSYS_ThreadHandle: SYS_ThreadHandle].}
-when defined(Unix): 
+when defined(Unix):
   type 
     SYS_ThreadHandle* = pointer
   {.deprecated: [TSYS_ThreadHandle: SYS_ThreadHandle].}
@@ -1300,7 +1304,7 @@ type                          # This is the system-independent thread info struc
     threadid*: int32
     handle*: SYS_ThreadHandle
     status*: int
-    errbuf*: Terror
+    errbuf*: Error
     data*: pointer
 
   PKeyStateArr* = ptr KeyStateArr
@@ -2211,7 +2215,7 @@ proc glLoadLibrary*(filename: cstring): int{.cdecl,
 proc glGetProcAddress*(procname: cstring): pointer{.cdecl, 
     importc: "SDL_GL_GetProcAddress", dynlib: LibName.}
   # Set an attribute of the OpenGL subsystem before intialization.
-proc glSetAttribute*(attr: TGLAttr, value: int): int{.cdecl, 
+proc glSetAttribute*(attr: GLAttr, value: int): int{.cdecl, 
     importc: "SDL_GL_SetAttribute", dynlib: LibName.}
   # Get an attribute of the OpenGL subsystem from the windowing
   #  interface, such as glX. This is of course different from getting
@@ -2220,7 +2224,7 @@ proc glSetAttribute*(attr: TGLAttr, value: int): int{.cdecl,
   #
   #  Developers should track the values they pass into SDL_GL_SetAttribute
   #  themselves if they want to retrieve these values.
-proc glGetAttribute*(attr: TGLAttr, value: var int): int{.cdecl, 
+proc glGetAttribute*(attr: GLAttr, value: var int): int{.cdecl, 
     importc: "SDL_GL_GetAttribute", dynlib: LibName.}
   # Swap the OpenGL buffers, if double-buffering is supported.
 proc glSwapBuffers*(){.cdecl, importc: "SDL_GL_SwapBuffers", dynlib: LibName.}
@@ -2267,7 +2271,7 @@ proc wmToggleFullScreen*(surface: PSurface): int{.cdecl,
   # Grabbing means that the mouse is confined to the application window,
   #  and nearly all keyboard input is passed directly to the application,
   #  and not interpreted by a window manager, if any.
-proc wmGrabInput*(mode: TGrabMode): GrabMode{.cdecl, 
+proc wmGrabInput*(mode: GrabMode): GrabMode{.cdecl, 
     importc: "SDL_WM_GrabInput", dynlib: LibName.}
   #------------------------------------------------------------------------------
   # mouse-routines
diff --git a/tests/enum/tenumitems.nim b/tests/enum/tenumitems.nim
index 04737fa9e..38233aad7 100644
--- a/tests/enum/tenumitems.nim
+++ b/tests/enum/tenumitems.nim
@@ -1,6 +1,6 @@
 discard """
   line: 7
-  errormsg: "undeclared identifier: 'items'"
+  errormsg: "attempting to call undeclared routine: 'items'"
 """
 
 type a = enum b,c,d
diff --git a/tests/misc/tissue710.nim b/tests/misc/tissue710.nim
index ecfdf653e..3b6d3e5f3 100644
--- a/tests/misc/tissue710.nim
+++ b/tests/misc/tissue710.nim
@@ -1,7 +1,7 @@
 discard """
   file: "tissue710.nim"
   line: 8
-  errorMsg: "undeclared identifier: '||'"
+  errorMsg: "attempting to call undeclared routine: '||'"
 """
 var sum = 0
 for x in 3..1000:
diff --git a/tests/misc/tnoop.nim b/tests/misc/tnoop.nim
index 10c2eb2ec..1e3fbe6cf 100644
--- a/tests/misc/tnoop.nim
+++ b/tests/misc/tnoop.nim
@@ -1,7 +1,7 @@
 discard """
   file: "tnoop.nim"
   line: 11
-  errormsg: "undeclared identifier: 'a'"
+  errormsg: "attempting to call undeclared routine: 'a'"
 """
 
 
diff --git a/tests/modules/topaque.nim b/tests/modules/topaque.nim
index f0587c959..84e2388bc 100644
--- a/tests/modules/topaque.nim
+++ b/tests/modules/topaque.nim
@@ -1,16 +1,16 @@
 discard """
   file: "topaque.nim"
   line: 16
-  errormsg: "undeclared identifier: \'buffer\'"
+  errormsg: "undeclared field: \'buffer\'"
 """
 # Test the new opaque types
 
-import 
+import
   mopaque
-  
+
 var
   L: TLexer
-  
+
 L.filename = "ha"
 L.line = 34
 L.buffer[0] = '\0' #ERROR_MSG undeclared field: 'buffer'
diff --git a/tests/parallel/tptr_to_ref.nim b/tests/parallel/tptr_to_ref.nim
new file mode 100644
index 000000000..66d618481
--- /dev/null
+++ b/tests/parallel/tptr_to_ref.nim
@@ -0,0 +1,26 @@
+# bug #2854
+
+import locks, threadpool, osproc
+
+const MAX_WORKERS = 10
+
+type
+  Killer = object
+    lock: Lock
+    bailed {.guard: lock.}: bool
+    processes {.guard: lock.}: array[0..MAX_WORKERS-1, foreign ptr Process]
+
+template hold(lock: Lock, body: stmt) =
+  lock.acquire
+  defer: lock.release
+  {.locks: [lock].}:
+    body
+
+proc initKiller*(): Killer =
+  initLock(result.lock)
+  result.lock.hold:
+    result.bailed = false
+    for i, _ in result.processes:
+      result.processes[i] = nil
+
+var killer = initKiller()
diff --git a/tests/tuples/twrongtupleaccess.nim b/tests/tuples/twrongtupleaccess.nim
index 1a9ae64a2..b1684b097 100644
--- a/tests/tuples/twrongtupleaccess.nim
+++ b/tests/tuples/twrongtupleaccess.nim
@@ -1,7 +1,7 @@
 discard """
   file: "twrongtupleaccess.nim"
   line: 9
-  errormsg: "undeclared identifier: \'setBLAH\'"
+  errormsg: "attempting to call undeclared routine: \'setBLAH\'"
 """
 # Bugfix
 
diff --git a/tests/vm/tconstobj.nim b/tests/vm/tconstobj.nim
new file mode 100644
index 000000000..414708945
--- /dev/null
+++ b/tests/vm/tconstobj.nim
@@ -0,0 +1,14 @@
+discard """
+  output: '''(name: hello)'''
+"""
+
+# bug #2774
+
+type Foo = object
+  name: string
+
+const fooArray = [
+  Foo(name: "hello")
+]
+
+echo fooArray[0]
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim
index 99befa92d..253543a50 100644
--- a/tools/niminst/niminst.nim
+++ b/tools/niminst/niminst.nim
@@ -538,7 +538,7 @@ when haveZipLib:
     var n = "$#.zip" % proj
     if c.outdir.len == 0: n = "build" / n
     else: n = c.outdir / n
-    var z: TZipArchive
+    var z: ZipArchive
     if open(z, n, fmWrite):
       addFile(z, proj / buildBatFile32, "build" / buildBatFile32)
       addFile(z, proj / buildBatFile64, "build" / buildBatFile64)