summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-12-31 01:55:13 +0100
committerAraq <rumpf_a@web.de>2014-12-31 01:55:13 +0100
commita93585e47fb41865a5315d83e78791c1349f945d (patch)
tree6b39e654ae7e8a50a5475d6cc62ff60f1586074c
parent13b72ed0c025f540ac676dd229b781eb4ddee713 (diff)
parent595a8b628f48dfd29facf4d329d32ea5e7c6d9e7 (diff)
downloadNim-a93585e47fb41865a5315d83e78791c1349f945d.tar.gz
Merge branch 'devel' of https://github.com/Araq/Nim into devel
-rw-r--r--compiler/nim.ini2
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semgnrc.nim8
-rw-r--r--compiler/seminst.nim4
-rw-r--r--compiler/semtypes.nim74
-rw-r--r--compiler/sigmatch.nim28
-rw-r--r--lib/posix/posix.nim4
-rw-r--r--lib/pure/rawsockets.nim4
-rw-r--r--tests/generics/t1789.nim44
9 files changed, 122 insertions, 48 deletions
diff --git a/compiler/nim.ini b/compiler/nim.ini
index 576b6d2bb..1f14eb21b 100644
--- a/compiler/nim.ini
+++ b/compiler/nim.ini
@@ -125,7 +125,7 @@ Files: "start.bat"
 BinPath: r"bin;dist\mingw\bin;dist"
 
 ;           Section | dir | zipFile | size hint (in KB) | url | exe start menu entry
-Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|doc\overview.html"
+Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|overview.html"
 Download: r"C Compiler (MingW)|dist|mingw.zip|82944|http://nim-lang.org/download/${mingw}.zip"
 Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.1.3.zip|aporia\bin\aporia.exe"
 ; for now only NSIS supports optional downloads
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index ee3391e3e..b2f623fb8 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -219,7 +219,7 @@ proc maybeLiftType(t: var PType, c: PContext, info: TLineInfo) =
   # gnrc. params, then it won't be necessary to open a new scope here
   openScope(c)
   var lifted = liftParamType(c, skType, newNodeI(nkArgList, info),
-                         t, ":anon", info)
+                             t, ":anon", info)
   closeScope(c)
   if lifted != nil: t = lifted
 
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index 7c32b0051..06959b8d1 100644
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -60,7 +60,13 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
     else:
       result = symChoice(c, n, s, scOpen)
   of skGenericParam: 
-    result = newSymNodeTypeDesc(s, n.info)
+    if s.typ != nil and s.typ.kind == tyStatic:
+      if s.typ.n != nil:
+        result = s.typ.n
+      else:
+        result = n
+    else:
+      result = newSymNodeTypeDesc(s, n.info)
     styleCheckUse(n.info, s)
   of skParam:
     result = n
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 2decb5d0b..81a4465c5 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -21,7 +21,8 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
     var q = a.sym
     if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic, tyIter}+tyTypeClasses:
       continue
-    var s = newSym(skType, q.name, getCurrOwner(), q.info)
+    let symKind = if q.typ.kind == tyStatic: skConst else: skType
+    var s = newSym(symKind, q.name, getCurrOwner(), q.info)
     s.flags = s.flags + {sfUsed, sfFromGeneric}
     var t = PType(idTableGet(pt, q.typ))
     if t == nil:
@@ -40,6 +41,7 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
       t = generateTypeInstance(c, pt, a, t)
       #t = ReplaceTypeVarsT(cl, t)
     s.typ = t
+    if t.kind == tyStatic: s.ast = t.n
     addDecl(c, s)
     entry.concreteTypes[i] = t
 
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 4305a48e1..eb15c3809 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -214,44 +214,48 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType =
     localError(n.info, errXExpectsOneTypeParam, "range")
     result = newOrPrevType(tyError, prev, c)
 
+proc semArrayIndex(c: PContext, n: PNode): PType =
+  if isRange(n): result = semRangeAux(c, n, nil)
+  else:
+    let e = semExprWithType(c, n, {efDetermineType})
+    if e.typ.kind == tyFromExpr:
+      result = makeRangeWithStaticExpr(c, e.typ.n)
+    elif e.kind in {nkIntLit..nkUInt64Lit}:
+      result = makeRangeType(c, 0, e.intVal-1, n.info, e.typ)
+    elif e.kind == nkSym and e.typ.kind == tyStatic:
+      if e.sym.ast != nil:
+        return semArrayIndex(c, e.sym.ast)
+      internalAssert c.inGenericContext > 0
+      if not isOrdinalType(e.typ.lastSon):
+        localError(n[1].info, errOrdinalTypeExpected)
+      result = makeRangeWithStaticExpr(c, e)
+      result.flags.incl tfUnresolved
+    elif e.kind in nkCallKinds and hasGenericArguments(e):
+      if not isOrdinalType(e.typ):
+        localError(n[1].info, errOrdinalTypeExpected)
+      # This is an int returning call, depending on an
+      # yet unknown generic param (see tgenericshardcases).
+      # We are going to construct a range type that will be
+      # properly filled-out in semtypinst (see how tyStaticExpr
+      # is handled there).
+      result = makeRangeWithStaticExpr(c, e)
+    elif e.kind == nkIdent:
+      result = e.typ.skipTypes({tyTypeDesc})
+    else:
+      let x = semConstExpr(c, e)
+      if x.kind in {nkIntLit..nkUInt64Lit}:
+        result = makeRangeType(c, 0, x.intVal-1, n.info, 
+                             x.typ.skipTypes({tyTypeDesc}))
+      else:
+        result = x.typ.skipTypes({tyTypeDesc})
+        #localError(n[1].info, errConstExprExpected)
+
 proc semArray(c: PContext, n: PNode, prev: PType): PType = 
-  var indx, base: PType
+  var base: PType
   result = newOrPrevType(tyArray, prev, c)
-  if sonsLen(n) == 3: 
+  if sonsLen(n) == 3:
     # 3 = length(array indx base)
-    if isRange(n[1]): indx = semRangeAux(c, n[1], nil)
-    else:
-      let e = semExprWithType(c, n.sons[1], {efDetermineType})
-      if e.typ.kind == tyFromExpr:
-        indx = makeRangeWithStaticExpr(c, e.typ.n)
-      elif e.kind in {nkIntLit..nkUInt64Lit}:
-        indx = makeRangeType(c, 0, e.intVal-1, n.info, e.typ)
-      elif e.kind == nkSym and e.typ.kind == tyStatic:
-        if e.sym.ast != nil: return semArray(c, e.sym.ast, nil)
-        internalAssert c.inGenericContext > 0
-        if not isOrdinalType(e.typ.lastSon):
-          localError(n[1].info, errOrdinalTypeExpected)
-        indx = makeRangeWithStaticExpr(c, e)
-        indx.flags.incl tfUnresolved
-      elif e.kind in nkCallKinds and hasGenericArguments(e):
-        if not isOrdinalType(e.typ):
-          localError(n[1].info, errOrdinalTypeExpected)
-        # This is an int returning call, depending on an
-        # yet unknown generic param (see tgenericshardcases).
-        # We are going to construct a range type that will be
-        # properly filled-out in semtypinst (see how tyStaticExpr
-        # is handled there).
-        indx = makeRangeWithStaticExpr(c, e)
-      elif e.kind == nkIdent:
-        indx = e.typ.skipTypes({tyTypeDesc})
-      else:
-        let x = semConstExpr(c, e)
-        if x.kind in {nkIntLit..nkUInt64Lit}:
-          indx = makeRangeType(c, 0, x.intVal-1, n.info, 
-                               x.typ.skipTypes({tyTypeDesc}))
-        else:
-          indx = x.typ.skipTypes({tyTypeDesc})
-          #localError(n[1].info, errConstExprExpected)
+    var indx = semArrayIndex(c, n[1])
     addSonSkipIntLit(result, indx)
     if indx.kind == tyGenericInst: indx = lastSon(indx)
     if indx.kind notin {tyGenericParam, tyStatic, tyFromExpr}:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 06f9d58b7..d7bf4fee9 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -517,6 +517,16 @@ proc maybeSkipDistinct(t: PType, callee: PSym): PType =
   else:
     result = t
 
+proc tryResolvingStaticExpr(c: var TCandidate, n: PNode): PNode =
+  # Consider this example:
+  #   type Value[N: static[int]] = object
+  #   proc foo[N](a: Value[N], r: range[0..(N-1)])
+  # Here, N-1 will be initially nkStaticExpr that can be evaluated only after
+  # N is bound to a concrete value during the matching of the first param.
+  # This proc is used to evaluate such static expressions.
+  let instantiated = replaceTypesInBody(c.c, c.bindings, n)
+  result = c.c.semExpr(c.c, instantiated)
+
 proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
   # typeRel can be used to establish various relationships between types:
   #
@@ -620,6 +630,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
       # bugfix: accept integer conversions here
       #if result < isGeneric: result = isNone
       if result notin {isNone, isGeneric}:
+        # resolve any late-bound static expressions
+        # that may appear in the range:
+        for i in 0..1:
+          if f.n[i].kind == nkStaticExpr:
+            f.n.sons[i] = tryResolvingStaticExpr(c, f.n[i])
         result = typeRangeRel(f, a)
     else:
       if skipTypes(f, {tyRange}).kind == a.kind:
@@ -1006,15 +1021,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
 
   of tyFromExpr:
     # fix the expression, so it contains the already instantiated types
-    let instantiated = replaceTypesInBody(c.c, c.bindings, f.n)
-    let reevaluted = c.c.semExpr(c.c, instantiated)
-    case reevaluted.typ.kind
+    let reevaluated = tryResolvingStaticExpr(c, f.n)
+    case reevaluated.typ.kind
     of tyTypeDesc:
-      result = typeRel(c, a, reevaluted.typ.base)
+      result = typeRel(c, a, reevaluated.typ.base)
     of tyStatic:
-      result = typeRel(c, a, reevaluted.typ.base)
-      if result != isNone and reevaluted.typ.n != nil:
-        if not exprStructuralEquivalent(aOrig.n, reevaluted.typ.n):
+      result = typeRel(c, a, reevaluated.typ.base)
+      if result != isNone and reevaluated.typ.n != nil:
+        if not exprStructuralEquivalent(aOrig.n, reevaluated.typ.n):
           result = isNone
     else:
       localError(f.n.info, errTypeExpected)
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index deb120372..0498a0e70 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -1570,9 +1570,9 @@ else:
 
 
 when defined(macosx):
+  # We can't use the NOSIGNAL flag in the ``send`` function, it has no effect
   var
-    MSG_HAVEMORE* {.importc, header: "<sys/socket.h>".}: cint
-    MSG_NOSIGNAL* = MSG_HAVEMORE
+    MSG_NOSIGNAL* = 0'i32
 else:
   var
     MSG_NOSIGNAL* {.importc, header: "<sys/socket.h>".}: cint
diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim
index 62a011999..e23deea5b 100644
--- a/lib/pure/rawsockets.nim
+++ b/lib/pure/rawsockets.nim
@@ -428,6 +428,10 @@ proc selectWrite*(writefds: var seq[SocketHandle],
   
   pruneSocketSet(writefds, (wr))
 
+# We ignore signal SIGPIPE on Darwin
+when defined(macosx):
+  signal(SIGPIPE, SIG_IGN)
+
 when defined(Windows):
   var wsa: WSAData
   if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError())
diff --git a/tests/generics/t1789.nim b/tests/generics/t1789.nim
new file mode 100644
index 000000000..188db88f6
--- /dev/null
+++ b/tests/generics/t1789.nim
@@ -0,0 +1,44 @@
+discard """
+  output: "3\n0"
+"""
+
+# https://github.com/Araq/Nim/issues/1789
+
+type
+  Foo[N: static[int]] = object
+
+proc bindStaticN[N](foo: Foo[N]) =
+  var ar0: array[3, int]
+  var ar1: array[N, int]
+  var ar2: array[1..N, int]
+  var ar3: array[0..(N+10), float]
+  echo N
+
+var f: Foo[3]
+f.bindStaticN
+
+# case 2
+
+type
+  ObjectWithStatic[X, Y: static[int], T] = object
+    bar: array[X * Y, T]   # this one works
+
+  AliasWithStatic[X, Y: static[int], T] = array[X * Y, T]
+
+var
+  x: ObjectWithStatic[1, 2, int]
+  y: AliasWithStatic[2, 3, int]
+
+# case 3
+
+type
+  Bar[N: static[int], T] = object
+    bar: array[N, T]
+
+proc `[]`*[N, T](f: Bar[N, T], n: range[0..(N - 1)]): T =
+  assert high(n) == N-1
+  result = f.bar[n]
+  
+var b: Bar[3, int]
+echo b[2]
+