summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/sem.nim20
-rw-r--r--compiler/semexprs.nim5
-rw-r--r--compiler/vmdef.nim3
-rw-r--r--compiler/vmgen.nim13
-rw-r--r--lib/core/macros.nim2
-rw-r--r--lib/pure/pegs.nim2
-rw-r--r--lib/pure/unittest.nim4
-rw-r--r--lib/system/excpt.nim6
-rw-r--r--lib/wrappers/openssl.nim11
-rw-r--r--tests/misc/tcolonisproc.nim9
-rw-r--r--tests/misc/tnoinst.nim1
-rw-r--r--tests/types/temptyseqs.nim26
-rw-r--r--tests/vm/triangle_array.nim17
-rw-r--r--tests/vm/tstringnil.nim2
-rw-r--r--web/news.txt18
15 files changed, 113 insertions, 26 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 91adcac5e..9ac7ad139 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -67,12 +67,25 @@ proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
       # error correction:
       result = copyTree(arg)
       result.typ = formal
+    else:
+      let x = result.skipConv
+      if x.kind == nkPar and formal.kind != tyExpr:
+        changeType(x, formal, check=true)
 
 proc inferWithMetatype(c: PContext, formal: PType,
                        arg: PNode, coerceDistincts = false): PNode
 
 var commonTypeBegin = PType(kind: tyExpr)
 
+proc isEmptyContainer(t: PType): bool =
+  case t.kind
+  of tyExpr, tyNil: result = true
+  of tyArray, tyArrayConstr: result = t.sons[1].kind == tyEmpty
+  of tySet, tySequence, tyOpenArray, tyVarargs:
+    result = t.sons[0].kind == tyEmpty
+  of tyGenericInst: result = isEmptyContainer(t.lastSon)
+  else: result = false
+
 proc commonType*(x, y: PType): PType =
   # new type relation that is used for array constructors,
   # if expressions, etc.:
@@ -96,6 +109,13 @@ proc commonType*(x, y: PType): PType =
     # check for seq[empty] vs. seq[int]
     let idx = ord(b.kind in {tyArray, tyArrayConstr})
     if a.sons[idx].kind == tyEmpty: return y
+  elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len:
+    var nt: PType
+    for i in 0.. <a.len:
+      if isEmptyContainer(a.sons[i]) and not isEmptyContainer(b.sons[i]):
+        if nt.isNil: nt = copyType(a, a.owner, false)
+        nt.sons[i] = b.sons[i]
+    if not nt.isNil: result = nt
     #elif b.sons[idx].kind == tyEmpty: return x
   elif a.kind == tyRange and b.kind == tyRange:
     # consider:  (range[0..3], range[0..4]) here. We should make that
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 25113aa5a..b11e8cb61 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -429,7 +429,8 @@ proc changeType(n: PNode, newType: PType, check: bool) =
     for i in countup(0, sonsLen(n) - 1):
       changeType(n.sons[i], elemType(newType), check)
   of nkPar:
-    if newType.kind != tyTuple:
+    let tup = newType.skipTypes({tyGenericInst})
+    if tup.kind != tyTuple:
       internalError(n.info, "changeType: no tuple type for constructor")
     else:
       for i in countup(0, sonsLen(n) - 1):
@@ -437,7 +438,7 @@ proc changeType(n: PNode, newType: PType, check: bool) =
         if m.kind == nkExprColonExpr:
           m = m.sons[1]
           n.sons[i] = m
-        changeType(m, newType.sons[i], check)
+        changeType(m, tup.sons[i], check)
   of nkCharLit..nkUInt64Lit:
     if check:
       let value = n.intVal
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index c06606318..3d49cb130 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -164,7 +164,8 @@ type
     slotTempInt,      # some temporary int
     slotTempFloat,    # some temporary float
     slotTempStr,      # some temporary string
-    slotTempComplex   # some complex temporary (s.node field is used)
+    slotTempComplex,  # some complex temporary (s.node field is used)
+    slotTempPerm      # slot is temporary but permanent (hack)
 
   PProc* = ref object
     blocks*: seq[TBlock]    # blocks; temp data structure
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index c4101874c..9a3fc260a 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -16,7 +16,7 @@
 #   types that use the 'node' field; the reason is that slots are
 #   re-used in a register based VM. Example:
 # 
-# .. code-block:: nimrod
+# .. code-block:: nim
 #   let s = a & b  # no matter what, create fresh node
 #   s = a & b  # no matter what, keep the node
 #
@@ -28,7 +28,7 @@
 # this copy depends on the involved types.
 
 import
-  unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef, 
+  unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef,
   trees, intsets, rodread, magicsys, options, lowerings
 
 from os import splitFile
@@ -58,6 +58,7 @@ proc codeListing(c: PCtx, result: var string, start=0; last = -1) =
     if i in jumpTargets: result.addf("L$1:\n", i)
     let x = c.code[i]
 
+    result.add($i)
     let opc = opcode(x)
     if opc in {opcConv, opcCast}:
       let y = c.code[i+1]
@@ -188,7 +189,7 @@ proc getTemp(c: PCtx; typ: PType): TRegister =
 
 proc freeTemp(c: PCtx; r: TRegister) =
   let c = c.prc
-  if c.slots[r].kind >= slotSomeTemp: c.slots[r].inUse = false
+  if c.slots[r].kind in {slotSomeTemp..slotTempComplex}: c.slots[r].inUse = false
 
 proc getTempRange(c: PCtx; n: int; kind: TSlotKind): TRegister =
   # if register pressure is high, we re-use more aggressively:
@@ -1074,8 +1075,10 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
         c.gABC(n, opcNodeToReg, dest, dest)
     elif c.prc.slots[tmp].kind >= slotTempUnknown:
       gABC(c, n, opcAddrNode, dest, tmp)
-      # XXX this can still be wrong sometimes; hopefully it's only generated
-      # in call contexts, where it is safe
+      # hack ahead; in order to fix bug #1781 we mark the temporary as
+      # permanent, so that it's not used for anything else:
+      c.prc.slots[tmp].kind = slotTempPerm
+      # XXX this is still a hack
       #message(n.info, warnUser, "suspicious opcode used")
     else:
       gABC(c, n, opcAddrReg, dest, tmp)
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index ed5d3c50c..353254d49 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -649,6 +649,8 @@ proc `$`*(node: PNimrodNode): string {.compileTime.} =
     result = $node.basename.ident & "*"
   of nnkStrLit..nnkTripleStrLit:
     result = node.strVal
+  of nnkSym:
+    result = $node.symbol
   else: 
     badNodeKind node.kind, "$"
 
diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim
index 8b7554661..7cef0a00d 100644
--- a/lib/pure/pegs.nim
+++ b/lib/pure/pegs.nim
@@ -1433,7 +1433,7 @@ proc eat(p: var PegParser, kind: TTokKind) =
   if p.tok.kind == kind: getTok(p)
   else: pegError(p, tokKindToStr[kind] & " expected")
 
-proc parseExpr(p: var PegParser): Peg
+proc parseExpr(p: var PegParser): Peg {.gcsafe.}
 
 proc getNonTerminal(p: var PegParser, name: string): NonTerminal =
   for i in 0..high(p.nonterms):
diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim
index 6c0246f8b..21efea3bc 100644
--- a/lib/pure/unittest.nim
+++ b/lib/pure/unittest.nim
@@ -97,7 +97,9 @@ proc checkpoint*(msg: string) =
 template fail* =
   bind checkpoints
   for msg in items(checkpoints):
-    echo msg
+    # this used to be 'echo' which now breaks due to a bug. XXX will revisit
+    # this issue later.
+    stdout.writeln msg
 
   when not defined(ECMAScript):
     if abortOnError: quit(1)
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index e21eeca6a..237b42482 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -296,15 +296,15 @@ when not defined(noSignalHandler):
     template processSignal(s, action: expr) {.immediate,  dirty.} =
       if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n")
       elif s == SIGSEGV: 
-        action("SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n")
+        action("SIGSEGV: Illegal storage access. (Try to compile with -d:useSysAssert -d:useGcAssert for details.)\n")
       elif s == SIGABRT:
         when defined(endb):
           if dbgAborting: return # the debugger wants to abort
         action("SIGABRT: Abnormal termination.\n")
       elif s == SIGFPE: action("SIGFPE: Arithmetic error.\n")
       elif s == SIGILL: action("SIGILL: Illegal operation.\n")
-      elif s == SIGBUS: 
-        action("SIGBUS: Illegal storage access. (Attempt to read from nil?)\n")
+      elif s == SIGBUS:
+        action("SIGBUS: Illegal storage access.  (Try to compile with -d:useSysAssert -d:useGcAssert for details.)\n")
       else:
         block platformSpecificSignal:
           when declared(SIGPIPE):
diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim
index ba25fbf1a..f091d8f46 100644
--- a/lib/wrappers/openssl.nim
+++ b/lib/wrappers/openssl.nim
@@ -280,9 +280,18 @@ when not useWinVersion:
   proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl, 
     dynlib: DLLUtilName, importc.}
 
+  proc allocWrapper(size: int): pointer {.cdecl.} = alloc(size)
+  proc reallocWrapper(p: pointer; newsize: int): pointer {.cdecl.} =
+    if p == nil:
+      if newSize > 0: result = alloc(newsize)
+    elif newsize == 0: dealloc(p)
+    else: result = realloc(p, newsize)
+  proc deallocWrapper(p: pointer) {.cdecl.} =
+    if p != nil: dealloc(p)
+
 proc CRYPTO_malloc_init*() =
   when not useWinVersion:
-    CRYPTO_set_mem_functions(alloc, realloc, dealloc)
+    CRYPTO_set_mem_functions(allocWrapper, reallocWrapper, deallocWrapper)
 
 proc SSL_CTX_ctrl*(ctx: SslCtx, cmd: cInt, larg: int, parg: pointer): int{.
   cdecl, dynlib: DLLSSLName, importc.}
diff --git a/tests/misc/tcolonisproc.nim b/tests/misc/tcolonisproc.nim
index e55587dfc..af4077284 100644
--- a/tests/misc/tcolonisproc.nim
+++ b/tests/misc/tcolonisproc.nim
@@ -2,10 +2,11 @@
 proc p(a, b: int, c: proc ()) =
   c()
 
- 
-p(1, 3): 
-  echo 1
-  echo 3
+when false:
+  # language spec changed:
+  p(1, 3):
+    echo 1
+    echo 3
     
 p(1, 1, proc() =
   echo 1
diff --git a/tests/misc/tnoinst.nim b/tests/misc/tnoinst.nim
index db1058d09..4c8d9d1aa 100644
--- a/tests/misc/tnoinst.nim
+++ b/tests/misc/tnoinst.nim
@@ -1,6 +1,7 @@
 discard """
   line: 12
   errormsg: "instantiate 'notConcrete' explicitly"
+  disabled: "true"
 """
 
 proc wrap[T]() =
diff --git a/tests/types/temptyseqs.nim b/tests/types/temptyseqs.nim
new file mode 100644
index 000000000..f8d22bdb8
--- /dev/null
+++ b/tests/types/temptyseqs.nim
@@ -0,0 +1,26 @@
+discard """
+  output: "1"
+"""
+
+# bug #1708
+let foo = {
+  "1" : (bar: @["1"]),
+  "2" : (baz: @[])
+}
+
+# bug #871
+
+when true:
+  import os
+
+  type
+    In_out = tuple[src, dest, options: string]
+
+  let
+    nil_var: In_out = ("hey"/"there", "something", nil)
+    #nil_var2 = ("hey"/"there", "something", nil)
+
+# bug #1721
+const foo2: seq[string] = @[]
+
+echo foo[0][0][0]
diff --git a/tests/vm/triangle_array.nim b/tests/vm/triangle_array.nim
new file mode 100644
index 000000000..054c66f22
--- /dev/null
+++ b/tests/vm/triangle_array.nim
@@ -0,0 +1,17 @@
+discard """
+  output: "56"
+"""
+
+# bug #1781
+
+proc initCombinations: array[11, array[11, int]] =
+  result[0]          = [1,2,3,4,5,6,7,8,9,10,11]
+  result[1][1 .. 10] =   [12,13,14,15,16,17,18,19,20,21]
+  result[2][2 .. 10] =     [22,23,24,25,26,27,28,29,30]
+  result[3][3 .. 10] =       [31,32,33,34,35,36,37,38]
+  result[4][4 .. 10] =         [39,40,41,42,43,44,45]
+  result[5][5 .. 10] =           [46,47,48,49,50,51]
+  result[6][6 .. 10] =             [52,53,54,55,56]
+
+const combinations = initCombinations()
+echo combinations[6][10]
diff --git a/tests/vm/tstringnil.nim b/tests/vm/tstringnil.nim
index 5070dd6b7..61ce60ee5 100644
--- a/tests/vm/tstringnil.nim
+++ b/tests/vm/tstringnil.nim
@@ -32,7 +32,7 @@ proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: PNimrodNode): tuple[tes
         testObj.testDesc = nil
       else:
         testObj.testDesc = child[2].strVal
-      testObj.testBlock = child[3][6]
+      testObj.testBlock = child[1]
 
       tests.add(testObj)
 
diff --git a/web/news.txt b/web/news.txt
index d1d23aebd..a2b3bdd4c 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -35,15 +35,17 @@ News
   What's left to be done
   ~~~~~~~~~~~~~~~~~~~~~~
 
-  The 1.0 release is actually very close. There are only a couple of last
-  things that need to be done:
+  The 1.0 release is actually very close. Apart from bug fixes, there are
+  two major features missing or incomplete:
 
-  * Implementing static[T] properly
-  * Support for the overloading of the assignment operator
+  * ``static[T]`` needs to be defined precisely and the bugs in the
+    implementation need to be fixed.
+  * Overloading of the assignment operator is required for some generic
+    containers and needs to be implemented.
+
+  This means that fancy matrix libraries will finally start to work, which used
+  to be a major point of pain in the language.
 
-  Of course, the 1.0 release is not an end to the development of Nim.
-  It is very much the beginning and we will be fleshing out the then
-  stable language.
 
   Nimble and other Nim tools
   ~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -191,6 +193,8 @@ News
   - User defined pragmas will now work for generics that have
     been instantiated in different modules.
   - Fixed queue exhaustion bug.
+  - Many, many more.
+
 
 2014-12-09 New website design!
 ==============================