diff options
29 files changed, 219 insertions, 114 deletions
diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index ff5494ad8..fc8e760bc 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -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 diff --git a/compiler/dfa.nim b/compiler/dfa.nim index 013242f62..44c89b881 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -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) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 664f45c79..952e63888 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -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 diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 9a624fcce..94790440f 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -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) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 7be0610a2..e1a8390e1 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -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) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index d5c5b7f86..f2cb2dcb3 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -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) diff --git a/config/nimdoc.cfg b/config/nimdoc.cfg index 96e91283a..960c58c9e 100644 --- a/config/nimdoc.cfg +++ b/config/nimdoc.cfg @@ -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> """ diff --git a/doc/backends.rst b/doc/backends.rst index 13ef7bf4d..ef30971c9 100644 --- a/doc/backends.rst +++ b/doc/backends.rst @@ -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. diff --git a/doc/docgen.rst b/doc/docgen.rst index fa23bdc79..65c7bd908 100644 --- a/doc/docgen.rst +++ b/doc/docgen.rst @@ -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 diff --git a/doc/docs.rst b/doc/docs.rst index 4484784ae..cd1a05853 100644 --- a/doc/docs.rst +++ b/doc/docs.rst @@ -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. diff --git a/doc/lib.rst b/doc/lib.rst index bfb7306fb..5ae1a59c7 100644 --- a/doc/lib.rst +++ b/doc/lib.rst @@ -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 diff --git a/doc/manual.rst b/doc/manual.rst index c898c6c55..588da07e2 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -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. diff --git a/doc/nimc.rst b/doc/nimc.rst index 4082b5378..acda484fb 100644 --- a/doc/nimc.rst +++ b/doc/nimc.rst @@ -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 ================== diff --git a/doc/tools.rst b/doc/tools.rst index 6757621fb..c7586d6bd 100644 --- a/doc/tools.rst +++ b/doc/tools.rst @@ -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>`_ diff --git a/lib/impure/db_odbc.nim b/lib/impure/db_odbc.nim index d6343acc7..224bcbb50 100644 --- a/lib/impure/db_odbc.nim +++ b/lib/impure/db_odbc.nim @@ -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) diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 51bb9c757..232da5c93 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -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: diff --git a/lib/pure/concurrency/cpuload.nim b/lib/pure/concurrency/cpuload.nim index 1ec739485..78a95681d 100644 --- a/lib/pure/concurrency/cpuload.nim +++ b/lib/pure/concurrency/cpuload.nim @@ -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() = diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 9279fea77..81d5702c9 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -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") diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index dd8040928..d296017dd 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -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: diff --git a/nimdoc/testproject/expected/subdir/subdir_b/utils.html b/nimdoc/testproject/expected/subdir/subdir_b/utils.html index 285d09d5c..d81be8f48 100644 --- a/nimdoc/testproject/expected/subdir/subdir_b/utils.html +++ b/nimdoc/testproject/expected/subdir/subdir_b/utils.html @@ -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. diff --git a/nimdoc/testproject/expected/testproject.html b/nimdoc/testproject/expected/testproject.html index 064a70011..f1c567627 100644 --- a/nimdoc/testproject/expected/testproject.html +++ b/nimdoc/testproject/expected/testproject.html @@ -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 diff --git a/nimdoc/testproject/expected/theindex.html b/nimdoc/testproject/expected/theindex.html index fc5c0e1c5..106a3be1d 100644 --- a/nimdoc/testproject/expected/theindex.html +++ b/nimdoc/testproject/expected/theindex.html @@ -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"> diff --git a/tests/async/tasyncfilewrite.nim b/tests/async/tasyncfilewrite.nim index 8439778ca..373b93301 100644 --- a/tests/async/tasyncfilewrite.nim +++ b/tests/async/tasyncfilewrite.nim @@ -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: diff --git a/tests/destructor/tprevent_assign.nim b/tests/destructor/tprevent_assign.nim new file mode 100644 index 000000000..108ccc371 --- /dev/null +++ b/tests/destructor/tprevent_assign.nim @@ -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() diff --git a/tests/generics/t8694.nim b/tests/generics/t8694.nim new file mode 100644 index 000000000..da6c6dbed --- /dev/null +++ b/tests/generics/t8694.nim @@ -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) diff --git a/tests/generics/t9130.nim b/tests/generics/t9130.nim new file mode 100644 index 000000000..a993bc6b2 --- /dev/null +++ b/tests/generics/t9130.nim @@ -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) diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index 2c55bd0bd..59ce70315 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -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) = diff --git a/tools/dochack/fuzzysearch.nim b/tools/dochack/fuzzysearch.nim index e6b1ea3cd..69f9fce3c 100644 --- a/tools/dochack/fuzzysearch.nim +++ b/tools/dochack/fuzzysearch.nim @@ -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]) diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index d24eba5dc..3c4ded75e 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -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() |