Merge branch 'devel' into fix_issues_9126

This commit is contained in:
Andreas Rumpf
2018-10-01 14:15:35 +02:00
committed by GitHub
29 changed files with 219 additions and 114 deletions

View File

@@ -181,7 +181,7 @@ proc isHarmlessVar*(s: PSym; c: Con): bool =
if c.g[i].sym == s:
if defsite < 0: defsite = i
else: return false
of use:
of use, useWithinCall:
if c.g[i].sym == s:
if defsite < 0: return false
for j in defsite .. i:
@@ -190,10 +190,11 @@ proc isHarmlessVar*(s: PSym; c: Con): bool =
# if we want to die after the first 'use':
if usages > 1: return false
inc usages
of useWithinCall:
if c.g[i].sym == s: return false
#of useWithinCall:
# if c.g[i].sym == s: return false
of goto, fork:
discard "we do not perform an abstract interpretation yet"
result = usages <= 1
template interestingSym(s: PSym): bool =
s.owner == c.owner and s.kind in InterestingSyms and hasDestructor(s.typ)
@@ -222,26 +223,35 @@ proc patchHead(s: PSym) =
if sfFromGeneric in s.flags:
patchHead(s.ast[bodyPos])
template genOp(opr, opname) =
proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string) =
var m = "'" & opname & "' is not available for type <" & typeToString(t) & ">"
if opname == "=" and ri != nil:
m.add "; requires a copy because it's not the last read of '"
m.add renderTree(ri)
m.add '\''
localError(c.graph.config, ri.info, errGenerated, m)
template genOp(opr, opname, ri) =
let op = opr
if op == nil:
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator not found for type " & typeToString(t))
elif op.ast[genericParamsPos].kind != nkEmpty:
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic")
patchHead op
if sfError in op.flags: checkForErrorPragma(c, t, ri, opname)
result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest))
proc genSink(c: Con; t: PType; dest: PNode): PNode =
proc genSink(c: Con; t: PType; dest, ri: PNode): PNode =
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
genOp(if t.sink != nil: t.sink else: t.assignment, "=sink")
genOp(if t.sink != nil: t.sink else: t.assignment, "=sink", ri)
proc genCopy(c: Con; t: PType; dest: PNode): PNode =
proc genCopy(c: Con; t: PType; dest, ri: PNode): PNode =
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
genOp(t.assignment, "=")
genOp(t.assignment, "=", ri)
proc genDestroy(c: Con; t: PType; dest: PNode): PNode =
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
genOp(t.destructor, "=destroy")
genOp(t.destructor, "=destroy", nil)
proc addTopVar(c: var Con; v: PNode) =
c.topLevelVars.add newTree(nkIdentDefs, v, c.emptyNode, c.emptyNode)
@@ -291,33 +301,33 @@ proc genMagicCall(n: PNode; c: var Con; magicname: string; m: TMagic): PNode =
proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
if ri.kind in constrExprs:
result = genSink(c, dest.typ, dest)
result = genSink(c, dest.typ, dest, ri)
# watch out and no not transform 'ri' twice if it's a call:
let ri2 = copyNode(ri)
recurse(ri, ri2)
result.add ri2
elif ri.kind == nkSym and isHarmlessVar(ri.sym, c):
elif ri.kind == nkSym and ri.sym.kind != skParam and isHarmlessVar(ri.sym, c):
# Rule 3: `=sink`(x, z); wasMoved(z)
var snk = genSink(c, dest.typ, dest)
var snk = genSink(c, dest.typ, dest, ri)
snk.add p(ri, c)
result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved))
elif ri.kind == nkSym and isSinkParam(ri.sym):
result = genSink(c, dest.typ, dest)
result = genSink(c, dest.typ, dest, ri)
result.add destructiveMoveSink(ri, c)
else:
result = genCopy(c, dest.typ, dest)
result = genCopy(c, dest.typ, dest, ri)
result.add p(ri, c)
proc passCopyToSink(n: PNode; c: var Con): PNode =
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let tmp = getTemp(c, n.typ, n.info)
if hasDestructor(n.typ):
var m = genCopy(c, n.typ, tmp)
var m = genCopy(c, n.typ, tmp, n)
m.add p(n, c)
result.add m
message(c.graph.config, n.info, hintPerformance,
"passing '$1' to a sink parameter introduces an implicit copy; " &
"use 'move($1)' to prevent it" % $n)
("passing '$1' to a sink parameter introduces an implicit copy; " &
"use 'move($1)' to prevent it") % $n)
else:
result.add newTree(nkAsgn, tmp, p(n, c))
result.add tmp
@@ -331,6 +341,7 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode =
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
var temp = newSym(skLet, getIdent(c.graph.cache, "blitTmp"), c.owner, n.info)
temp.typ = n.typ
var v = newNodeI(nkLetSection, n.info)
let tempAsNode = newSymNode(temp)
@@ -410,7 +421,7 @@ proc p(n: PNode; c: var Con): PNode =
discard "produce temp creation"
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let tmp = getTemp(c, n.typ, n.info)
var sinkExpr = genSink(c, n.typ, tmp)
var sinkExpr = genSink(c, n.typ, tmp, n)
sinkExpr.add n
result.add sinkExpr
result.add tmp

View File

@@ -442,4 +442,5 @@ proc dataflowAnalysis*(s: PSym; body: PNode; conf: ConfigRef) =
proc constructCfg*(s: PSym; body: PNode): ControlFlowGraph =
## constructs a control flow graph for ``body``.
var c = Con(code: @[], blocks: @[])
gen(c, body)
shallowCopy(result, c.code)

View File

@@ -112,7 +112,7 @@ proc getOutFile2(conf: ConfigRef; filename: RelativeFile,
else:
result = getOutFile(conf, filename, ext)
proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef): PDoc =
proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef, outExt: string = HtmlExt): PDoc =
declareClosures()
new(result)
result.conf = conf
@@ -146,7 +146,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef):
warnUser, "only 'rst2html' supports the ':test:' attribute")
result.emitted = initIntSet()
result.destFile = getOutFile2(conf, relativeTo(filename, conf.projectPath),
HtmlExt, RelativeDir"htmldocs", false)
outExt, RelativeDir"htmldocs", false)
result.thisDir = result.destFile.splitFile.dir
proc dispA(conf: ConfigRef; dest: var Rope, xml, tex: string, args: openArray[Rope]) =
@@ -960,7 +960,7 @@ proc commandDoc*(cache: IdentCache, conf: ConfigRef) =
proc commandRstAux(cache: IdentCache, conf: ConfigRef;
filename: AbsoluteFile, outExt: string) =
var filen = addFileExt(filename, "txt")
var d = newDocumentor(filen, cache, conf)
var d = newDocumentor(filen, cache, conf, outExt)
d.onTestSnippet = proc (d: var RstGenerator; filename, cmd: string;
status: int; content: string) =
var outp: AbsoluteFile

View File

@@ -961,6 +961,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
# ``proc p() {.error}`` and ``proc p() = {.error: "msg".}``
if it.kind in nkPragmaCallKinds: discard getStrLitNode(c, it)
incl(sym.flags, sfError)
excl(sym.flags, sfForward)
else:
let s = expectStrLit(c, it)
recordPragma(c, it, "error", s)

View File

@@ -225,7 +225,7 @@ proc semGenericStmt(c: PContext, n: PNode,
var mixinContext = false
if s != nil:
incl(s.flags, sfUsed)
mixinContext = s.magic in {mDefined, mDefinedInScope, mCompiles, mRunnableExamples}
mixinContext = s.magic in {mDefined, mDefinedInScope, mCompiles}
let sc = symChoice(c, fn, s, if s.isMixedIn: scForceOpen else: scOpen)
case s.kind
of skMacro:
@@ -255,11 +255,11 @@ proc semGenericStmt(c: PContext, n: PNode,
discard
of skProc, skFunc, skMethod, skIterator, skConverter, skModule:
result.sons[0] = sc
# do not check of 's.magic==mRoof' here because it might be some
# other '^' but after overload resolution the proper one:
if ctx.bracketExpr != nil and n.len == 2 and s.name.s == "^":
result.add ctx.bracketExpr
first = 1
# We're not interested in the example code during this pass so let's
# skip it
if s.magic == mRunnableExamples:
inc first
of skGenericParam:
result.sons[0] = newSymNodeTypeDesc(s, fn.info)
styleCheckUse(fn.info, s)

View File

@@ -1677,7 +1677,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
else:
if s.kind == skMethod: semMethodPrototype(c, s, n)
if proto != nil: localError(c.config, n.info, errImplOfXexpected % proto.name.s)
if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone:
if {sfImportc, sfBorrow, sfError} * s.flags == {} and s.magic == mNone:
incl(s.flags, sfForward)
elif sfBorrow in s.flags: semBorrow(c, n, s)
sideEffectsCheck(c, s)

View File

@@ -38,7 +38,8 @@ doc.section.toc = """
# * $seeSrc: generated HTML from doc.item.seesrc (if some switches are used).
doc.item = """
<dt id="$itemSym"><a name="$itemSymOrID"></a><pre>$header</pre></dt>
<a id="$itemSymOrIdEnc"></a>
<dt><pre>$header</pre></dt>
<dd>
$desc
$seeSrc
@@ -48,7 +49,7 @@ $seeSrc
# Chunk of HTML emitted for each entry in the HTML table of contents.
# See doc.item for available substitution variables.
doc.item.toc = """
<li><a class="reference" href="#$itemSymOrID"
<li><a class="reference" href="#$itemSymOrIDEnc"
title="$header_plain">$name<span class="attachedType" style="visibility:hidden">$attype</span></a></li>
"""

View File

@@ -135,7 +135,7 @@ them along the Nim code is easier than using a system library. Libraries
installed on the host system can be linked in with the `PassL pragma
<nimc.html#passl-pragma>`_.
To wrap native code, take a look at the `c2nim tool <c2nim.html>`_ which helps
To wrap native code, take a look at the `c2nim tool <https://nim-lang.org/docs/c2nim.html>`_ which helps
with the process of scanning and transforming header files into a Nim
interface.

View File

@@ -131,7 +131,7 @@ Output::
Similarly to the old ``doc`` command the old ``jsondoc`` command has been
renamed ``jsondoc0``.
The ``jsondoc0`` command::
nim jsondoc0 sample
@@ -158,11 +158,11 @@ Project switch
--------------
::
nim doc2 --project filename.nim
nim doc --project filename.nim
This will recursively generate documentation of all nim modules imported
into the input module, including system modules. Be careful with this command,
as it may end up sprinkling html files all over your filesystem!
into the input module that belong to the Nimble package that ``filename.nim``
belongs to.
Index switch
@@ -222,9 +222,8 @@ Usage::
Output::
You're reading it!
The input can be viewed here `docgen.txt <docgen.txt>`_. The ``rst2tex``
command is invoked identically to ``rst2html``, but outputs a .tex file instead
of .html.
The ``rst2tex`` command is invoked identically to ``rst2html``, but outputs
a .tex file instead of .html.
HTML anchor generation
@@ -312,8 +311,7 @@ but can have up to four (additional columns are ignored). The content of these
columns is:
1. Mandatory term being indexed. Terms can include quoting according to
Nim's rules (eg. \`^\` like in `the actors module
<actors.html#^,ptr.TChannel[T]>`_).
Nim's rules (eg. \`^\`).
2. Base filename plus anchor hyper link (eg.
``algorithm.html#*,int,SortOrder``).
3. Optional human readable string to display as hyper link. If the value is not

View File

@@ -27,10 +27,6 @@ The documentation consists of several documents:
| The Nim compiler supports source code filters as a simple yet powerful
builtin templating system.
- | `Term rewriting macros <trmacros.html>`_
| Term rewriting macros enhance the compilation process with user defined
optimizations.
- | `Internal documentation <intern.html>`_
| The internal documentation describes how the compiler is implemented. Read
this if you want to hack the compiler.

View File

@@ -184,12 +184,6 @@ Generic Operating System Services
This module provides support for memory mapped files (Posix's ``mmap``)
on the different operating systems.
* `fsmonitor <fsmonitor.html>`_
This module implements the ability to monitor a directory/file for changes
using Posix's inotify API.
**Warning:** This module will likely be moved out to a Nimble package soon.
* `asyncfile <asyncfile.html>`_
This module implements asynchronous file reading and writing using
``asyncdispatch``.
@@ -238,9 +232,6 @@ Internet Protocols and Support
This module implements procs for opening URLs with the user's default
browser.
* `httpserver <httpserver.html>`_
This module implements a simple HTTP server.
* `httpclient <httpclient.html>`_
This module implements a simple HTTP client which supports both synchronous
and asynchronous retrieval of web pages.
@@ -289,11 +280,6 @@ Parsers
* `parseopt <parseopt.html>`_
The ``parseopt`` module implements a command line option parser.
* `parseopt2 <parseopt2.html>`_
The ``parseopt2`` module implements a command line option parser. This
supports long and short command options with optional values and command line
arguments.
* `parsecfg <parsecfg.html>`_
The ``parsecfg`` module implements a high performance configuration file
parser. The configuration file's syntax is similar to the Windows ``.ini``
@@ -393,10 +379,6 @@ Multimedia support
Miscellaneous
-------------
* `events <events.html>`_
This module implements an event system that is not dependent on external
graphical toolkits.
* `oids <oids.html>`_
An OID is a global ID that consists of a timestamp,
a unique counter and a random value. This combination should suffice to

View File

@@ -7344,7 +7344,7 @@ prefixes ``/*TYPESECTION*/`` or ``/*VARSECTION*/`` or ``/*INCLUDESECTION*/``:
ImportCpp pragma
----------------
**Note**: `c2nim <c2nim.html>`_ can parse a large subset of C++ and knows
**Note**: `c2nim <https://nim-lang.org/docs/c2nim.html>`_ can parse a large subset of C++ and knows
about the ``importcpp`` pragma pattern language. It is not necessary
to know all the details described here.

View File

@@ -136,7 +136,7 @@ source code with the `when statement <manual.html#when-statement>`_ and
`defined proc <system.html#defined>`_. The typical use of this switch is to
enable builds in release mode (``-d:release``) where certain safety checks are
omitted for better performance. Another common use is the ``-d:ssl`` switch to
activate `SSL sockets <sockets.html>`_.
activate SSL sockets.
Additionally, you may pass a value along with the symbol: ``-d:x=y``
which may be used in conjunction with the `compile time define
@@ -158,7 +158,7 @@ The ``nim`` executable processes configuration files in the following
directories (in this order; later files overwrite previous settings):
1) ``$nim/config/nim.cfg``, ``/etc/nim/nim.cfg`` (UNIX) or ``%NIM%/config/nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option.
2) ``$HOME/.config/nim.cfg`` (POSIX) or ``%APPDATA%/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option.
2) If environment variable ``XDG_CONFIG_HOME`` is defined, ``$XDG_CONFIG_HOME/nim/nim.cfg`` or ``~/.config/nim/nim.cfg`` (POSIX) or ``%APPDATA%/nim/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option.
3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option.
4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option.
5) A project can also have a project specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command line option.
@@ -289,8 +289,7 @@ For example, with the above mentioned config::
This will generate a file called ``switchhomebrew.elf`` which can then be turned into
an nro file with the ``elf2nro`` tool in the DevkitPro release. Examples can be found at
`the nim-libnx github repo <https://github.com/jyapayne/nim-libnx.git>`_ or you can use
`the switch builder tool <https://github.com/jyapayne/switch-builder.git>`_.
`the nim-libnx github repo <https://github.com/jyapayne/nim-libnx.git>`_.
There are a few things that don't work because the DevkitPro libraries don't support them.
They are:
@@ -396,11 +395,6 @@ the generated C contains code to ensure that proper stack traces with line
number information are given if the program crashes or an uncaught exception
is raised.
Debugger option
---------------
The ``debugger`` option enables or disables the *Embedded Nim Debugger*.
See the documentation of endb_ for further information.
Hot code reloading
------------------
**Note:** At the moment hot code reloading is supported only in
@@ -442,11 +436,6 @@ Once your code is compiled for hot reloading, you can use a framework such
as `LiveReload <http://livereload.com/>` or `BrowserSync <https://browsersync.io/>`
to implement the actual reloading behavior in your project.
Breakpoint pragma
-----------------
The *breakpoint* pragma was specially added for the sake of debugging with
ENDB. See the documentation of `endb <endb.html>`_ for further information.
DynlibOverride
==============
@@ -543,13 +532,6 @@ fatal errors that produce a stack trace. This can be disabled with the
``-d:noSignalHandler`` switch.
Debugging with Nim
==================
Nim comes with its own *Embedded Nim Debugger*. See
the documentation of endb_ for further information.
Optimizing for Nim
==================

View File

@@ -13,7 +13,7 @@ The standard distribution ships with the following tools:
and obtain useful information like definition of symbols or suggestions for
completion.
- | `C2nim <c2nim.html>`_
- | `C2nim <https://nim-lang.org/docs/c2nim.html>`_
| C to Nim source converter. Translates C header files to Nim.
- | `nimgrep <nimgrep.html>`_

View File

@@ -183,7 +183,7 @@ proc sqlGetDBMS(db: var DbConn): string {.
db.sqlCheck(SQLGetInfo(db.hDb, SQL_DBMS_NAME, cast[SqlPointer](buf.addr),
4095.TSqlSmallInt, sz.addr))
except: discard
return $buf.cstring
return $(addr buf)
proc dbQuote*(s: string): string {.noSideEffect.} =
## DB quotes the string.
@@ -201,10 +201,7 @@ proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string {.
var a = 0
for c in items(string(formatstr)):
if c == '?':
if args[a] == nil:
add(result, "NULL")
else:
add(result, dbQuote(args[a]))
add(result, dbQuote(args[a]))
inc(a)
else:
add(result, c)
@@ -303,7 +300,7 @@ iterator fastRows*(db: var DbConn, query: SqlQuery,
buf[0] = '\0'
db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
rowRes[colId-1] = $buf.cstring
rowRes[colId-1] = $(addr buf)
cCnt = tempcCnt
yield rowRes
res = SQLFetch(db.stmt)
@@ -338,7 +335,7 @@ iterator instantRows*(db: var DbConn, query: SqlQuery,
buf[0] = '\0'
db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
rowRes[colId-1] = $buf.cstring
rowRes[colId-1] = $(addr buf)
cCnt = tempcCnt
yield (row: rowRes, len: cCnt.int)
res = SQLFetch(db.stmt)
@@ -380,7 +377,7 @@ proc getRow*(db: var DbConn, query: SqlQuery,
buf[0] = '\0'
db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
rowRes[colId-1] = $buf.cstring
rowRes[colId-1] = $(addr buf)
cCnt = tempcCnt
res = SQLFetch(db.stmt)
result = rowRes
@@ -415,7 +412,7 @@ proc getAllRows*(db: var DbConn, query: SqlQuery,
buf[0] = '\0'
db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
rowRes[colId-1] = $buf.cstring
rowRes[colId-1] = $(addr buf)
cCnt = tempcCnt
rows.add(rowRes)
res = SQLFetch(db.stmt)

View File

@@ -424,11 +424,15 @@ proc sortIndex(a: var openArray[IndexEntry]) =
if h == 1: break
proc escapeLink(s: string): string =
## This proc is mostly copied from uri/encodeUrl except that
## these chars are also left unencoded: '#', '/'.
result = newStringOfCap(s.len + s.len shr 2)
for c in items(s):
case c
of 'a'..'z', '_', 'A'..'Z', '0'..'9', '.', '#', ',', '/':
result.add c
of 'a'..'z', 'A'..'Z', '0'..'9', '-', '.', '_', '~': # same as that in uri/encodeUrl
add(result, c)
of '#', '/': # example.com/foo/#bar (don't escape the '/' and '#' in such links)
add(result, c)
else:
add(result, "%")
add(result, toHex(ord(c), 2))
@@ -444,7 +448,7 @@ proc generateSymbolIndex(symbols: seq[IndexEntry]): string =
var j = i
while j < symbols.len and keyword == symbols[j].keyword:
let
url = symbols[j].link #.escapeLink
url = symbols[j].link.escapeLink
text = if symbols[j].linkTitle.len > 0: symbols[j].linkTitle else: url
desc = if symbols[j].linkDesc.len > 0: symbols[j].linkDesc else: ""
if desc.len > 0:

View File

@@ -81,7 +81,7 @@ proc advice*(s: var ThreadPoolState): ThreadPoolAdvice =
result = doNothing
inc s.calls
when not defined(testing) and isMainModule:
when not defined(testing) and isMainModule and not defined(nimdoc):
import random
proc busyLoop() =

View File

@@ -1147,7 +1147,7 @@ proc processType(typeName: NimNode, obj: NimNode,
`getEnumCall`
)
of nnkSym:
let name = ($typeName).normalize
let name = normalize($typeName.getTypeImpl())
case name
of "string":
result = quote do:
@@ -1639,3 +1639,17 @@ when isMainModule:
# bug #6438
doAssert($ %*[] == "[]")
doAssert($ %*{} == "{}")
# bug #9111
block:
type
Bar = string
Foo = object
a: int
b: Bar
let
js = """{"a": 123, "b": "abc"}""".parseJson
foo = js.to Foo
doAssert(foo.b == "abc")

View File

@@ -60,6 +60,7 @@ proc encodeUrl*(s: string, usePlus=true): string =
let fromSpace = if usePlus: "+" else: "%20"
for c in s:
case c
# https://tools.ietf.org/html/rfc3986#section-2.3
of 'a'..'z', 'A'..'Z', '0'..'9', '-', '.', '_', '~': add(result, c)
of ' ': add(result, fromSpace)
else:

View File

@@ -1250,7 +1250,7 @@ function main() {
<li>
<a class="reference reference-toplevel" href="#12" id="62">Procs</a>
<ul class="simple simple-toc-section">
<li><a class="reference" href="#someType,"
<li><a class="reference" href="#someType%2C"
title="someType(): SomeType"><wbr />some<wbr />Type<span class="attachedType" style="visibility:hidden">SomeType</span></a></li>
</ul>
@@ -1265,7 +1265,8 @@ function main() {
<div class="section" id="7">
<h1><a class="toc-backref" href="#7">Types</a></h1>
<dl class="item">
<dt id="SomeType"><a name="SomeType"></a><pre><a href="utils.html#SomeType"><span class="Identifier">SomeType</span></a> <span class="Other">=</span> <span class="Keyword">enum</span>
<a id="SomeType"></a>
<dt><pre><a href="utils.html#SomeType"><span class="Identifier">SomeType</span></a> <span class="Other">=</span> <span class="Keyword">enum</span>
<span class="Identifier">enumValueA</span><span class="Other">,</span> <span class="Identifier">enumValueB</span><span class="Other">,</span> <span class="Identifier">enumValueC</span></pre></dt>
<dd>
@@ -1276,7 +1277,8 @@ function main() {
<div class="section" id="12">
<h1><a class="toc-backref" href="#12">Procs</a></h1>
<dl class="item">
<dt id="someType"><a name="someType,"></a><pre><span class="Keyword">proc</span> <span class="Identifier">someType</span><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="utils.html#SomeType"><span class="Identifier">SomeType</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
<a id="someType%2C"></a>
<dt><pre><span class="Keyword">proc</span> <span class="Identifier">someType</span><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="utils.html#SomeType"><span class="Identifier">SomeType</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
<dd>
constructor.

View File

@@ -1255,7 +1255,7 @@ function main() {
<li>
<a class="reference reference-toplevel" href="#12" id="62">Procs</a>
<ul class="simple simple-toc-section">
<li><a class="reference" href="#bar,T,T"
<li><a class="reference" href="#bar%2CT%2CT"
title="bar[T](a, b: T): T"><wbr />bar<span class="attachedType" style="visibility:hidden"></span></a></li>
</ul>
@@ -1263,7 +1263,7 @@ function main() {
<li>
<a class="reference reference-toplevel" href="#17" id="67">Macros</a>
<ul class="simple simple-toc-section">
<li><a class="reference" href="#bar.m,"
<li><a class="reference" href="#bar.m%2C"
title="bar(): untyped"><wbr />bar<span class="attachedType" style="visibility:hidden"></span></a></li>
</ul>
@@ -1271,7 +1271,7 @@ function main() {
<li>
<a class="reference reference-toplevel" href="#18" id="68">Templates</a>
<ul class="simple simple-toc-section">
<li><a class="reference" href="#foo.t,SomeType,SomeType"
<li><a class="reference" href="#foo.t%2CSomeType%2CSomeType"
title="foo(a, b: SomeType)"><wbr />foo<span class="attachedType" style="visibility:hidden"></span></a></li>
</ul>
@@ -1297,7 +1297,8 @@ function main() {
<div class="section" id="8">
<h1><a class="toc-backref" href="#8">Vars</a></h1>
<dl class="item">
<dt id="aVariable"><a name="aVariable"></a><pre><span class="Identifier">aVariable</span><span class="Other">:</span> <span class="Identifier">array</span><span class="Other">[</span><span class="DecNumber">1</span><span class="Other">,</span> <span class="Identifier">int</span><span class="Other">]</span></pre></dt>
<a id="aVariable"></a>
<dt><pre><span class="Identifier">aVariable</span><span class="Other">:</span> <span class="Identifier">array</span><span class="Other">[</span><span class="DecNumber">1</span><span class="Other">,</span> <span class="Identifier">int</span><span class="Other">]</span></pre></dt>
<dd>
@@ -1307,7 +1308,8 @@ function main() {
<div class="section" id="12">
<h1><a class="toc-backref" href="#12">Procs</a></h1>
<dl class="item">
<dt id="bar"><a name="bar,T,T"></a><pre><span class="Keyword">proc</span> <span class="Identifier">bar</span><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">a</span><span class="Other">,</span> <span class="Identifier">b</span><span class="Other">:</span> <span class="Identifier">T</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">T</span></pre></dt>
<a id="bar%2CT%2CT"></a>
<dt><pre><span class="Keyword">proc</span> <span class="Identifier">bar</span><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">a</span><span class="Other">,</span> <span class="Identifier">b</span><span class="Other">:</span> <span class="Identifier">T</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">T</span></pre></dt>
<dd>
@@ -1317,7 +1319,8 @@ function main() {
<div class="section" id="17">
<h1><a class="toc-backref" href="#17">Macros</a></h1>
<dl class="item">
<dt id="bar"><a name="bar.m,"></a><pre><span class="Keyword">macro</span> <span class="Identifier">bar</span><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">untyped</span></pre></dt>
<a id="bar.m%2C"></a>
<dt><pre><span class="Keyword">macro</span> <span class="Identifier">bar</span><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">untyped</span></pre></dt>
<dd>
@@ -1327,7 +1330,8 @@ function main() {
<div class="section" id="18">
<h1><a class="toc-backref" href="#18">Templates</a></h1>
<dl class="item">
<dt id="foo"><a name="foo.t,SomeType,SomeType"></a><pre><span class="Keyword">template</span> <span class="Identifier">foo</span><span class="Other">(</span><span class="Identifier">a</span><span class="Other">,</span> <span class="Identifier">b</span><span class="Other">:</span> <a href="subdir/subdir_b/utils.html#SomeType"><span class="Identifier">SomeType</span></a><span class="Other">)</span></pre></dt>
<a id="foo.t%2CSomeType%2CSomeType"></a>
<dt><pre><span class="Keyword">template</span> <span class="Identifier">foo</span><span class="Other">(</span><span class="Identifier">a</span><span class="Other">,</span> <span class="Identifier">b</span><span class="Other">:</span> <a href="subdir/subdir_b/utils.html#SomeType"><span class="Identifier">SomeType</span></a><span class="Other">)</span></pre></dt>
<dd>
This does nothing

View File

@@ -1227,9 +1227,9 @@ function main() {
</ul></dd>
<dt><a name="bar" href="#bar"><span>bar:</span></a></dt><dd><ul class="simple">
<li><a class="reference external"
data-doc-search-tag="testproject: bar[T](a, b: T): T" href="testproject.html#bar,T,T">testproject: bar[T](a, b: T): T</a></li>
data-doc-search-tag="testproject: bar[T](a, b: T): T" href="testproject.html#bar%2CT%2CT">testproject: bar[T](a, b: T): T</a></li>
<li><a class="reference external"
data-doc-search-tag="testproject: bar(): untyped" href="testproject.html#bar.m,">testproject: bar(): untyped</a></li>
data-doc-search-tag="testproject: bar(): untyped" href="testproject.html#bar.m%2C">testproject: bar(): untyped</a></li>
</ul></dd>
<dt><a name="enumValueA" href="#enumValueA"><span>enumValueA:</span></a></dt><dd><ul class="simple">
<li><a class="reference external"
@@ -1245,7 +1245,7 @@ function main() {
</ul></dd>
<dt><a name="foo" href="#foo"><span>foo:</span></a></dt><dd><ul class="simple">
<li><a class="reference external"
data-doc-search-tag="testproject: foo(a, b: SomeType)" href="testproject.html#foo.t,SomeType,SomeType">testproject: foo(a, b: SomeType)</a></li>
data-doc-search-tag="testproject: foo(a, b: SomeType)" href="testproject.html#foo.t%2CSomeType%2CSomeType">testproject: foo(a, b: SomeType)</a></li>
</ul></dd>
<dt><a name="SomeType" href="#SomeType"><span>SomeType:</span></a></dt><dd><ul class="simple">
<li><a class="reference external"
@@ -1253,7 +1253,7 @@ function main() {
</ul></dd>
<dt><a name="someType" href="#someType"><span>someType:</span></a></dt><dd><ul class="simple">
<li><a class="reference external"
data-doc-search-tag="utils: someType(): SomeType" href="subdir/subdir_b/utils.html#someType,">utils: someType(): SomeType</a></li>
data-doc-search-tag="utils: someType(): SomeType" href="subdir/subdir_b/utils.html#someType%2C">utils: someType(): SomeType</a></li>
</ul></dd>
</dl>
<div class="row">

View File

@@ -9,6 +9,7 @@ import os, asyncfile, asyncdispatch
const F = "test_async.txt"
removeFile(F)
defer: removeFile(F)
let f = openAsync(F, fmWrite)
var futs = newSeq[Future[void]]()
for i in 1..3:

View File

@@ -0,0 +1,33 @@
discard """
errormsg: "'=' is not available for type <Foo>; requires a copy because it's not the last read of 'otherTree'"
line: 29
"""
type
Foo = object
x: int
proc `=destroy`(f: var Foo) = f.x = 0
proc `=`(a: var Foo; b: Foo) {.error.} # = a.x = b.x
proc `=sink`(a: var Foo; b: Foo) = a.x = b.x
proc createTree(x: int): Foo =
Foo(x: x)
proc take2(a, b: sink Foo) =
echo a.x, " ", b.x
proc allowThis() =
# all these temporary lets are harmless:
let otherTree = createTree(44)
let b = otherTree
let c = b
take2(createTree(34), c)
proc preventThis() =
let otherTree = createTree(44)
let b = otherTree
take2(createTree(34), otherTree)
allowThis()
preventThis()

31
tests/generics/t8694.nim Normal file
View File

@@ -0,0 +1,31 @@
discard """
output: '''
true
true
true
'''
"""
when true:
# Error: undeclared identifier: '|'
proc bar[T](t:T): bool =
runnableExamples:
type Foo = int | float
true
echo bar(0)
when true:
# ok
proc bar(t:int): bool =
runnableExamples:
type Foo = int | float
true
echo bar(0)
when true:
# Error: undeclared identifier: '|'
proc bar(t:typedesc): bool =
runnableExamples:
type Foo = int | float
true
echo bar(int)

33
tests/generics/t9130.nim Normal file
View File

@@ -0,0 +1,33 @@
when true:
# stack overflow
template baz1*(iter: untyped): untyped =
runnableExamples:
import sugar
proc fun(a: proc(x:int): int) = discard
baz1(fun(x:int => x))
discard
proc foo1[A](ts: A) =
baz1(ts)
when true:
# ok
template baz2*(iter: untyped): untyped =
runnableExamples:
import sugar
proc fun(a: proc(x:int): int) = discard
baz2(fun(x:int => x))
discard
proc foo2(ts: int) =
baz2(ts)
when true:
# stack overflow
template baz3*(iter: untyped): untyped =
runnableExamples:
baz3(fun(x:int => x))
discard
proc foo3[A](ts: A) =
baz3(ts)

View File

@@ -218,7 +218,7 @@ proc ioTests(r: var TResults, cat: Category, options: string) =
# dummy compile result:
var c = initResults()
testSpec c, makeTest("tests/system/helpers/readall_echo", options, cat)
testSpec r, makeTest("tests/system/io", options, cat)
testSpec r, makeTest("tests/system/tio", options, cat)
# ------------------------- async tests ---------------------------------------
proc asyncTests(r: var TResults, cat: Category, options: string) =

View File

@@ -86,7 +86,7 @@ proc fuzzyMatch*(pattern, str: cstring) : tuple[score: int, matched: bool] =
score += ord(LeadingCharMatch)
var onBoundary = (patIndex == high(pattern))
if not onBoundary:
if not onBoundary and strIndex < high(str):
let
nextPatternChar = toLowerAscii(pattern[patIndex + 1])
nextStrChar = toLowerAscii(str[strIndex + 1])

View File

@@ -94,6 +94,8 @@ doc/manual/var_t_return.rst
lib/system.nim
lib/system/nimscript.nim
lib/pure/ospaths.nim
lib/pure/parsejson.nim
lib/pure/cstrutils.nim
lib/core/macros.nim
lib/pure/marshal.nim
lib/core/typeinfo.nim
@@ -102,6 +104,7 @@ lib/pure/typetraits.nim
nimsuggest/sexp.nim
lib/pure/concurrency/threadpool.nim
lib/pure/concurrency/cpuinfo.nim
lib/pure/concurrency/cpuload.nim
lib/js/dom.nim
lib/js/jsffi.nim
lib/js/jsconsole.nim
@@ -139,6 +142,7 @@ lib/pure/browsers.nim
lib/impure/db_postgres.nim
lib/impure/db_mysql.nim
lib/impure/db_sqlite.nim
lib/impure/db_odbc.nim
lib/pure/db_common.nim
lib/pure/httpserver.nim
lib/pure/httpclient.nim
@@ -156,6 +160,9 @@ lib/pure/mimetypes.nim
lib/pure/json.nim
lib/pure/base64.nim
lib/pure/scgi.nim
lib/impure/nre.nim
lib/deprecated/pure/sockets.nim
lib/deprecated/pure/asyncio.nim
lib/pure/collections/tables.nim
lib/pure/collections/sets.nim
lib/pure/collections/lists.nim
@@ -166,6 +173,7 @@ lib/pure/collections/queues.nim
lib/pure/collections/deques.nim
lib/pure/encodings.nim
lib/pure/collections/sequtils.nim
lib/pure/collections/rtarrays.nim
lib/pure/cookies.nim
lib/pure/memfiles.nim
lib/pure/subexes.nim
@@ -194,6 +202,7 @@ lib/pure/selectors.nim
lib/pure/sugar.nim
lib/pure/collections/chains.nim
lib/pure/asyncfile.nim
lib/deprecated/pure/ftpclient.nim
lib/pure/asyncftpclient.nim
lib/pure/lenientops.nim
lib/pure/md5.nim
@@ -203,7 +212,9 @@ lib/pure/oswalkdir.nim
lib/pure/collections/heapqueue.nim
lib/pure/fenv.nim
lib/std/sha1.nim
lib/std/varints.nim
lib/impure/rdstdin.nim
lib/wrappers/linenoise/linenoise.nim
lib/pure/strformat.nim
lib/pure/segfaults.nim
lib/pure/mersenne.nim
@@ -230,6 +241,8 @@ lib/wrappers/odbcsql.nim
lib/wrappers/pcre.nim
lib/wrappers/openssl.nim
lib/posix/posix.nim
lib/posix/linux.nim
lib/posix/termios.nim
lib/wrappers/odbcsql.nim
lib/js/jscore.nim
""".splitWhitespace()