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
commit e867c8e5c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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 c.g[i].sym == s:
if defsite < 0: defsite = i if defsite < 0: defsite = i
else: return false else: return false
of use: of use, useWithinCall:
if c.g[i].sym == s: if c.g[i].sym == s:
if defsite < 0: return false if defsite < 0: return false
for j in defsite .. i: 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 we want to die after the first 'use':
if usages > 1: return false if usages > 1: return false
inc usages inc usages
of useWithinCall: #of useWithinCall:
if c.g[i].sym == s: return false # if c.g[i].sym == s: return false
of goto, fork: of goto, fork:
discard "we do not perform an abstract interpretation yet" discard "we do not perform an abstract interpretation yet"
result = usages <= 1
template interestingSym(s: PSym): bool = template interestingSym(s: PSym): bool =
s.owner == c.owner and s.kind in InterestingSyms and hasDestructor(s.typ) 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: if sfFromGeneric in s.flags:
patchHead(s.ast[bodyPos]) 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 let op = opr
if op == nil: if op == nil:
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator not found for type " & typeToString(t)) globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator not found for type " & typeToString(t))
elif op.ast[genericParamsPos].kind != nkEmpty: elif op.ast[genericParamsPos].kind != nkEmpty:
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic") globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic")
patchHead op patchHead op
if sfError in op.flags: checkForErrorPragma(c, t, ri, opname)
result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest)) 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}) 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}) let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
genOp(t.assignment, "=") genOp(t.assignment, "=", ri)
proc genDestroy(c: Con; t: PType; dest: PNode): PNode = proc genDestroy(c: Con; t: PType; dest: PNode): PNode =
let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
genOp(t.destructor, "=destroy") genOp(t.destructor, "=destroy", nil)
proc addTopVar(c: var Con; v: PNode) = proc addTopVar(c: var Con; v: PNode) =
c.topLevelVars.add newTree(nkIdentDefs, v, c.emptyNode, c.emptyNode) 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 = proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
if ri.kind in constrExprs: 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: # watch out and no not transform 'ri' twice if it's a call:
let ri2 = copyNode(ri) let ri2 = copyNode(ri)
recurse(ri, ri2) recurse(ri, ri2)
result.add 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) # 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) snk.add p(ri, c)
result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved)) result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved))
elif ri.kind == nkSym and isSinkParam(ri.sym): 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) result.add destructiveMoveSink(ri, c)
else: else:
result = genCopy(c, dest.typ, dest) result = genCopy(c, dest.typ, dest, ri)
result.add p(ri, c) result.add p(ri, c)
proc passCopyToSink(n: PNode; c: var Con): PNode = proc passCopyToSink(n: PNode; c: var Con): PNode =
result = newNodeIT(nkStmtListExpr, n.info, n.typ) result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let tmp = getTemp(c, n.typ, n.info) let tmp = getTemp(c, n.typ, n.info)
if hasDestructor(n.typ): if hasDestructor(n.typ):
var m = genCopy(c, n.typ, tmp) var m = genCopy(c, n.typ, tmp, n)
m.add p(n, c) m.add p(n, c)
result.add m result.add m
message(c.graph.config, n.info, hintPerformance, message(c.graph.config, n.info, hintPerformance,
"passing '$1' to a sink parameter introduces an implicit copy; " & ("passing '$1' to a sink parameter introduces an implicit copy; " &
"use 'move($1)' to prevent it" % $n) "use 'move($1)' to prevent it") % $n)
else: else:
result.add newTree(nkAsgn, tmp, p(n, c)) result.add newTree(nkAsgn, tmp, p(n, c))
result.add tmp result.add tmp
@ -331,6 +341,7 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode =
result = newNodeIT(nkStmtListExpr, n.info, n.typ) result = newNodeIT(nkStmtListExpr, n.info, n.typ)
var temp = newSym(skLet, getIdent(c.graph.cache, "blitTmp"), c.owner, n.info) var temp = newSym(skLet, getIdent(c.graph.cache, "blitTmp"), c.owner, n.info)
temp.typ = n.typ
var v = newNodeI(nkLetSection, n.info) var v = newNodeI(nkLetSection, n.info)
let tempAsNode = newSymNode(temp) let tempAsNode = newSymNode(temp)
@ -410,7 +421,7 @@ proc p(n: PNode; c: var Con): PNode =
discard "produce temp creation" discard "produce temp creation"
result = newNodeIT(nkStmtListExpr, n.info, n.typ) result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let tmp = getTemp(c, n.typ, n.info) 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 sinkExpr.add n
result.add sinkExpr result.add sinkExpr
result.add tmp result.add tmp

View file

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

View file

@ -112,7 +112,7 @@ proc getOutFile2(conf: ConfigRef; filename: RelativeFile,
else: else:
result = getOutFile(conf, filename, ext) 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() declareClosures()
new(result) new(result)
result.conf = conf result.conf = conf
@ -146,7 +146,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef):
warnUser, "only 'rst2html' supports the ':test:' attribute") warnUser, "only 'rst2html' supports the ':test:' attribute")
result.emitted = initIntSet() result.emitted = initIntSet()
result.destFile = getOutFile2(conf, relativeTo(filename, conf.projectPath), result.destFile = getOutFile2(conf, relativeTo(filename, conf.projectPath),
HtmlExt, RelativeDir"htmldocs", false) outExt, RelativeDir"htmldocs", false)
result.thisDir = result.destFile.splitFile.dir result.thisDir = result.destFile.splitFile.dir
proc dispA(conf: ConfigRef; dest: var Rope, xml, tex: string, args: openArray[Rope]) = 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; proc commandRstAux(cache: IdentCache, conf: ConfigRef;
filename: AbsoluteFile, outExt: string) = filename: AbsoluteFile, outExt: string) =
var filen = addFileExt(filename, "txt") 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; d.onTestSnippet = proc (d: var RstGenerator; filename, cmd: string;
status: int; content: string) = status: int; content: string) =
var outp: AbsoluteFile 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".}`` # ``proc p() {.error}`` and ``proc p() = {.error: "msg".}``
if it.kind in nkPragmaCallKinds: discard getStrLitNode(c, it) if it.kind in nkPragmaCallKinds: discard getStrLitNode(c, it)
incl(sym.flags, sfError) incl(sym.flags, sfError)
excl(sym.flags, sfForward)
else: else:
let s = expectStrLit(c, it) let s = expectStrLit(c, it)
recordPragma(c, it, "error", s) recordPragma(c, it, "error", s)

View file

@ -225,7 +225,7 @@ proc semGenericStmt(c: PContext, n: PNode,
var mixinContext = false var mixinContext = false
if s != nil: if s != nil:
incl(s.flags, sfUsed) 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) let sc = symChoice(c, fn, s, if s.isMixedIn: scForceOpen else: scOpen)
case s.kind case s.kind
of skMacro: of skMacro:
@ -255,11 +255,11 @@ proc semGenericStmt(c: PContext, n: PNode,
discard discard
of skProc, skFunc, skMethod, skIterator, skConverter, skModule: of skProc, skFunc, skMethod, skIterator, skConverter, skModule:
result.sons[0] = sc 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 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: of skGenericParam:
result.sons[0] = newSymNodeTypeDesc(s, fn.info) result.sons[0] = newSymNodeTypeDesc(s, fn.info)
styleCheckUse(fn.info, s) styleCheckUse(fn.info, s)

View file

@ -1677,7 +1677,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
else: else:
if s.kind == skMethod: semMethodPrototype(c, s, n) if s.kind == skMethod: semMethodPrototype(c, s, n)
if proto != nil: localError(c.config, n.info, errImplOfXexpected % proto.name.s) 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) incl(s.flags, sfForward)
elif sfBorrow in s.flags: semBorrow(c, n, s) elif sfBorrow in s.flags: semBorrow(c, n, s)
sideEffectsCheck(c, 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). # * $seeSrc: generated HTML from doc.item.seesrc (if some switches are used).
doc.item = """ doc.item = """
<dt id="$itemSym"><a name="$itemSymOrID"></a><pre>$header</pre></dt> <a id="$itemSymOrIdEnc"></a>
<dt><pre>$header</pre></dt>
<dd> <dd>
$desc $desc
$seeSrc $seeSrc
@ -48,7 +49,7 @@ $seeSrc
# Chunk of HTML emitted for each entry in the HTML table of contents. # Chunk of HTML emitted for each entry in the HTML table of contents.
# See doc.item for available substitution variables. # See doc.item for available substitution variables.
doc.item.toc = """ 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> 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 installed on the host system can be linked in with the `PassL pragma
<nimc.html#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 with the process of scanning and transforming header files into a Nim
interface. interface.

View file

@ -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 This will recursively generate documentation of all nim modules imported
into the input module, including system modules. Be careful with this command, into the input module that belong to the Nimble package that ``filename.nim``
as it may end up sprinkling html files all over your filesystem! belongs to.
Index switch Index switch
@ -222,9 +222,8 @@ Usage::
Output:: Output::
You're reading it! You're reading it!
The input can be viewed here `docgen.txt <docgen.txt>`_. The ``rst2tex`` The ``rst2tex`` command is invoked identically to ``rst2html``, but outputs
command is invoked identically to ``rst2html``, but outputs a .tex file instead a .tex file instead of .html.
of .html.
HTML anchor generation HTML anchor generation
@ -312,8 +311,7 @@ but can have up to four (additional columns are ignored). The content of these
columns is: columns is:
1. Mandatory term being indexed. Terms can include quoting according to 1. Mandatory term being indexed. Terms can include quoting according to
Nim's rules (eg. \`^\` like in `the actors module Nim's rules (eg. \`^\`).
<actors.html#^,ptr.TChannel[T]>`_).
2. Base filename plus anchor hyper link (eg. 2. Base filename plus anchor hyper link (eg.
``algorithm.html#*,int,SortOrder``). ``algorithm.html#*,int,SortOrder``).
3. Optional human readable string to display as hyper link. If the value is not 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 | The Nim compiler supports source code filters as a simple yet powerful
builtin templating system. builtin templating system.
- | `Term rewriting macros <trmacros.html>`_
| Term rewriting macros enhance the compilation process with user defined
optimizations.
- | `Internal documentation <intern.html>`_ - | `Internal documentation <intern.html>`_
| The internal documentation describes how the compiler is implemented. Read | The internal documentation describes how the compiler is implemented. Read
this if you want to hack the compiler. 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``) This module provides support for memory mapped files (Posix's ``mmap``)
on the different operating systems. 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>`_ * `asyncfile <asyncfile.html>`_
This module implements asynchronous file reading and writing using This module implements asynchronous file reading and writing using
``asyncdispatch``. ``asyncdispatch``.
@ -238,9 +232,6 @@ Internet Protocols and Support
This module implements procs for opening URLs with the user's default This module implements procs for opening URLs with the user's default
browser. browser.
* `httpserver <httpserver.html>`_
This module implements a simple HTTP server.
* `httpclient <httpclient.html>`_ * `httpclient <httpclient.html>`_
This module implements a simple HTTP client which supports both synchronous This module implements a simple HTTP client which supports both synchronous
and asynchronous retrieval of web pages. and asynchronous retrieval of web pages.
@ -289,11 +280,6 @@ Parsers
* `parseopt <parseopt.html>`_ * `parseopt <parseopt.html>`_
The ``parseopt`` module implements a command line option parser. 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>`_ * `parsecfg <parsecfg.html>`_
The ``parsecfg`` module implements a high performance configuration file The ``parsecfg`` module implements a high performance configuration file
parser. The configuration file's syntax is similar to the Windows ``.ini`` parser. The configuration file's syntax is similar to the Windows ``.ini``
@ -393,10 +379,6 @@ Multimedia support
Miscellaneous Miscellaneous
------------- -------------
* `events <events.html>`_
This module implements an event system that is not dependent on external
graphical toolkits.
* `oids <oids.html>`_ * `oids <oids.html>`_
An OID is a global ID that consists of a timestamp, An OID is a global ID that consists of a timestamp,
a unique counter and a random value. This combination should suffice to 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 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 about the ``importcpp`` pragma pattern language. It is not necessary
to know all the details described here. 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 `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 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 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`` Additionally, you may pass a value along with the symbol: ``-d:x=y``
which may be used in conjunction with the `compile time define 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): 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. 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. 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. 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. 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 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 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 nim-libnx github repo <https://github.com/jyapayne/nim-libnx.git>`_.
`the switch builder tool <https://github.com/jyapayne/switch-builder.git>`_.
There are a few things that don't work because the DevkitPro libraries don't support them. There are a few things that don't work because the DevkitPro libraries don't support them.
They are: 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 number information are given if the program crashes or an uncaught exception
is raised. 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 Hot code reloading
------------------ ------------------
**Note:** At the moment hot code reloading is supported only in **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/>` as `LiveReload <http://livereload.com/>` or `BrowserSync <https://browsersync.io/>`
to implement the actual reloading behavior in your project. 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 DynlibOverride
============== ==============
@ -543,13 +532,6 @@ fatal errors that produce a stack trace. This can be disabled with the
``-d:noSignalHandler`` switch. ``-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 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 and obtain useful information like definition of symbols or suggestions for
completion. completion.
- | `C2nim <c2nim.html>`_ - | `C2nim <https://nim-lang.org/docs/c2nim.html>`_
| C to Nim source converter. Translates C header files to Nim. | C to Nim source converter. Translates C header files to Nim.
- | `nimgrep <nimgrep.html>`_ - | `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), db.sqlCheck(SQLGetInfo(db.hDb, SQL_DBMS_NAME, cast[SqlPointer](buf.addr),
4095.TSqlSmallInt, sz.addr)) 4095.TSqlSmallInt, sz.addr))
except: discard except: discard
return $buf.cstring return $(addr buf)
proc dbQuote*(s: string): string {.noSideEffect.} = proc dbQuote*(s: string): string {.noSideEffect.} =
## DB quotes the string. ## DB quotes the string.
@ -201,9 +201,6 @@ proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string {.
var a = 0 var a = 0
for c in items(string(formatstr)): for c in items(string(formatstr)):
if c == '?': if c == '?':
if args[a] == nil:
add(result, "NULL")
else:
add(result, dbQuote(args[a])) add(result, dbQuote(args[a]))
inc(a) inc(a)
else: else:
@ -303,7 +300,7 @@ iterator fastRows*(db: var DbConn, query: SqlQuery,
buf[0] = '\0' buf[0] = '\0'
db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR, db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr)) cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
rowRes[colId-1] = $buf.cstring rowRes[colId-1] = $(addr buf)
cCnt = tempcCnt cCnt = tempcCnt
yield rowRes yield rowRes
res = SQLFetch(db.stmt) res = SQLFetch(db.stmt)
@ -338,7 +335,7 @@ iterator instantRows*(db: var DbConn, query: SqlQuery,
buf[0] = '\0' buf[0] = '\0'
db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR, db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr)) cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
rowRes[colId-1] = $buf.cstring rowRes[colId-1] = $(addr buf)
cCnt = tempcCnt cCnt = tempcCnt
yield (row: rowRes, len: cCnt.int) yield (row: rowRes, len: cCnt.int)
res = SQLFetch(db.stmt) res = SQLFetch(db.stmt)
@ -380,7 +377,7 @@ proc getRow*(db: var DbConn, query: SqlQuery,
buf[0] = '\0' buf[0] = '\0'
db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR, db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr)) cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
rowRes[colId-1] = $buf.cstring rowRes[colId-1] = $(addr buf)
cCnt = tempcCnt cCnt = tempcCnt
res = SQLFetch(db.stmt) res = SQLFetch(db.stmt)
result = rowRes result = rowRes
@ -415,7 +412,7 @@ proc getAllRows*(db: var DbConn, query: SqlQuery,
buf[0] = '\0' buf[0] = '\0'
db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR, db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr)) cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
rowRes[colId-1] = $buf.cstring rowRes[colId-1] = $(addr buf)
cCnt = tempcCnt cCnt = tempcCnt
rows.add(rowRes) rows.add(rowRes)
res = SQLFetch(db.stmt) res = SQLFetch(db.stmt)

View file

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

View file

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

View file

@ -1147,7 +1147,7 @@ proc processType(typeName: NimNode, obj: NimNode,
`getEnumCall` `getEnumCall`
) )
of nnkSym: of nnkSym:
let name = ($typeName).normalize let name = normalize($typeName.getTypeImpl())
case name case name
of "string": of "string":
result = quote do: result = quote do:
@ -1639,3 +1639,17 @@ when isMainModule:
# bug #6438 # bug #6438
doAssert($ %*[] == "[]") doAssert($ %*[] == "[]")
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" let fromSpace = if usePlus: "+" else: "%20"
for c in s: for c in s:
case c case c
# https://tools.ietf.org/html/rfc3986#section-2.3
of 'a'..'z', 'A'..'Z', '0'..'9', '-', '.', '_', '~': add(result, c) of 'a'..'z', 'A'..'Z', '0'..'9', '-', '.', '_', '~': add(result, c)
of ' ': add(result, fromSpace) of ' ': add(result, fromSpace)
else: else:

View file

@ -1250,7 +1250,7 @@ function main() {
<li> <li>
<a class="reference reference-toplevel" href="#12" id="62">Procs</a> <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
<ul class="simple simple-toc-section"> <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> title="someType(): SomeType"><wbr />some<wbr />Type<span class="attachedType" style="visibility:hidden">SomeType</span></a></li>
</ul> </ul>
@ -1265,7 +1265,8 @@ function main() {
<div class="section" id="7"> <div class="section" id="7">
<h1><a class="toc-backref" href="#7">Types</a></h1> <h1><a class="toc-backref" href="#7">Types</a></h1>
<dl class="item"> <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> <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> <dd>
@ -1276,7 +1277,8 @@ function main() {
<div class="section" id="12"> <div class="section" id="12">
<h1><a class="toc-backref" href="#12">Procs</a></h1> <h1><a class="toc-backref" href="#12">Procs</a></h1>
<dl class="item"> <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> <dd>
constructor. constructor.

View file

@ -1255,7 +1255,7 @@ function main() {
<li> <li>
<a class="reference reference-toplevel" href="#12" id="62">Procs</a> <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
<ul class="simple simple-toc-section"> <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> title="bar[T](a, b: T): T"><wbr />bar<span class="attachedType" style="visibility:hidden"></span></a></li>
</ul> </ul>
@ -1263,7 +1263,7 @@ function main() {
<li> <li>
<a class="reference reference-toplevel" href="#17" id="67">Macros</a> <a class="reference reference-toplevel" href="#17" id="67">Macros</a>
<ul class="simple simple-toc-section"> <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> title="bar(): untyped"><wbr />bar<span class="attachedType" style="visibility:hidden"></span></a></li>
</ul> </ul>
@ -1271,7 +1271,7 @@ function main() {
<li> <li>
<a class="reference reference-toplevel" href="#18" id="68">Templates</a> <a class="reference reference-toplevel" href="#18" id="68">Templates</a>
<ul class="simple simple-toc-section"> <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> title="foo(a, b: SomeType)"><wbr />foo<span class="attachedType" style="visibility:hidden"></span></a></li>
</ul> </ul>
@ -1297,7 +1297,8 @@ function main() {
<div class="section" id="8"> <div class="section" id="8">
<h1><a class="toc-backref" href="#8">Vars</a></h1> <h1><a class="toc-backref" href="#8">Vars</a></h1>
<dl class="item"> <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> <dd>
@ -1307,7 +1308,8 @@ function main() {
<div class="section" id="12"> <div class="section" id="12">
<h1><a class="toc-backref" href="#12">Procs</a></h1> <h1><a class="toc-backref" href="#12">Procs</a></h1>
<dl class="item"> <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> <dd>
@ -1317,7 +1319,8 @@ function main() {
<div class="section" id="17"> <div class="section" id="17">
<h1><a class="toc-backref" href="#17">Macros</a></h1> <h1><a class="toc-backref" href="#17">Macros</a></h1>
<dl class="item"> <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> <dd>
@ -1327,7 +1330,8 @@ function main() {
<div class="section" id="18"> <div class="section" id="18">
<h1><a class="toc-backref" href="#18">Templates</a></h1> <h1><a class="toc-backref" href="#18">Templates</a></h1>
<dl class="item"> <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> <dd>
This does nothing This does nothing

View file

@ -1227,9 +1227,9 @@ function main() {
</ul></dd> </ul></dd>
<dt><a name="bar" href="#bar"><span>bar:</span></a></dt><dd><ul class="simple"> <dt><a name="bar" href="#bar"><span>bar:</span></a></dt><dd><ul class="simple">
<li><a class="reference external" <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" <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> </ul></dd>
<dt><a name="enumValueA" href="#enumValueA"><span>enumValueA:</span></a></dt><dd><ul class="simple"> <dt><a name="enumValueA" href="#enumValueA"><span>enumValueA:</span></a></dt><dd><ul class="simple">
<li><a class="reference external" <li><a class="reference external"
@ -1245,7 +1245,7 @@ function main() {
</ul></dd> </ul></dd>
<dt><a name="foo" href="#foo"><span>foo:</span></a></dt><dd><ul class="simple"> <dt><a name="foo" href="#foo"><span>foo:</span></a></dt><dd><ul class="simple">
<li><a class="reference external" <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> </ul></dd>
<dt><a name="SomeType" href="#SomeType"><span>SomeType:</span></a></dt><dd><ul class="simple"> <dt><a name="SomeType" href="#SomeType"><span>SomeType:</span></a></dt><dd><ul class="simple">
<li><a class="reference external" <li><a class="reference external"
@ -1253,7 +1253,7 @@ function main() {
</ul></dd> </ul></dd>
<dt><a name="someType" href="#someType"><span>someType:</span></a></dt><dd><ul class="simple"> <dt><a name="someType" href="#someType"><span>someType:</span></a></dt><dd><ul class="simple">
<li><a class="reference external" <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> </ul></dd>
</dl> </dl>
<div class="row"> <div class="row">

View file

@ -9,6 +9,7 @@ import os, asyncfile, asyncdispatch
const F = "test_async.txt" const F = "test_async.txt"
removeFile(F) removeFile(F)
defer: removeFile(F)
let f = openAsync(F, fmWrite) let f = openAsync(F, fmWrite)
var futs = newSeq[Future[void]]() var futs = newSeq[Future[void]]()
for i in 1..3: 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: # dummy compile result:
var c = initResults() var c = initResults()
testSpec c, makeTest("tests/system/helpers/readall_echo", options, cat) 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 --------------------------------------- # ------------------------- async tests ---------------------------------------
proc asyncTests(r: var TResults, cat: Category, options: string) = 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) score += ord(LeadingCharMatch)
var onBoundary = (patIndex == high(pattern)) var onBoundary = (patIndex == high(pattern))
if not onBoundary: if not onBoundary and strIndex < high(str):
let let
nextPatternChar = toLowerAscii(pattern[patIndex + 1]) nextPatternChar = toLowerAscii(pattern[patIndex + 1])
nextStrChar = toLowerAscii(str[strIndex + 1]) nextStrChar = toLowerAscii(str[strIndex + 1])

View file

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