summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-08-10 12:06:16 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-08-10 12:06:16 +0200
commit404de2f23e931f922f283faa6d3491bfe3c0e68e (patch)
tree79ed71c485de952680a02a653f81ce00cc4da531 /lib
parent1d78ba64b4761de88817a2e5748a456679cb2bab (diff)
parent43f634db8dfac4fb13c8454958d35e776410dac1 (diff)
downloadNim-404de2f23e931f922f283faa6d3491bfe3c0e68e.tar.gz
Merge branch 'devel' into araq-misc
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/collections/sequtils.nim11
-rw-r--r--lib/pure/httpclient.nim15
-rw-r--r--lib/pure/sugar.nim38
-rw-r--r--lib/system/channels.nim2
4 files changed, 60 insertions, 6 deletions
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index 8f81fe4f5..99ce91979 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -676,8 +676,8 @@ template mapIt*(s, op: untyped): untyped =
       var it{.inject.}: type(items(s));
       op))
   var result: seq[outType]
-  evalOnce(t, s)
-  when compiles(t.len):
+  when compiles(s.len):
+    evalOnce(t, s)
     var i = 0
     result = newSeq[outType](t.len)
     for it {.inject.} in t:
@@ -685,7 +685,7 @@ template mapIt*(s, op: untyped): untyped =
       i += 1
   else:
     result = @[]
-    for it {.inject.} in t:
+    for it {.inject.} in s:
       result.add(op)
   result
 
@@ -1071,5 +1071,10 @@ when isMainModule:
       proc foo(x: openArray[int]): seq[int] = x.mapIt(it + 1)
       doAssert foo([1,2,3]) == @[2,3,4]
 
+  block: # mapIt with invalid RHS for `let` (#8566)
+    type X = enum
+      A, B
+    doAssert mapIt(X, $it) == @["A", "B"]
+
   when not defined(testing):
     echo "Finished doc tests"
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index 8b4fb0f8c..72de72718 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -807,6 +807,7 @@ type
     lastProgressReport: float
     when SocketType is AsyncSocket:
       bodyStream: FutureStream[string]
+      parseBodyFut: Future[void]
     else:
       bodyStream: Stream
     getBody: bool ## When `false`, the body is never read in requestAux.
@@ -1066,10 +1067,14 @@ proc parseResponse(client: HttpClient | AsyncHttpClient,
   if getBody:
     when client is HttpClient:
       client.bodyStream = newStringStream()
+      result.bodyStream = client.bodyStream
+      parseBody(client, result.headers, result.version)
     else:
       client.bodyStream = newFutureStream[string]("parseResponse")
-    await parseBody(client, result.headers, result.version)
-    result.bodyStream = client.bodyStream
+      result.bodyStream = client.bodyStream
+      assert(client.parseBodyFut.isNil or client.parseBodyFut.finished)
+      client.parseBodyFut = parseBody(client, result.headers, result.version)
+        # do not wait here for the body request to complete
 
 proc newConnection(client: HttpClient | AsyncHttpClient,
                    url: Uri) {.multisync.} =
@@ -1159,6 +1164,12 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string,
   # Helper that actually makes the request. Does not handle redirects.
   let requestUrl = parseUri(url)
 
+  when client is AsyncHttpClient:
+    if not client.parseBodyFut.isNil:
+      # let the current operation finish before making another request
+      await client.parseBodyFut
+      client.parseBodyFut = nil
+
   await newConnection(client, requestUrl)
 
   let effectiveHeaders = client.headers.override(headers)
diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim
index 258b40191..8ded552d9 100644
--- a/lib/pure/sugar.nim
+++ b/lib/pure/sugar.nim
@@ -198,3 +198,41 @@ macro dump*(x: typed): untyped =
   let r = quote do:
     debugEcho `s`, " = ", `x`
   return r
+
+# TODO: consider exporting this in macros.nim
+proc freshIdentNodes(ast: NimNode): NimNode =
+  # Replace NimIdent and NimSym by a fresh ident node
+  # see also https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458
+  proc inspect(node: NimNode): NimNode =
+    case node.kind:
+    of nnkIdent, nnkSym:
+      result = ident($node)
+    of nnkEmpty, nnkLiterals:
+      result = node
+    else:
+      result = node.kind.newTree()
+      for child in node:
+        result.add inspect(child)
+  result = inspect(ast)
+
+macro distinctBase*(T: typedesc): untyped =
+  ## reverses ``type T = distinct A``; works recursively.
+  runnableExamples:
+    type T = distinct int
+    doAssert distinctBase(T) is int
+    doAssert: not compiles(distinctBase(int))
+    type T2 = distinct T
+    doAssert distinctBase(T2) is int
+
+  let typeNode = getTypeImpl(T)
+  expectKind(typeNode, nnkBracketExpr)
+  if typeNode[0].typeKind != ntyTypeDesc:
+    error "expected typeDesc, got " & $typeNode[0]
+  var typeSym = typeNode[1]
+  typeSym = getTypeImpl(typeSym)
+  if typeSym.typeKind != ntyDistinct:
+    error "type is not distinct"
+  typeSym = typeSym[0]
+  while typeSym.typeKind == ntyDistinct:
+    typeSym = getTypeImpl(typeSym)[0]
+  typeSym.freshIdentNodes
diff --git a/lib/system/channels.nim b/lib/system/channels.nim
index 254b87dfc..14d3a3005 100644
--- a/lib/system/channels.nim
+++ b/lib/system/channels.nim
@@ -233,7 +233,7 @@ proc send*[TMsg](c: var Channel[TMsg], msg: TMsg) {.inline.} =
 proc trySend*[TMsg](c: var Channel[TMsg], msg: TMsg): bool {.inline.} =
   ## Tries to send a message to a thread. `msg` is deeply copied. Doesn't block.
   ## Returns `false` if the message was not sent because number of pending items
-  ## in the cannel exceeded `maxItems`.
+  ## in the channel exceeded `maxItems`.
   sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), unsafeAddr(msg), true)
 
 proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) =