Merge branch 'devel' into araq-misc

This commit is contained in:
Andreas Rumpf 2018-08-10 12:06:16 +02:00
commit 404de2f23e
13 changed files with 193 additions and 17 deletions

31
build_all.sh Normal file
View file

@ -0,0 +1,31 @@
#! /bin/sh
# build development version of the compiler; can be rerun safely
set -u # error on undefined variables
set -e # exit on first error
echo_run(){
echo "\n$@"
"$@"
}
[ -d csources ] || echo_run git clone --depth 1 https://github.com/nim-lang/csources.git
nim_csources=bin/nim_csources
build_nim_csources(){
## avoid changing dir in case of failure
(
echo_run cd csources
echo_run sh build.sh
)
# keep $nim_csources in case needed to investigate bootstrap issues
# without having to rebuild from csources
echo_run cp bin/nim $nim_csources
}
[ -f $nim_csources ] || echo_run build_nim_csources
echo_run bin/nim c koch
echo_run ./koch boot -d:release
echo_run ./koch tools # Compile Nimble and other tools.

View file

@ -482,7 +482,7 @@ include packagehandling
proc getOsCacheDir(): string = proc getOsCacheDir(): string =
when defined(posix): when defined(posix):
result = getHomeDir() / ".cache" result = string getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache")
else: else:
result = getHomeDir() / genSubDir result = getHomeDir() / genSubDir

View file

@ -1611,7 +1611,8 @@ A ``distinct`` type is new type derived from a `base type`:idx: that is
incompatible with its base type. In particular, it is an essential property incompatible with its base type. In particular, it is an essential property
of a distinct type that it **does not** imply a subtype relation between it of a distinct type that it **does not** imply a subtype relation between it
and its base type. Explicit type conversions from a distinct type to its and its base type. Explicit type conversions from a distinct type to its
base type and vice versa are allowed. base type and vice versa are allowed. See also ``distinctBase`` to get the
reverse operation.
Modelling currencies Modelling currencies

View file

@ -159,7 +159,8 @@ Generated C code directory
The generated files that Nim produces all go into a subdirectory called The generated files that Nim produces all go into a subdirectory called
``nimcache``. Its full path is ``nimcache``. Its full path is
- ``~/.cache/$projectname(_r|_d)`` on Posix - ``$XDG_CACHE_HOME/$projectname(_r|_d)`` or ``~/.cache/$projectname(_r|_d)``
on Posix
- ``$HOME/nimcache/$projectname(_r|_d)`` on Windows. - ``$HOME/nimcache/$projectname(_r|_d)`` on Windows.
The ``_r`` suffix is used for release builds, ``_d`` is for debug builds. The ``_r`` suffix is used for release builds, ``_d`` is for debug builds.

View file

@ -676,8 +676,8 @@ template mapIt*(s, op: untyped): untyped =
var it{.inject.}: type(items(s)); var it{.inject.}: type(items(s));
op)) op))
var result: seq[outType] var result: seq[outType]
when compiles(s.len):
evalOnce(t, s) evalOnce(t, s)
when compiles(t.len):
var i = 0 var i = 0
result = newSeq[outType](t.len) result = newSeq[outType](t.len)
for it {.inject.} in t: for it {.inject.} in t:
@ -685,7 +685,7 @@ template mapIt*(s, op: untyped): untyped =
i += 1 i += 1
else: else:
result = @[] result = @[]
for it {.inject.} in t: for it {.inject.} in s:
result.add(op) result.add(op)
result result
@ -1071,5 +1071,10 @@ when isMainModule:
proc foo(x: openArray[int]): seq[int] = x.mapIt(it + 1) proc foo(x: openArray[int]): seq[int] = x.mapIt(it + 1)
doAssert foo([1,2,3]) == @[2,3,4] 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): when not defined(testing):
echo "Finished doc tests" echo "Finished doc tests"

View file

@ -807,6 +807,7 @@ type
lastProgressReport: float lastProgressReport: float
when SocketType is AsyncSocket: when SocketType is AsyncSocket:
bodyStream: FutureStream[string] bodyStream: FutureStream[string]
parseBodyFut: Future[void]
else: else:
bodyStream: Stream bodyStream: Stream
getBody: bool ## When `false`, the body is never read in requestAux. getBody: bool ## When `false`, the body is never read in requestAux.
@ -1066,10 +1067,14 @@ proc parseResponse(client: HttpClient | AsyncHttpClient,
if getBody: if getBody:
when client is HttpClient: when client is HttpClient:
client.bodyStream = newStringStream() client.bodyStream = newStringStream()
result.bodyStream = client.bodyStream
parseBody(client, result.headers, result.version)
else: else:
client.bodyStream = newFutureStream[string]("parseResponse") 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, proc newConnection(client: HttpClient | AsyncHttpClient,
url: Uri) {.multisync.} = url: Uri) {.multisync.} =
@ -1159,6 +1164,12 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string,
# Helper that actually makes the request. Does not handle redirects. # Helper that actually makes the request. Does not handle redirects.
let requestUrl = parseUri(url) 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) await newConnection(client, requestUrl)
let effectiveHeaders = client.headers.override(headers) let effectiveHeaders = client.headers.override(headers)

View file

@ -198,3 +198,41 @@ macro dump*(x: typed): untyped =
let r = quote do: let r = quote do:
debugEcho `s`, " = ", `x` debugEcho `s`, " = ", `x`
return r 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

View file

@ -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.} = 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. ## 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 ## 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) sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), unsafeAddr(msg), true)
proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) = proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) =

View file

@ -50,24 +50,33 @@ Next, to build from source you will need:
other distros as well). other distros as well).
Then, if you are on a \*nix system or Windows, the following steps should compile Then, if you are on a \*nix system or Windows, the following steps should compile
Nim from source using ``gcc``, ``git`` and the ``koch`` build tool (in the place Nim from source using ``gcc``, ``git`` and the ``koch`` build tool.
of ``sh build.sh`` you should substitute ``build.bat`` on x86 Windows or
``build64.bat`` on x86_64 Windows):
**Note: The following commands are for the development version of the compiler.** **Note: The following commands are for the development version of the compiler.**
For most users, installing the latest stable version is enough. Check out For most users, installing the latest stable version is enough. Check out
the installation instructions on the website to do so: https://nim-lang.org/install.html. the installation instructions on the website to do so: https://nim-lang.org/install.html.
``` ```
# step 1:
git clone https://github.com/nim-lang/Nim.git git clone https://github.com/nim-lang/Nim.git
cd Nim cd Nim
# step 2 (posix) clones `csources.git`, bootstraps Nim compiler and compiles tools
sh build_all.sh
# step 2 (windows)
git clone --depth 1 https://github.com/nim-lang/csources.git git clone --depth 1 https://github.com/nim-lang/csources.git
cd csources cd csources
sh build.sh # requires `gcc` in your PATH, see also https://nim-lang.org/install_windows.html
cd ../ build.bat # x86 Windows
bin/nim c koch build64.bat # x86_64 Windows
./koch boot -d:release cd ..
./koch tools # Compile Nimble and other tools.
bin\nim c koch
koch boot -d:release
koch tools # Compile Nimble and other tools
# end of step 2 (windows)
``` ```
Finally, once you have finished the build steps (on Windows, Mac or Linux) you Finally, once you have finished the build steps (on Windows, Mac or Linux) you

29
tests/generics/t6137.nim Normal file
View file

@ -0,0 +1,29 @@
discard """
action: "reject"
line: 29
errormsg: "\'vectFunc\' doesn't have a concrete type, due to unspecified generic parameters."
"""
type
# simple vector of declared fixed length
vector[N : static[int]] = array[0..N-1, float]
proc `*`[T](x: float, a: vector[T]): vector[T] =
# multiplication by scalar
for ii in 0..high(a):
result[ii] = a[ii]*x
let
# define a vector of length 3
x: vector[3] = [1.0, 3.0, 5.0]
proc vectFunc[T](x: vector[T]): vector[T] {.procvar.} =
# Define a vector function
result = 2.0*x
proc passVectFunction[T](g: proc(x: vector[T]): vector[T], x: vector[T]): vector[T] =
# pass a vector function as input in another procedure
result = g(x)
let
xNew = passVectFunction(vectFunc,x)

10
tests/generics/t7141.nim Normal file
View file

@ -0,0 +1,10 @@
discard """
action: "reject"
line: 7
errormsg: "cannot instantiate: \'T\'"
"""
proc foo[T](x: T) =
discard
var fun = if true: foo else: foo

View file

@ -99,3 +99,15 @@ echo sizeof(a)
echo sizeof(b) echo sizeof(b)
echo sizeof(c) echo sizeof(c)
# This is the same example but using a proc instead of a macro
# Instead of type mismatch for macro, proc just failed with internal error: getTypeDescAux(tyNone)
# https://github.com/nim-lang/Nim/issues/7231
proc getBase2*(bits: static[int]): typedesc =
if bits == 128:
result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint64"))
else:
result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint32"))
type
MpUint2*[bits: static[int]] = getbase2(bits)

29
tests/stdlib/tsugar.nim Normal file
View file

@ -0,0 +1,29 @@
discard """
file: "tsugar.nim"
output: ""
"""
import sugar
import macros
block distinctBase:
block:
type
Foo[T] = distinct seq[T]
var a: Foo[int]
doAssert a.type.distinctBase is seq[int]
block:
# simplified from https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458
macro uintImpl(bits: static[int]): untyped =
if bits >= 128:
let inner = getAST(uintImpl(bits div 2))
result = newTree(nnkBracketExpr, ident("UintImpl"), inner)
else:
result = ident("uint64")
type
BaseUint = UintImpl or SomeUnsignedInt
UintImpl[Baseuint] = object
Uint[bits: static[int]] = distinct uintImpl(bits)
doAssert Uint[128].distinctBase is UintImpl[uint64]