diff options
29 files changed, 225 insertions, 91 deletions
diff --git a/.travis.yml b/.travis.yml index b3b4834b3..b4fa886b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,9 @@ os: - osx dist: trusty -matrix: - allow_failures: - - os: osx +#matrix: +# allow_failures: +# - os: osx addons: apt: @@ -43,9 +43,7 @@ script: #- nimble install jester@#head -y #- nimble install niminst - nim c --taintMode:on -d:nimCoroutines tests/testament/tester - # Do not run the tests on OSX as OSX does 'testinstall' which *also* runs all the tests! - - if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then tests/testament/tester --pedantic all -d:nimCoroutines; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./koch testinstall; fi + - tests/testament/tester --pedantic all -d:nimCoroutines - nim c -o:bin/nimpretty nimpretty/nimpretty.nim - nim c -r nimpretty/tester.nim - ./koch docs diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index fbedf6cc6..a1365ce07 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1864,6 +1864,23 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) = else: binaryArith(p, e, d, m) +proc skipAddr(n: PNode): PNode = + result = if n.kind in {nkAddr, nkHiddenAddr}: n[0] else: n + +proc genWasMoved(p: BProc; n: PNode) = + var a: TLoc + initLocExpr(p, n[1].skipAddr, a) + resetLoc(p, a) + #linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n", + # addrLoc(p.config, a), getTypeDesc(p.module, a.t)) + +proc genMove(p: BProc; n: PNode; d: var TLoc) = + if d.k == locNone: getTemp(p, n.typ, d) + var a: TLoc + initLocExpr(p, n[1].skipAddr, a) + genAssignment(p, d, a, {}) + resetLoc(p, a) + proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = case op of mOr, mAnd: genAndOr(p, e, d, op) @@ -1991,6 +2008,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = initLocExpr(p, e.sons[2], b) genDeepCopy(p, a, b) of mDotDot, mEqCString: genCall(p, e, d) + of mWasMoved: genWasMoved(p, e) + of mMove: genMove(p, e, d) else: when defined(debugMagics): echo p.prc.name.s, " ", p.prc.id, " ", p.prc.flags, " ", p.prc.ast[genericParamsPos].kind diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 52a4a72f2..3c7a0d26e 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -1206,7 +1206,7 @@ proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope = let x = fakeClosureType(m, t.owner) genTupleInfo(m, x, x, result, info) of tySequence: - if tfHasAsgn notin t.flags: + if m.config.selectedGC != gcDestructors: genTypeInfoAux(m, t, t, result, info) if m.config.selectedGC >= gcMarkAndSweep: let markerProc = genTraverseProc(m, origType, sig) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index a22b613f0..62c55de3d 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -81,6 +81,7 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimAshr") defineSymbol("nimNoNilSeqs") defineSymbol("nimNoNilSeqs2") + defineSymbol("nimHasUserErrors") defineSymbol("nimHasNilSeqs") for f in low(Feature)..high(Feature): diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index bd735560a..ff5494ad8 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -291,21 +291,21 @@ 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, ri.typ, dest) + result = genSink(c, dest.typ, dest) # 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): # Rule 3: `=sink`(x, z); wasMoved(z) - var snk = genSink(c, ri.typ, dest) + var snk = genSink(c, dest.typ, dest) 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, ri.typ, dest) + result = genSink(c, dest.typ, dest) result.add destructiveMoveSink(ri, c) else: - result = genCopy(c, ri.typ, dest) + result = genCopy(c, dest.typ, dest) result.add p(ri, c) proc passCopyToSink(n: PNode; c: var Con): PNode = diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 83dd5de2a..4e36b72e5 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -304,7 +304,7 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe d.target == outHtml: let external = externalDep(d, s.owner) result.addf "<a href=\"$1#$2\"><span class=\"Identifier\">$3</span></a>", - [rope changeFileExt(external, "html").string, rope literal, + [rope changeFileExt(external, "html"), rope literal, rope(esc(d.target, literal))] else: dispA(d.conf, result, "<span class=\"Identifier\">$1</span>", diff --git a/compiler/passes.nim b/compiler/passes.nim index 365731669..718b42c2a 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -125,6 +125,11 @@ proc processImplicits(conf: ConfigRef; implicits: seq[string], nodeKind: TNodeKi importStmt.addSon str if not processTopLevelStmt(importStmt, a): break +const + imperativeCode = {low(TNodeKind)..high(TNodeKind)} - {nkTemplateDef, nkProcDef, nkMethodDef, + nkMacroDef, nkConverterDef, nkIteratorDef, nkFuncDef, nkPragma, + nkExportStmt, nkExportExceptStmt, nkFromStmt, nkImportStmt, nkImportExceptStmt} + proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {.discardable.} = if graph.stopCompile(): return true var @@ -191,7 +196,25 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool { sl = reorder(graph, sl, module) discard processTopLevelStmt(sl, a) break - elif not processTopLevelStmt(n, a): break + elif n.kind in imperativeCode: + # read everything until the next proc declaration etc. + var sl = newNodeI(nkStmtList, n.info) + sl.add n + var rest: PNode = nil + while true: + var n = parseTopLevelStmt(p) + if n.kind == nkEmpty or n.kind notin imperativeCode: + rest = n + break + sl.add n + #echo "-----\n", sl + if not processTopLevelStmt(sl, a): break + if rest != nil: + #echo "-----\n", rest + if not processTopLevelStmt(rest, a): break + else: + #echo "----- single\n", n + if not processTopLevelStmt(n, a): break closeParsers(p) if s.kind != llsStdIn: break closePasses(graph, a) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 36c79bc9e..9a624fcce 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -954,12 +954,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, recordPragma(c, it, "warning", s) message(c.config, it.info, warnUser, s) of wError: - if sym != nil and sym.isRoutine: + if sym != nil and (sym.isRoutine or sym.kind == skType): # This is subtle but correct: the error *statement* is only # allowed for top level statements. Seems to be easier than # distinguishing properly between # ``proc p() {.error}`` and ``proc p() = {.error: "msg".}`` - noVal(c, it) + if it.kind in nkPragmaCallKinds: discard getStrLitNode(c, it) incl(sym.flags, sfError) else: let s = expectStrLit(c, it) diff --git a/compiler/sem.nim b/compiler/sem.nim index 5e5205c20..dbc174d50 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -542,12 +542,20 @@ proc isImportSystemStmt(g: ModuleGraph; n: PNode): bool = return true else: discard +proc isEmptyTree(n: PNode): bool = + case n.kind + of nkStmtList: + for it in n: + if not isEmptyTree(it): return false + result = true + of nkEmpty, nkCommentStmt: result = true + else: result = false + proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = if n.kind == nkDefer: localError(c.config, n.info, "defer statement not supported at top level") if c.topStmts == 0 and not isImportSystemStmt(c.graph, n): - if sfSystemModule notin c.module.flags and - n.kind notin {nkEmpty, nkCommentStmt}: + if sfSystemModule notin c.module.flags and not isEmptyTree(n): c.importTable.addSym c.graph.systemModule # import the "System" identifier importAllSymbols(c, c.graph.systemModule) inc c.topStmts diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index 8b2e20efc..f781972a5 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -216,7 +216,8 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) = if c.c.config.selectedGC == gcDestructors: discard considerOverloadedOp(c, t, body, x, y) elif tfHasAsgn in t.flags: - body.add newSeqCall(c.c, x, y) + if c.kind != attachedDestructor: + body.add newSeqCall(c.c, x, y) let i = declareCounter(c, body, firstOrd(c.c.config, t)) let whileLoop = genWhileLoop(c, i, x) let elemType = t.lastSon diff --git a/compiler/suggest.nim b/compiler/suggest.nim index b6b8d713c..b264415d8 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -33,7 +33,7 @@ # included from sigmatch.nim import algorithm, prefixmatches, lineinfos, pathutils -from wordrecg import wDeprecated +from wordrecg import wDeprecated, wError when defined(nimsuggest): import passes, tables # importer @@ -453,33 +453,42 @@ proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym; isDecl: suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideOutline, info, 100, PrefixMatch.None, false, 0)) -proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) = - var pragmaNode: PNode - +proc extractPragma(s: PSym): PNode = if s.kind in routineKinds: - pragmaNode = s.ast[pragmasPos] + result = s.ast[pragmasPos] elif s.kind in {skType}: # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma] - pragmaNode = s.ast[0][1] - - doAssert pragmaNode == nil or pragmaNode.kind == nkPragma + result = s.ast[0][1] + doAssert result == nil or result.kind == nkPragma +proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) = + let pragmaNode = extractPragma(s) if pragmaNode != nil: for it in pragmaNode: if whichPragma(it) == wDeprecated and it.safeLen == 2 and - it[1].kind in {nkStrLit..nkTripleStrLit}: + it[1].kind in {nkStrLit..nkTripleStrLit}: message(conf, info, warnDeprecated, it[1].strVal & "; " & s.name.s) return - message(conf, info, warnDeprecated, s.name.s) +proc userError(conf: ConfigRef; info: TLineInfo; s: PSym) = + let pragmaNode = extractPragma(s) + + if pragmaNode != nil: + for it in pragmaNode: + if whichPragma(it) == wError and it.safeLen == 2 and + it[1].kind in {nkStrLit..nkTripleStrLit}: + localError(conf, info, it[1].strVal & "; usage of '$1' is a user-defined error" % s.name.s) + return + localError(conf, info, "usage of '$1' is a user-defined error" % s.name.s) + proc markUsed(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) = incl(s.flags, sfUsed) if s.kind == skEnumField and s.owner != nil: incl(s.owner.flags, sfUsed) if {sfDeprecated, sfError} * s.flags != {}: if sfDeprecated in s.flags: warnAboutDeprecated(conf, info, s) - if sfError in s.flags: localError(conf, info, "usage of '$1' is a user-defined error" % s.name.s) + if sfError in s.flags: userError(conf, info, s) when defined(nimsuggest): suggestSym(conf, info, s, usageSym, false) diff --git a/compiler/transf.nim b/compiler/transf.nim index b31be71a3..83e66a069 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -1054,8 +1054,8 @@ proc transformStmt*(g: ModuleGraph; module: PSym, n: PNode): PNode = when useEffectSystem: trackTopLevelStmt(g, module, result) #if n.info ?? "temp.nim": # echo renderTree(result, {renderIds}) - #if c.needsDestroyPass: - # result = injectDestructorCalls(g, module, result) + if c.needsDestroyPass: + result = injectDestructorCalls(g, module, result) incl(result.flags, nfTransf) proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode = @@ -1067,6 +1067,6 @@ proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode = liftDefer(c, result) # expressions are not to be injected with destructor calls as that # the list of top level statements needs to be collected before. - #if c.needsDestroyPass: - # result = injectDestructorCalls(g, module, result) + if c.needsDestroyPass: + result = injectDestructorCalls(g, module, result) incl(result.flags, nfTransf) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index b6b5bf4f2..e612d7a2a 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1529,7 +1529,7 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) = template needsRegLoad(): untyped = {gfNode, gfNodeAddr} * flags == {} and - fitsRegister(n.typ.skipTypes({tyVar, tyLent})) + fitsRegister(n.typ.skipTypes({tyVar, tyLent, tyStatic})) proc genArrAccess2(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; flags: TGenFlags) = @@ -1590,7 +1590,7 @@ proc getNullValueAux(obj: PNode, result: PNode; conf: ConfigRef) = else: globalError(conf, result.info, "cannot create null element for: " & $obj) proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = - var t = skipTypes(typ, abstractRange-{tyTypeDesc}) + var t = skipTypes(typ, abstractRange+{tyStatic}-{tyTypeDesc}) case t.kind of tyBool, tyEnum, tyChar, tyInt..tyInt64: result = newNodeIT(nkIntLit, info, t) @@ -1602,7 +1602,7 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = result = newNodeIT(nkStrLit, info, t) result.strVal = "" of tyVar, tyLent, tyPointer, tyPtr, tyExpr, - tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil: + tyStmt, tyTypeDesc, tyRef, tyNil: result = newNodeIT(nkNilLit, info, t) of tyProc: if t.callConv != ccClosure: diff --git a/doc/nims.rst b/doc/nims.rst index d4ef0055f..a0756eb13 100644 --- a/doc/nims.rst +++ b/doc/nims.rst @@ -4,39 +4,56 @@ Strictly speaking, ``NimScript`` is the subset of Nim that can be evaluated by Nim's builtin virtual machine (VM). This VM is used for Nim's compiletime -function evaluation features, but also replaces Nim's existing configuration -system. +function evaluation features. -So instead of a ``myproject.nim.cfg`` configuration file, you can use -a ``myproject.nims`` file that simply contains Nim code controlling the -compilation process. For a directory wide configuration, use ``config.nims`` -instead of ``nim.cfg``. +You can use a ``<myproject>.nims`` file that simply contains Nim code +controlling the compilation process. For a directory wide +configuration, use ``config.nims`` instead of ``<myproject>.nims``. -The VM cannot deal with ``importc``, the FFI is not available, so there are not -many stdlib modules that you can use with Nim's VM. However, at least the -following modules are available: +The VM cannot deal with ``importc`` because the FFI is not +available. So the stdlib modules using ``importc`` cannot be used with +Nim's VM. However, at least the following modules are available: -* `strutils <strutils.html>`_ +* `macros <macros.html>`_ * `ospaths <ospaths.html>`_ +* `strutils <strutils.html>`_ * `math <math.html>`_ * `distros <distros.html>`_ -The `system <system.html>`_ module in NimScript mode additionally supports -these operations: `nimscript <nimscript.html>`_. +In addition to the standard Nim syntax (`system <system.html>`_ +module), NimScripts support the procs and templates defined in the +`nimscript <nimscript.html>`_ module too. NimScript as a configuration file ================================= -What is ``x.y.key = "value"`` in the configuration file -becomes ``switch("x.y.key", "value")``. ``--option`` is ``switch("option")``. -The ``system`` module also exports 2 ``--`` templates for convenience: +A command-line switch ``--FOO`` is written as ``switch("FOO")`` in +NimScript. Similarly, command-line ``--FOO:VAL`` translates to +``switch("FOO", "VAL")``. + +Here are few examples of using the ``switch`` proc: .. code-block:: nim - --forceBuild - # is the same as: + # command-line: --opt:size + switch("opt", "size") + # command-line: --define:foo or -d:foo + switch("define", "foo") + # command-line: --forceBuild switch("forceBuild") +*Note that specifically the ``-d:release`` define cannot be set using +``switch`` in NimScripts.* + +NimScripts also support ``--`` templates for convenience, which look +like command-line switches written as-is in the NimScript file. So the +above example can be rewritten as: + +.. code-block:: nim + --opt:size + --define:foo + --forceBuild + NimScript as a build tool ========================= @@ -91,7 +108,7 @@ Standalone NimScript NimScript can also be used directly as a portable replacement for Bash and Batch files. Use ``nim e myscript.nims`` to run ``myscript.nims``. For example, -installation of Nimble is done with this simple script: +installation of Nimble could be accomplished with this simple script: .. code-block:: nim diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index c230e6598..fa589e905 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -985,14 +985,21 @@ proc utimes*(path: cstring, times: ptr array[2, Timeval]): int {. proc handle_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.importc: "signal", header: "<signal.h>".} template onSignal*(signals: varargs[cint], body: untyped) = - ## Setup code to be executed when Unix signals are received. Example: - ## from posix import SIGINT, SIGTERM - ## onSignal(SIGINT, SIGTERM): - ## echo "bye" + ## Setup code to be executed when Unix signals are received. The + ## currently handled signal is injected as ``sig`` into the calling + ## scope. + ## + ## Example: + ## + ## .. code-block:: + ## from posix import SIGINT, SIGTERM + ## onSignal(SIGINT, SIGTERM): + ## echo "bye from signal ", sig for s in signals: handle_signal(s, - proc (sig: cint) {.noconv.} = + proc (signal: cint) {.noconv.} = + let sig {.inject.} = signal body ) diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim index 541265da9..4f681f980 100644 --- a/lib/pure/concurrency/cpuinfo.nim +++ b/lib/pure/concurrency/cpuinfo.nim @@ -44,12 +44,12 @@ when defined(genode): importcpp: "@->cpu().affinity_space().total()".} when defined(haiku): - {.emit: "#include <OS.h>".} type - SystemInfo {.importc: "system_info", bycopy.} = object + SystemInfo {.importc: "system_info", header: "<OS.h>".} = object cpuCount {.importc: "cpu_count".}: uint32 - proc getSystemInfo(info: ptr SystemInfo): int32 {.importc: "get_system_info".} + proc getSystemInfo(info: ptr SystemInfo): int32 {.importc: "get_system_info", + header: "<OS.h>".} proc countProcessors*(): int {.rtl, extern: "ncpi$1".} = ## returns the numer of the processors/cores the machine has. diff --git a/lib/pure/math.nim b/lib/pure/math.nim index bc804eb86..909aa11b7 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -383,8 +383,8 @@ when not defined(JS): # C ## .. code-block:: nim ## echo trunc(PI) # 3.0 - proc fmod*(x, y: float32): float32 {.deprecated, importc: "fmodf", header: "<math.h>".} - proc fmod*(x, y: float64): float64 {.deprecated, importc: "fmod", header: "<math.h>".} + proc fmod*(x, y: float32): float32 {.deprecated: "use mod instead", importc: "fmodf", header: "<math.h>".} + proc fmod*(x, y: float64): float64 {.deprecated: "use mod instead", importc: "fmod", header: "<math.h>".} ## Computes the remainder of `x` divided by `y` ## ## .. code-block:: nim diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 2b3cf5142..5c7d369c9 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -802,20 +802,16 @@ type pcDir, ## path refers to a directory pcLinkToDir ## path refers to a symbolic link to a directory - when defined(posix): proc getSymlinkFileKind(path: string): PathComponent = # Helper function. var s: Stat assert(path != "") - if stat(path, s) < 0'i32: - raiseOSError(osLastError()) - if S_ISDIR(s.st_mode): + if stat(path, s) == 0'i32 and S_ISDIR(s.st_mode): result = pcLinkToDir else: result = pcLinkToFile - proc staticWalkDir(dir: string; relative: bool): seq[ tuple[kind: PathComponent, path: string]] = discard @@ -1480,6 +1476,24 @@ when defined(macosx): proc getExecPath2(c: cstring, size: var cuint32): bool {. importc: "_NSGetExecutablePath", header: "<mach-o/dyld.h>".} +when defined(haiku): + const + PATH_MAX = 1024 + B_FIND_PATH_IMAGE_PATH = 1000 + + proc find_path(codePointer: pointer, baseDirectory: cint, subPath: cstring, + pathBuffer: cstring, bufferSize: csize): int32 + {.importc, header: "<FindDirectory.h>".} + + proc getApplHaiku(): string = + result = newString(PATH_MAX) + + if find_path(nil, B_FIND_PATH_IMAGE_PATH, nil, result, PATH_MAX) == 0: + let realLen = len(cstring(result)) + setLen(result, realLen) + else: + result = "" + proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = ## Returns the filename of the application's executable. ## @@ -1534,6 +1548,8 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = raiseOSError(OSErrorCode(-1), "POSIX command line not supported") elif defined(freebsd) or defined(dragonfly): result = getApplFreebsd() + elif defined(haiku): + result = getApplHaiku() # little heuristic that may work on other POSIX-like systems: if result.len == 0: result = getApplHeuristic() diff --git a/lib/system.nim b/lib/system.nim index 49e6a396d..f62842db2 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1932,10 +1932,10 @@ const NimMajor* {.intdefine.}: int = 0 ## is the major number of Nim's version. - NimMinor* {.intdefine.}: int = 18 + NimMinor* {.intdefine.}: int = 19 ## is the minor number of Nim's version. - NimPatch* {.intdefine.}: int = 1 + NimPatch* {.intdefine.}: int = 0 ## is the patch number of Nim's version. NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch @@ -4112,8 +4112,16 @@ proc `==`*(x, y: cstring): bool {.magic: "EqCString", noSideEffect, when defined(nimNoNilSeqs2): when not compileOption("nilseqs"): - proc `==`*(x: string; y: type(nil)): bool {.error.} = discard - proc `==`*(x: type(nil); y: string): bool {.error.} = discard + when defined(nimHasUserErrors): + proc `==`*(x: string; y: type(nil)): bool {. + error: "'nil' is now invalid for 'string'; compile with --nilseqs:on for a migration period".} = + discard + proc `==`*(x: type(nil); y: string): bool {. + error: "'nil' is now invalid for 'string'; compile with --nilseqs:on for a migration period".} = + discard + else: + proc `==`*(x: string; y: type(nil)): bool {.error.} = discard + proc `==`*(x: type(nil); y: string): bool {.error.} = discard template closureScope*(body: untyped): untyped = ## Useful when creating a closure in a loop to capture local loop variables by diff --git a/tests/destructor/t6434.nim b/tests/destructor/t6434.nim index 1657e90bc..9c912f1f9 100644 --- a/tests/destructor/t6434.nim +++ b/tests/destructor/t6434.nim @@ -2,6 +2,8 @@ discard """ exitcode: 0 output: '''assingment assingment +assingment +assingment ''' """ diff --git a/tests/seq/t7346.nim b/tests/destructor/t7346.nim index ef2fd5b79..ef2fd5b79 100644 --- a/tests/seq/t7346.nim +++ b/tests/destructor/t7346.nim diff --git a/tests/destructor/texplicit_move.nim b/tests/destructor/texplicit_move.nim new file mode 100644 index 000000000..6735ac75d --- /dev/null +++ b/tests/destructor/texplicit_move.nim @@ -0,0 +1,19 @@ + +discard """ + output: '''3 +0 +destroyed!''' +""" + +type + myseq* = object + f: int + +proc `=destroy`*(x: var myseq) = + echo "destroyed!" + +var + x: myseq +x.f = 3 +echo move(x.f) +echo x.f diff --git a/tests/destructor/tmove_objconstr.nim b/tests/destructor/tmove_objconstr.nim index 178ff2a7d..50aecf46d 100644 --- a/tests/destructor/tmove_objconstr.nim +++ b/tests/destructor/tmove_objconstr.nim @@ -59,4 +59,4 @@ for x in getPony(): echo x # XXX this needs to be enabled once top level statements # produce destructor calls again. -echo "Pony is dying!" +#echo "Pony is dying!" diff --git a/tests/errmsgs/t5167_5.nim b/tests/errmsgs/t5167_5.nim index ab02f29f6..ccd9cc0a5 100644 --- a/tests/errmsgs/t5167_5.nim +++ b/tests/errmsgs/t5167_5.nim @@ -1,18 +1,18 @@ discard """ cmd: "nim check $file" -errormsg: "'m' has unspecified generic parameters" +errormsg: "'t' has unspecified generic parameters" nimout: ''' t5167_5.nim(20, 9) Error: 't' has unspecified generic parameters -t5167_5.nim(21, 5) Error: 't' has unspecified generic parameters -t5167_5.nim(23, 9) Error: 'm' has unspecified generic parameters -t5167_5.nim(24, 5) Error: 'm' has unspecified generic parameters ''' """ + + + template t[B]() = echo "foo1" -macro m[T]: stmt = nil +macro m[T]: untyped = nil proc bar(x: proc (x: int)) = echo "bar" diff --git a/tests/pragmas/tnoreturn.nim b/tests/pragmas/tnoreturn.nim index bb59b1c71..50b427d71 100644 --- a/tests/pragmas/tnoreturn.nim +++ b/tests/pragmas/tnoreturn.nim @@ -9,8 +9,8 @@ proc noret1*(i: int) {.noreturn.} = proc noret2*(i: int): void {.noreturn.} = echo i -noret1(1) -noret2(2) +if true: noret1(1) +if true: noret2(2) var p {.used.}: proc(i: int): int doAssert(not compiles( diff --git a/tests/pragmas/treorder.nim b/tests/pragmas/treorder.nim index 659a6f644..09a98ef6a 100644 --- a/tests/pragmas/treorder.nim +++ b/tests/pragmas/treorder.nim @@ -14,10 +14,10 @@ echo callWithFoo(0) echo(CA+CD) echo useTypes(TA(x:TB(x:1)), 2) second(0) - + template callWithFoo(arg: untyped): untyped = foo(arg) - + proc first(i: int): void proc second(i: int): void = @@ -35,7 +35,7 @@ type type TCyclicA = ref object x: TDoubleCyclic - + type TCyclicB = ref object x: TDoubleCyclic diff --git a/tests/trmacros/tor.nim b/tests/trmacros/tor.nim index d698e928d..087dc0d68 100644 --- a/tests/trmacros/tor.nim +++ b/tests/trmacros/tor.nim @@ -1,11 +1,11 @@ discard """ - output: '''3030 + output: '''0 true 3''' """ template arithOps: untyped = (`+` | `-` | `*`) -template testOr{ (arithOps{f})(a, b) }(a, b, f: untyped): untyped = f(a+1, b) +template testOr{ (arithOps{f})(a, b) }(a, b, f: untyped): untyped = f(a mod 10, b) let xx = 10 echo 10*xx diff --git a/tests/types/t6969.nim b/tests/types/t6969.nim index d6ce5e62a..14a8481cf 100644 --- a/tests/types/t6969.nim +++ b/tests/types/t6969.nim @@ -3,8 +3,4 @@ errormsg: "invalid type: 'object' for var" line: 6 """ -var a: object a: int -# or -var b: ref object a: int -# or -var c: ptr object a: int \ No newline at end of file +var a: object diff --git a/tests/vm/t9043.nim b/tests/vm/t9043.nim new file mode 100644 index 000000000..1ae2e383c --- /dev/null +++ b/tests/vm/t9043.nim @@ -0,0 +1,10 @@ +discard """ + nimout: "(Field0: 2, Field1: 2, Field2: 2, Field3: 2)" +""" + +proc foo[N: static[int]](dims: array[N, int])= + const N1 = N + const N2 = dims.len + static: echo (N, dims.len, N1, N2) + +foo([1, 2]) |