From 67380f71d606f5e4c31cdf0a591ad5e882e93fe4 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 21 Feb 2018 11:42:58 +0100 Subject: [PATCH 01/15] symbol files: delay the emission of forwarded procs --- compiler/rod.nim | 2 ++ compiler/rodimpl.nim | 26 +++++++++++++++++--------- compiler/sem.nim | 1 + 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/compiler/rod.nim b/compiler/rod.nim index bb9beff54c0fe..bc2f3931e07a3 100644 --- a/compiler/rod.nim +++ b/compiler/rod.nim @@ -20,6 +20,8 @@ when not defined(nimSymbolfiles): template addModuleDep*(module, fileIdx: int32; isIncludeFile: bool) = discard + template storeRemaining*(module: PSym) = discard + else: include rodimpl diff --git a/compiler/rodimpl.nim b/compiler/rodimpl.nim index 767929aa54129..ceed166b43a9e 100644 --- a/compiler/rodimpl.nim +++ b/compiler/rodimpl.nim @@ -15,6 +15,8 @@ import strutils, os, intsets, tables, ropes, db_sqlite, msgs, options, types, ## Todo: ## - Implement the 'import' replay logic so that the codegen runs over ## dependent modules. +## - Make conditional symbols and the configuration part of a module's +## dependencies. ## - Test multi methods. ## - Implement the limited VM support based on sets. ## - Depencency computation should use signature hashes in order to @@ -49,7 +51,7 @@ proc getModuleId*(fileIdx: int32; fullpath: string): int = if gSymbolFiles != v2Sf: return getID() let module = db.getRow( sql"select id, fullHash from modules where fullpath = ?", fullpath) - let currentFullhash = $secureHashFile(fullpath) + let currentFullhash = hashFileCached(fileIdx, fullpath) if module[0].len == 0: result = int db.insertID(sql"insert into modules(fullpath, interfHash, fullHash) values (?, ?, ?)", fullpath, "", currentFullhash) @@ -75,12 +77,13 @@ type sstack: seq[PSym] # a stack of symbols to process tstack: seq[PType] # a stack of types to process tmarks, smarks: IntSet + forwardedSyms: seq[PSym] PRodWriter = var TRodWriter proc initRodWriter(module: PSym): TRodWriter = result = TRodWriter(module: module, sstack: @[], tstack: @[], - tmarks: initIntSet(), smarks: initIntSet()) + tmarks: initIntSet(), smarks: initIntSet(), forwardedSyms: @[]) when false: proc getDefines(): string = @@ -89,13 +92,6 @@ when false: if result.len != 0: add(result, " ") add(result, d) - proc addInclDep(w: PRodWriter, dep: string; info: TLineInfo) = - let resolved = dep.findModule(info.toFullPath) - encodeVInt(fileIdx(w, resolved), w.inclDeps) - add(w.inclDeps, " ") - encodeStr($secureHashFile(resolved), w.inclDeps) - add(w.inclDeps, rodNL) - const rodNL = "\L" @@ -381,6 +377,9 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) = encodeNode(w, s.info, s.ast, result) proc storeSym(w: PRodWriter; s: PSym) = + if sfForward in s.flags and s.kind != skModule: + w.forwardedSyms.add s + return var buf = newStringOfCap(160) encodeSym(w, s, buf) # XXX only store the name for exported symbols in order to speed up lookup @@ -421,6 +420,14 @@ proc storeNode*(module: PSym; n: PNode) = break inc i +proc storeRemaining*(module: PSym) = + if gSymbolFiles != v2Sf: return + w.module = module + for s in w.forwardedSyms: + assert sfForward notin s.flags + storeSym(w, s) + w.forwardedSyms.setLen 0 + # ---------------- decoder ----------------------------------- type TRodReader = object @@ -781,6 +788,7 @@ proc loadSymFromBlob(r; b; info: TLineInfo): PSym = result.ast = decodeNode(r, b, result.info) if sfCompilerProc in result.flags: registerCompilerProc(result) + #echo "loading ", result.name.s proc loadSym(r; id: int; info: TLineInfo): PSym = result = r.syms.getOrDefault(id) diff --git a/compiler/sem.nim b/compiler/sem.nim index 12e77affca712..937f1637a6a56 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -619,6 +619,7 @@ proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode = replayMethodDefs(graph, c.rd) popOwner(c) popProcCon(c) + storeRemaining(c.module) if c.runnableExamples != nil: testExamples(c) const semPass* = makePass(myOpen, myOpenCached, myProcess, myClose, From d6229f20ffce969a48b100d45e4b3b165af2ce72 Mon Sep 17 00:00:00 2001 From: Ico Doornekamp Date: Fri, 23 Feb 2018 19:16:11 +0100 Subject: [PATCH 02/15] Allow float argument to sleepAsync() to allow sub-millisecond resolution --- lib/pure/asyncdispatch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index a52c667fc290b..dfc7201b8c7ad 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -1513,7 +1513,7 @@ proc poll*(timeout = 500) = # Common procedures between current and upcoming asyncdispatch include includes.asynccommon -proc sleepAsync*(ms: int): Future[void] = +proc sleepAsync*(ms: int | float): Future[void] = ## Suspends the execution of the current async procedure for the next ## ``ms`` milliseconds. var retFuture = newFuture[void]("sleepAsync") From ac6d9a307909d664fd335fdd13ebbcf16779a65f Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 26 Feb 2018 17:39:19 +0100 Subject: [PATCH 03/15] symbol files: baby steps to a working solution --- compiler/rodimpl.nim | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/rodimpl.nim b/compiler/rodimpl.nim index ceed166b43a9e..aff4f6909e9a2 100644 --- a/compiler/rodimpl.nim +++ b/compiler/rodimpl.nim @@ -400,8 +400,9 @@ proc storeNode*(module: PSym; n: PNode) = w.module = module var buf = newStringOfCap(160) encodeNode(w, module.info, n, buf) - db.exec(sql"insert into toplevelstmts(module, data) values (?, ?)", - abs(module.id), buf) + db.exec(sql"insert into toplevelstmts(module, position, data) values (?, ?, ?)", + abs(module.id), module.offset, buf) + inc module.offset var i = 0 while true: if i > 10_000: @@ -812,14 +813,14 @@ proc loadModuleSymTab(r; module: PSym) = if sfSystemModule in module.flags: magicsys.systemModule = module -proc loadNode*(module: PSym; index: var int): PNode = +proc loadNode*(module: PSym; index: int): PNode = assert gSymbolFiles == v2Sf if index == 0: loadModuleSymTab(gr, module) - index = parseInt db.getValue( - sql"select min(id) from toplevelstmts where module = ?", abs module.id) + #index = parseInt db.getValue( + # sql"select min(id) from toplevelstmts where module = ?", abs module.id) var b = BlobReader(pos: 0) - b.s = db.getValue(sql"select data from toplevelstmts where id = ? and module = ?", + b.s = db.getValue(sql"select data from toplevelstmts where position = ? and module = ?", index, abs module.id) if b.s.len == 0: db.exec(sql"insert into controlblock(idgen) values (?)", gFrontEndId) @@ -908,12 +909,14 @@ proc createDb() = db.exec(sql""" create table if not exists toplevelstmts( id integer primary key, + position integer not null, module integer not null, data blob not null, foreign key (module) references module(id) ); """) db.exec sql"create index TopLevelStmtByModuleIdx on toplevelstmts(module);" + db.exec sql"create index TopLevelStmtByPositionIdx on toplevelstmts(position);" db.exec(sql""" create table if not exists statics( From 6d4107b7835ef63a090ae920bfb53afad0abe2eb Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 27 Feb 2018 01:46:52 +0100 Subject: [PATCH 04/15] make the allocator take a special path for allocations bigger than 2GB; fixes #7120 --- lib/system/alloc.nim | 28 +++++++++++++++++++++++-- tests/fragmentation/tfragment_alloc.nim | 4 ++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 33e7b3898b85c..4291013a267b2 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -29,6 +29,8 @@ const FliOffset = 6 RealFli = MaxFli - FliOffset + HugeChunkSize = int high(int32) - 1 # 2 GB, depends on TLSF's impl + type PTrunk = ptr Trunk Trunk = object @@ -593,6 +595,26 @@ proc getBigChunk(a: var MemRegion, size: int): PBigChunk = incl(a, a.chunkStarts, pageIndex(result)) dec(a.freeMem, size) +proc getHugeChunk(a: var MemRegion; size: int): PBigChunk = + result = cast[PBigChunk](osAllocPages(size)) + incCurrMem(a, size) + # XXX add this to the heap links. But also remove it from it later. + when false: a.addHeapLink(result, size) + sysAssert((cast[ByteAddress](result) and PageMask) == 0, "getHugeChunk") + result.next = nil + result.prev = nil + result.size = size + # set 'used' to to true: + result.prevSize = 1 + incl(a, a.chunkStarts, pageIndex(result)) + +proc freeHugeChunk(a: var MemRegion; c: PBigChunk) = + let size = c.size + sysAssert(size >= HugeChunkSize, "freeHugeChunk: invalid size") + excl(a.chunkStarts, pageIndex(c)) + decCurrMem(a, size) + osDeallocPages(c, size) + proc getSmallChunk(a: var MemRegion): PSmallChunk = var res = getBigChunk(a, PageSize) sysAssert res.prev == nil, "getSmallChunk 1" @@ -759,7 +781,8 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer = else: size = requestedSize + bigChunkOverhead() # roundup(requestedSize+bigChunkOverhead(), PageSize) # allocate a large block - var c = getBigChunk(a, size) + var c = if size >= HugeChunkSize: getHugeChunk(a, size) + else: getBigChunk(a, size) sysAssert c.prev == nil, "rawAlloc 10" sysAssert c.next == nil, "rawAlloc 11" result = addr(c.data) @@ -823,7 +846,8 @@ proc rawDealloc(a: var MemRegion, p: pointer) = sysAssert a.occ >= 0, "rawDealloc: negative occupied memory (case B)" a.deleted = getBottom(a) del(a, a.root, cast[int](addr(c.data))) - freeBigChunk(a, c) + if c.size >= HugeChunkSize: freeHugeChunk(a, c) + else: freeBigChunk(a, c) sysAssert(allocInv(a), "rawDealloc: end") when logAlloc: cprintf("dealloc(pointer_%p)\n", p) diff --git a/tests/fragmentation/tfragment_alloc.nim b/tests/fragmentation/tfragment_alloc.nim index 031588d271297..5a44b7434d3b8 100644 --- a/tests/fragmentation/tfragment_alloc.nim +++ b/tests/fragmentation/tfragment_alloc.nim @@ -15,6 +15,10 @@ proc main = quit "could not serve request!" dealloc p # c_fprintf(stdout, "iteration: %ld size: %ld\n", i, size) + when defined(cpu64): + # bug #7120 + var x = alloc(((1 shl 29) - 4) * 8) + dealloc x main() From d81568fcd56b24db02de4e3d8c21913ce239438d Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 27 Feb 2018 02:18:18 +0100 Subject: [PATCH 05/15] make concept tests green again --- compiler/semcall.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 6fef11c48e772..ba38ed215b6a5 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -189,7 +189,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): if cond: candidates.add typeToString(got) if wanted != nil and got != nil: effectProblem(wanted, got, candidates) - candidates.add "\n" + if cond: candidates.add "\n" elif err.unmatchedVarParam != 0 and err.unmatchedVarParam < n.len: add(candidates, "for a 'var' type a variable needs to be passed, but '" & renderNotLValue(n[err.unmatchedVarParam]) & From 0a8684db4cf3aa5c6fe8bd1b3abad83a24ad33bf Mon Sep 17 00:00:00 2001 From: cooldome Date: Tue, 27 Feb 2018 02:03:49 +0000 Subject: [PATCH 06/15] User pragmas hide effect specs bug fix. Fixes #7216 (#7217) --- compiler/pragmas.nim | 32 +++++++++++++++++--------------- tests/pragmas/tuserpragma2.nim | 11 +++++++++++ 2 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 tests/pragmas/tuserpragma2.nim diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 4ed1cea24e447..1b80786280f9f 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -549,15 +549,13 @@ proc pragmaLine(c: PContext, n: PNode) = n.info = getInfoContext(-1) proc processPragma(c: PContext, n: PNode, i: int) = - var it = n.sons[i] + let it = n[i] if it.kind notin nkPragmaCallKinds and it.len == 2: invalidPragma(n) - elif it.sons[0].kind != nkIdent: invalidPragma(n) - elif it.sons[1].kind != nkIdent: invalidPragma(n) + elif it[0].kind != nkIdent: invalidPragma(n) + elif it[1].kind != nkIdent: invalidPragma(n) - var userPragma = newSym(skTemplate, it.sons[1].ident, nil, it.info) - var body = newNodeI(nkPragma, n.info) - for j in i+1 .. sonsLen(n)-1: addSon(body, n.sons[j]) - userPragma.ast = body + var userPragma = newSym(skTemplate, it[1].ident, nil, it.info) + userPragma.ast = newNode(nkPragma, n.info, n.sons[i+1..^1]) strTableAdd(c.userPragmas, userPragma) proc pragmaRaisesOrTags(c: PContext, n: PNode) = @@ -678,7 +676,7 @@ proc semCustomPragma(c: PContext, n: PNode): PNode = elif n.kind == nkExprColonExpr: result.kind = n.kind # pragma(arg) -> pragma: arg -proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, +proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, validPragmas: TSpecialWords): bool = var it = n.sons[i] var key = if it.kind in nkPragmaCallKinds and it.len > 1: it.sons[0] else: it @@ -691,13 +689,14 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, let ident = considerQuotedIdent(key) var userPragma = strTableGet(c.userPragmas, ident) if userPragma != nil: + # number of pragmas increase/decrease with user pragma expansion inc c.instCounter if c.instCounter > 100: globalError(it.info, errRecursiveDependencyX, userPragma.name.s) + pragma(c, sym, userPragma.ast, validPragmas) - # ensure the pragma is also remember for generic instantiations in other - # modules: - n.sons[i] = userPragma.ast + n.sons[i..i] = userPragma.ast.sons # expand user pragma with its content + i.inc(userPragma.ast.len - 1) # inc by -1 is ok, user pragmas was empty dec c.instCounter else: var k = whichKeyword(ident) @@ -1032,9 +1031,11 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode, let o = it.otherPragmas if not o.isNil: pushInfoContext(n.info) - for i in countup(0, sonsLen(o) - 1): + var i = 0 + while i < o.len(): if singlePragma(c, sym, o, i, validPragmas): internalError(n.info, "implicitPragmas") + inc i popInfoContext() if lfExportLib in sym.loc.flags and sfExportc notin sym.flags: @@ -1059,9 +1060,10 @@ proc hasPragma*(n: PNode, pragma: TSpecialWord): bool = proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = if n == nil: return - for i in countup(0, sonsLen(n) - 1): - if n.sons[i].kind == nkPragma: pragmaRec(c, sym, n.sons[i], validPragmas) - elif singlePragma(c, sym, n, i, validPragmas): break + var i = 0 + while i < n.len(): + if singlePragma(c, sym, n, i, validPragmas): break + inc i proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = if n == nil: return diff --git a/tests/pragmas/tuserpragma2.nim b/tests/pragmas/tuserpragma2.nim new file mode 100644 index 0000000000000..bf8844e66dc73 --- /dev/null +++ b/tests/pragmas/tuserpragma2.nim @@ -0,0 +1,11 @@ +discard """ + file: "tuserpragma2.nim" + line: 11 + errormsg: "can raise an unlisted exception: ref Exception" +""" + +# bug #7216 +{.pragma: my_pragma, raises: [].} + +proc test1 {.my_pragma.} = + raise newException(Exception, "msg") From 9c7374abcd2c1c79daccfef58c74964155985bbc Mon Sep 17 00:00:00 2001 From: Alexander Ivanov Date: Tue, 27 Feb 2018 16:23:19 +0200 Subject: [PATCH 07/15] Fix return (#7225) --- lib/js/asyncjs.nim | 14 ++++++++------ tests/js/tasync.nim | 2 ++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/js/asyncjs.nim b/lib/js/asyncjs.nim index 3c488dcfe1109..62444e49aff6c 100644 --- a/lib/js/asyncjs.nim +++ b/lib/js/asyncjs.nim @@ -71,14 +71,17 @@ type PromiseJs* {.importcpp: "Promise".} = ref object ## A JavaScript Promise + proc replaceReturn(node: var NimNode) = var z = 0 for s in node: var son = node[z] + let jsResolve = ident("jsResolve") if son.kind == nnkReturnStmt: - node[z] = nnkReturnStmt.newTree(nnkCall.newTree(ident("jsResolve"), son[0])) + let value = if son[0].kind != nnkEmpty: nnkCall.newTree(jsResolve, son[0]) else: jsResolve + node[z] = nnkReturnStmt.newTree(value) elif son.kind == nnkAsgn and son[0].kind == nnkIdent and $son[0] == "result": - node[z] = nnkAsgn.newTree(son[0], nnkCall.newTree(ident("jsResolve"), son[1])) + node[z] = nnkAsgn.newTree(son[0], nnkCall.newTree(jsResolve, son[1])) else: replaceReturn(son) inc z @@ -92,8 +95,7 @@ proc generateJsasync(arg: NimNode): NimNode = assert arg.kind == nnkProcDef result = arg var isVoid = false - var jsResolveNode = ident("jsResolve") - + let jsResolve = ident("jsResolve") if arg.params[0].kind == nnkEmpty: result.params[0] = nnkBracketExpr.newTree(ident("Future"), ident("void")) isVoid = true @@ -112,7 +114,7 @@ proc generateJsasync(arg: NimNode): NimNode = var resolve: NimNode if isVoid: resolve = quote: - var `jsResolveNode` {.importcpp: "undefined".}: Future[void] + var `jsResolve` {.importcpp: "undefined".}: Future[void] else: resolve = quote: proc jsResolve[T](a: T): Future[T] {.importcpp: "#".} @@ -124,7 +126,7 @@ proc generateJsasync(arg: NimNode): NimNode = if len(code) > 0 and isVoid: var voidFix = quote: - return `jsResolveNode` + return `jsResolve` result.body.add(voidFix) result.pragma = quote: diff --git a/tests/js/tasync.nim b/tests/js/tasync.nim index 76db38b274919..31823765195fb 100644 --- a/tests/js/tasync.nim +++ b/tests/js/tasync.nim @@ -17,6 +17,8 @@ proc e: int {.discardable.} = proc x(e: int): Future[void] {.async.} = var s = await y(e) + if e > 2: + return echo s e() From c9f184401cb0a7289119c1785c3af032f9998ff8 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 27 Feb 2018 17:42:38 +0100 Subject: [PATCH 08/15] merged #6512 manually; fixes #6431 --- lib/system.nim | 14 ++++++++++++++ tests/exception/tunhandledexc.nim | 1 + 2 files changed, 15 insertions(+) diff --git a/lib/system.nim b/lib/system.nim index 2b2ce70087cf0..2f95b45f01fea 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -4117,3 +4117,17 @@ template doAssertRaises*(exception, code: untyped): typed = raiseAssert(astToStr(exception) & " wasn't raised, another error was raised instead by:\n"& astToStr(code)) + +when defined(cpp) and appType != "lib" and not defined(js) and + not defined(nimscript) and hostOS != "standalone": + proc setTerminate(handler: proc() {.noconv.}) + {.importc: "std::set_terminate", header: "".} + setTerminate proc() {.noconv.} = + # Remove ourself as a handler, reinstalling the default handler. + setTerminate(nil) + + let ex = getCurrentException() + let trace = ex.getStackTrace() + stderr.write trace & "Error: unhandled exception: " & ex.msg & + " [" & $ex.name & "]\n" + quit 1 diff --git a/tests/exception/tunhandledexc.nim b/tests/exception/tunhandledexc.nim index c318aec8177f9..b519fa3f65712 100644 --- a/tests/exception/tunhandledexc.nim +++ b/tests/exception/tunhandledexc.nim @@ -2,6 +2,7 @@ discard """ file: "tunhandledexc.nim" outputsub: "Error: unhandled exception: bla [ESomeOtherErr]" exitcode: "1" + targets: "c cpp" """ type ESomething = object of Exception From 7740b12f21f4a6376fc047d66418515a8aa8ccf8 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 27 Feb 2018 17:47:19 +0100 Subject: [PATCH 09/15] revert commit 6cf8a72d498f5cb8a532c2ff3259bc7aecf474ef; Windows fixes getch bug --- lib/pure/terminal.nim | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 6ed04c0d8cc93..87e4ab591d564 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -727,10 +727,7 @@ proc getch*(): char = doAssert(readConsoleInput(fd, addr(keyEvent), 1, addr(numRead)) != 0) if numRead == 0 or keyEvent.eventType != 1 or keyEvent.bKeyDown == 0: continue - if keyEvent.uChar == 0: - return char(keyEvent.wVirtualKeyCode) - else: - return char(keyEvent.uChar) + return char(keyEvent.uChar) else: let fd = getFileHandle(stdin) var oldMode: Termios From a897371797154844f96906e72fa013b8205d0393 Mon Sep 17 00:00:00 2001 From: Vindaar Date: Tue, 27 Feb 2018 17:49:35 +0100 Subject: [PATCH 10/15] move `readPasswordFromStdin` from rdstdin to terminal (#7266) --- changelog.md | 5 ++++- lib/impure/rdstdin.nim | 44 ------------------------------------- lib/pure/terminal.nim | 50 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 45 deletions(-) diff --git a/changelog.md b/changelog.md index cc57a91881ee9..e8a0f893ac7b6 100644 --- a/changelog.md +++ b/changelog.md @@ -262,4 +262,7 @@ bar() import std / [strutils, os, osproc] import someNimblePackage / [strutils, os] -``` \ No newline at end of file +``` + +- The ``readPasswordFromStdin`` proc has been moved from the ``rdstdin`` + to the ``terminal`` module, thus it does not depend on linenoise anymore. diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index b06e8de6cbb40..5aa4cfcc38f9d 100644 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -73,32 +73,6 @@ when defined(Windows): discard readConsoleInputW(hStdin, irInputRecord, 1, dwEventsRead) return result - from unicode import toUTF8, Rune, runeLenAt - - proc readPasswordFromStdin*(prompt: string, password: var TaintedString): - bool {.tags: [ReadIOEffect, WriteIOEffect].} = - ## Reads a `password` from stdin without printing it. `password` must not - ## be ``nil``! Returns ``false`` if the end of the file has been reached, - ## ``true`` otherwise. - password.setLen(0) - stdout.write(prompt) - while true: - let c = getch() - case c.char - of '\r', chr(0xA): - break - of '\b': - # ensure we delete the whole UTF-8 character: - var i = 0 - var x = 1 - while i < password.len: - x = runeLenAt(password, i) - inc i, x - password.setLen(max(password.len - x, 0)) - else: - password.add(toUTF8(c.Rune)) - stdout.write "\n" - else: import linenoise, termios @@ -124,21 +98,3 @@ else: linenoise.free(buffer) result = true - proc readPasswordFromStdin*(prompt: string, password: var TaintedString): - bool {.tags: [ReadIOEffect, WriteIOEffect].} = - password.setLen(0) - let fd = stdin.getFileHandle() - var cur, old: Termios - discard fd.tcgetattr(cur.addr) - old = cur - cur.c_lflag = cur.c_lflag and not Cflag(ECHO) - discard fd.tcsetattr(TCSADRAIN, cur.addr) - stdout.write prompt - result = stdin.readLine(password) - stdout.write "\n" - discard fd.tcsetattr(TCSADRAIN, old.addr) - -proc readPasswordFromStdin*(prompt: string): TaintedString = - ## Reads a password from stdin without printing it. - result = TaintedString("") - discard readPasswordFromStdin(prompt, result) diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 87e4ab591d564..4f2f73ba75c99 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -736,6 +736,56 @@ proc getch*(): char = result = stdin.readChar() discard fd.tcsetattr(TCSADRAIN, addr oldMode) +when defined(windows): + from unicode import toUTF8, Rune, runeLenAt + + proc readPasswordFromStdin*(prompt: string, password: var TaintedString): + bool {.tags: [ReadIOEffect, WriteIOEffect].} = + ## Reads a `password` from stdin without printing it. `password` must not + ## be ``nil``! Returns ``false`` if the end of the file has been reached, + ## ``true`` otherwise. + password.string.setLen(0) + stdout.write(prompt) + while true: + let c = getch() + case c.char + of '\r', chr(0xA): + break + of '\b': + # ensure we delete the whole UTF-8 character: + var i = 0 + var x = 1 + while i < password.len: + x = runeLenAt(password.string, i) + inc i, x + password.string.setLen(max(password.len - x, 0)) + else: + password.string.add(toUTF8(c.Rune)) + stdout.write "\n" + +else: + import termios + + proc readPasswordFromStdin*(prompt: string, password: var TaintedString): + bool {.tags: [ReadIOEffect, WriteIOEffect].} = + password.string.setLen(0) + let fd = stdin.getFileHandle() + var cur, old: Termios + discard fd.tcgetattr(cur.addr) + old = cur + cur.c_lflag = cur.c_lflag and not Cflag(ECHO) + discard fd.tcsetattr(TCSADRAIN, cur.addr) + stdout.write prompt + result = stdin.readLine(password) + stdout.write "\n" + discard fd.tcsetattr(TCSADRAIN, old.addr) + +proc readPasswordFromStdin*(prompt = "password: "): TaintedString = + ## Reads a password from stdin without printing it. + result = TaintedString("") + discard readPasswordFromStdin(prompt, result) + + # Wrappers assuming output to stdout: template hideCursor*() = hideCursor(stdout) template showCursor*() = showCursor(stdout) From 934bba5255cd73d31513b824b1cdf9dcc1738111 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 28 Feb 2018 10:01:18 +0100 Subject: [PATCH 11/15] some progress on #7261; VM does not support the new backwards indexing --- compiler/vm.nim | 18 +++++++++++++++--- compiler/vmgen.nim | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/compiler/vm.nim b/compiler/vm.nim index 0a706b0fc768a..23216f0a3a2ee 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -779,9 +779,21 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[ra].intVal = ord(regs[rb].intVal <% regs[rc].intVal) of opcEqRef: decodeBC(rkInt) - regs[ra].intVal = ord((regs[rb].node.kind == nkNilLit and - regs[rc].node.kind == nkNilLit) or - regs[rb].node == regs[rc].node) + if regs[rb].kind == rkNodeAddr: + if regs[rc].kind == rkNodeAddr: + regs[ra].intVal = ord(regs[rb].nodeAddr == regs[rc].nodeAddr) + else: + assert regs[rc].kind == rkNode + # we know these cannot be equal + regs[ra].intVal = ord(false) + elif regs[rc].kind == rkNodeAddr: + assert regs[rb].kind == rkNode + # we know these cannot be equal + regs[ra].intVal = ord(false) + else: + regs[ra].intVal = ord((regs[rb].node.kind == nkNilLit and + regs[rc].node.kind == nkNilLit) or + regs[rb].node == regs[rc].node) of opcEqNimrodNode: decodeBC(rkInt) regs[ra].intVal = diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index a22acdff0de65..bcfaeef230ca0 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1288,7 +1288,7 @@ proc whichAsgnOpc(n: PNode): TOpcode = opcAsgnStr of tyFloat..tyFloat128: opcAsgnFloat - of tyRef, tyNil, tyVar, tyLent: + of tyRef, tyNil, tyVar, tyLent, tyPtr: opcAsgnRef else: opcAsgnComplex From dd7c166260856563c0fa545a93264cbb9cb28e7a Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 28 Feb 2018 10:13:19 +0100 Subject: [PATCH 12/15] make tests green again --- tests/exception/tunhandledexc.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/exception/tunhandledexc.nim b/tests/exception/tunhandledexc.nim index b519fa3f65712..c318aec8177f9 100644 --- a/tests/exception/tunhandledexc.nim +++ b/tests/exception/tunhandledexc.nim @@ -2,7 +2,6 @@ discard """ file: "tunhandledexc.nim" outputsub: "Error: unhandled exception: bla [ESomeOtherErr]" exitcode: "1" - targets: "c cpp" """ type ESomething = object of Exception From e3e17009ff4fa13ed917b46a9709e9e51f62e7cf Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 28 Feb 2018 15:43:08 +0000 Subject: [PATCH 13/15] Sort changelog into appropriate headings. --- changelog.md | 420 +++++++++++++++++++++++++++++---------------------- 1 file changed, 242 insertions(+), 178 deletions(-) diff --git a/changelog.md b/changelog.md index e8a0f893ac7b6..ad737acffc4ae 100644 --- a/changelog.md +++ b/changelog.md @@ -2,97 +2,40 @@ ### Changes affecting backwards compatibility +#### Breaking changes in the standard library + +- The ``[]`` proc for strings now raises an ``IndexError`` exception when + the specified slice is out of bounds. See issue + [#6223](https://github.com/nim-lang/Nim/issues/6223) for more details. + You can use ``substr(str, start, finish)`` to get the old behaviour back, + see [this commit](https://github.com/nim-lang/nimbot/commit/98cc031a27ea89947daa7f0bb536bcf86462941f) for an example. + +- ``strutils.split`` and ``strutils.rsplit`` with an empty string and a + separator now returns that empty string. + See issue [#4377](https://github.com/nim-lang/Nim/issues/4377). - Arrays of char cannot be converted to ``cstring`` anymore, pointers to arrays of char can! This means ``$`` for arrays can finally exist in ``system.nim`` and do the right thing. -- ``echo`` now works with strings that contain ``\0`` (the binary zero is not - shown) and ``nil`` strings are equal to empty strings. -- JSON: Deprecated `getBVal`, `getFNum`, and `getNum` in favour to - `getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added. + - `reExtended` is no longer default for the `re` constructor in the `re` module. + +- The behavior of ``$`` has been changed for all standard library collections. The + collection-to-string implementations now perform proper quoting and escaping of + strings and chars. + - `newAsyncSocket` taking an `AsyncFD` now runs `setBlocking(false)` on the fd. -- The `ReadyKey` type in the selectors module now contains an ``errorCode`` - field to help distinguish between ``Event.Error`` events. -- Implemented an `accept` proc that works on a `SocketHandle` in - ``nativesockets``. -- Implemented ``getIoHandler`` proc in the ``asyncdispatch`` module that allows - you to retrieve the underlying IO Completion Port or ``Selector[AsyncData]`` - object in the specified dispatcher. -- The overloading rules changed slightly so that constrained generics are - preferred over unconstrained generics. (Bug #6526) -- It is now possible to forward declare object types so that mutually - recursive types can be created across module boundaries. See - [package level objects](https://nim-lang.org/docs/manual.html#package-level-objects) - for more information. -- The **unary** ``<`` is now deprecated, for ``.. <`` use ``..<`` for other usages - use the ``pred`` proc. -- We changed how array accesses "from backwards" like ``a[^1]`` or ``a[0..^1]`` are - implemented. These are now implemented purely in ``system.nim`` without compiler - support. There is a new "heterogenous" slice type ``system.HSlice`` that takes 2 - generic parameters which can be ``BackwardsIndex`` indices. ``BackwardsIndex`` is - produced by ``system.^``. - This means if you overload ``[]`` or ``[]=`` you need to ensure they also work - with ``system.BackwardsIndex`` (if applicable for the accessors). + - ``mod`` and bitwise ``and`` do not produce ``range`` subtypes anymore. This turned out to be more harmful than helpful and the language is simpler without this special typing rule. -- Added ``algorithm.rotateLeft``. -- ``rationals.toRational`` now uses an algorithm based on continued fractions. - This means its results are more precise and it can't run into an infinite loop - anymore. -- Added ``typetraits.$`` as an alias for ``typetraits.name``. -- ``os.getEnv`` now takes an optional ``default`` parameter that tells ``getEnv`` - what to return if the environment variable does not exist. -- Bodies of ``for`` loops now get their own scope: - -```nim - # now compiles: - for i in 0..4: - let i = i + 1 - echo i -``` - -- The parsing rules of ``if`` expressions were changed so that multiple - statements are allowed in the branches. We found few code examples that - now fail because of this change, but here is one: - -```nim - t[ti] = if exp_negative: '-' else: '+'; inc(ti) -``` - -This now needs to be written as: - -```nim - t[ti] = (if exp_negative: '-' else: '+'); inc(ti) -``` - -- To make Nim even more robust the system iterators ``..`` and ``countup`` - now only accept a single generic type ``T``. This means the following code - doesn't die with an "out of range" error anymore: - -```nim - var b = 5.Natural - var a = -5 - for i in a..b: - echo i -``` - ``formatFloat``/``formatBiggestFloat`` now support formatting floats with zero precision digits. The previous ``precision = 0`` behavior (default formatting) is now available via ``precision = -1``. -- The ``nim doc`` command is now an alias for ``nim doc2``, the second version of - the documentation generator. The old version 1 can still be accessed - via the new ``nim doc0`` command. -- Added ``system.getStackTraceEntries`` that allows you to access the stack - trace in a structured manner without string parsing. -- Added ``sequtils.mapLiterals`` for easier construction of array and tuple - literals. -- Added ``parseutils.parseSaturatedNatural``. -- ``atomic`` and ``generic`` are no longer keywords in Nim. ``generic`` used to be - an alias for ``concept``, ``atomic`` was not used for anything. + - Moved from stdlib into Nimble packages: - [``basic2d``](https://github.com/nim-lang/basic2d) _deprecated: use ``glm``, ``arraymancer``, ``neo``, or another package instead_ @@ -107,106 +50,121 @@ This now needs to be written as: - [``libsvm``](https://github.com/nim-lang/libsvm_legacy) - [``joyent_http_parser``](https://github.com/nim-lang/joyent_http_parser) -- Added ``system.runnableExamples`` to make examples in Nim's documentation easier - to write and test. The examples are tested as the last step of - ``nim doc``. -- Nim's ``rst2html`` command now supports the testing of code snippets via an RST - extension that we called ``:test:``:: +- Proc [toCountTable](https://nim-lang.org/docs/tables.html#toCountTable,openArray[A]) + now produces a `CountTable` with values correspoding to the number of occurrences + of the key in the input. It used to produce a table with all values set to `1`. - ```rst - .. code-block:: nim - :test: - # shows how the 'if' statement works - if true: echo "yes" + Counting occurrences in a sequence used to be: + + ```nim + let mySeq = @[1, 2, 1, 3, 1, 4] + var myCounter = initCountTable[int]() + + for item in mySeq: + myCounter.inc item ``` -- The ``[]`` proc for strings now raises an ``IndexError`` exception when - the specified slice is out of bounds. See issue - [#6223](https://github.com/nim-lang/Nim/issues/6223) for more details. - You can use ``substr(str, start, finish)`` to get the old behaviour back, - see [this commit](https://github.com/nim-lang/nimbot/commit/98cc031a27ea89947daa7f0bb536bcf86462941f) for an example. -- ``strutils.split`` and ``strutils.rsplit`` with an empty string and a - separator now returns that empty string. - See issue [#4377](https://github.com/nim-lang/Nim/issues/4377). + + Now, you can simply do: + + ```nim + let + mySeq = @[1, 2, 1, 3, 1, 4] + myCounter = mySeq.toCountTable() + ``` + +- If you use ``--dynlibOverride:ssl`` with OpenSSL 1.0.x, you now have to + define ``openssl10`` symbol (``-d:openssl10``). By default OpenSSL 1.1.x is + assumed. + +- ``newNativeSocket`` is now named ``createNativeSocket``. + +- ``newAsyncNativeSocket`` is now named ``createAsyncNativeSocket`` + and it no longer raises an OS error but returns an ``osInvalidSocket`` when + creation fails. + +- The ``securehash`` module is now deprecated. Instead import ``std / sha1``. + +- The ``readPasswordFromStdin`` proc has been moved from the ``rdstdin`` + to the ``terminal`` module, thus it does not depend on linenoise anymore. + +#### Breaking changes in the compiler + +- ``\n`` is now only the single line feed character like in most + other programming languages. The new platform specific newline escape sequence is + written as ``\p``. This change only affects the Windows platform. + +- The overloading rules changed slightly so that constrained generics are + preferred over unconstrained generics. (Bug #6526) + +- We changed how array accesses "from backwards" like ``a[^1]`` or ``a[0..^1]`` are + implemented. These are now implemented purely in ``system.nim`` without compiler + support. There is a new "heterogenous" slice type ``system.HSlice`` that takes 2 + generic parameters which can be ``BackwardsIndex`` indices. ``BackwardsIndex`` is + produced by ``system.^``. + This means if you overload ``[]`` or ``[]=`` you need to ensure they also work + with ``system.BackwardsIndex`` (if applicable for the accessors). + +- The parsing rules of ``if`` expressions were changed so that multiple + statements are allowed in the branches. We found few code examples that + now fail because of this change, but here is one: + +```nim +t[ti] = if exp_negative: '-' else: '+'; inc(ti) +``` + +This now needs to be written as: + +```nim +t[ti] = (if exp_negative: '-' else: '+'); inc(ti) +``` + - The experimental overloading of the dot ``.`` operators now take an ``untyped``` parameter as the field name, it used to be a ``static[string]``. You can use ``when defined(nimNewDot)`` to make your code work with both old and new Nim versions. See [special-operators](https://nim-lang.org/docs/manual.html#special-operators) for more information. -- Added ``macros.unpackVarargs``. -- The memory manager now uses a variant of the TLSF algorithm that has much - better memory fragmentation behaviour. According - to [http://www.gii.upv.es/tlsf/](http://www.gii.upv.es/tlsf/) the maximum - fragmentation measured is lower than 25%. As a nice bonus ``alloc`` and - ``dealloc`` became O(1) operations. -- The behavior of ``$`` has been changed for all standard library collections. The - collection-to-string implementations now perform proper quoting and escaping of - strings and chars. -- The ``random`` procs in ``random.nim`` have all been deprecated. Instead use - the new ``rand`` procs. The module now exports the state of the random - number generator as type ``Rand`` so multiple threads can easily use their - own random number generators that do not require locking. For more information - about this rename see issue [#6934](https://github.com/nim-lang/Nim/issues/6934) -- The compiler is now more consistent in its treatment of ambiguous symbols: - Types that shadow procs and vice versa are marked as ambiguous (bug #6693). + - ``yield`` (or ``await`` which is mapped to ``yield``) never worked reliably in an array, seq or object constructor and is now prevented at compile-time. + +### Library additions + +- **Added ``sequtils.mapLiterals`` for easier construction of array and tuple literals.** + +- Added ``system.runnableExamples`` to make examples in Nim's documentation easier + to write and test. The examples are tested as the last step of + ``nim doc``. + +- Implemented ``getIoHandler`` proc in the ``asyncdispatch`` module that allows + you to retrieve the underlying IO Completion Port or ``Selector[AsyncData]`` + object in the specified dispatcher. + - For string formatting / interpolation a new module called [strformat](https://nim-lang.org/docs/strformat.html) has been added to the stdlib. -- codegenDecl pragma now works for the JavaScript backend. It returns an empty string for - function return type placeholders. -- Asynchronous programming for the JavaScript backend using the `asyncjs` module. -- Extra semantic checks for procs with noreturn pragma: return type is not allowed, - statements after call to noreturn procs are no longer allowed. -- Noreturn proc calls and raising exceptions branches are now skipped during common type - deduction in if and case expressions. The following code snippets now compile: -```nim -import strutils -let str = "Y" -let a = case str: - of "Y": true - of "N": false - else: raise newException(ValueError, "Invalid boolean") -let b = case str: - of nil, "": raise newException(ValueError, "Invalid boolean") - elif str.startsWith("Y"): true - elif str.startsWith("N"): false - else: false -let c = if str == "Y": true - elif str == "N": false - else: - echo "invalid bool" - quit("this is the end") -``` -- Proc [toCountTable](https://nim-lang.org/docs/tables.html#toCountTable,openArray[A]) now produces a `CountTable` with values correspoding to the number of occurrences of the key in the input. It used to produce a table with all values set to `1`. -Counting occurrences in a sequence used to be: +- The `ReadyKey` type in the selectors module now contains an ``errorCode`` + field to help distinguish between ``Event.Error`` events. -```nim -let mySeq = @[1, 2, 1, 3, 1, 4] -var myCounter = initCountTable[int]() +- Implemented an `accept` proc that works on a `SocketHandle` in + ``nativesockets``. -for item in mySeq: - myCounter.inc item -``` +- Added ``algorithm.rotateLeft``. -Now, you can simply do: +- Added ``typetraits.$`` as an alias for ``typetraits.name``. -```nim -let - mySeq = @[1, 2, 1, 3, 1, 4] - myCounter = mySeq.toCountTable() -``` +- Added ``system.getStackTraceEntries`` that allows you to access the stack + trace in a structured manner without string parsing. -- Added support for casting between integers of same bitsize in VM (compile time and nimscript). - This allow to among other things to reinterpret signed integers as unsigned. +- Added ``parseutils.parseSaturatedNatural``. + +- Added ``macros.unpackVarargs``. -- Pragmas now support call syntax, for example: ``{.exportc"myname".}`` and ``{.exportc("myname").}`` -- Custom pragmas are now supported using pragma ``pragma``, please see language manual for details +- Added support for asynchronous programming for the JavaScript backend using + the `asyncjs` module. -- Added True Color support for some terminals - Example: +- Added true color support for some terminals. Example: ```nim import colors, terminal @@ -228,41 +186,147 @@ setForegroundColor colRed setBackgroundColor colGreen styledEcho "Red on Green.", resetStyle ``` -- If you use ``--dynlibOverride:ssl`` with OpenSSL 1.0.x, you now have to - define ``openssl10`` symbol (``-d:openssl10``). By default OpenSSL 1.1.x is - assumed. -- ``writeStackTrace`` is now proclaimed to have no IO effect (even though it does) - so that it is more useful for debugging purposes. -- ``\n`` is now only the single line feed character like in most - other programming languages. The new platform specific newline escape sequence is - written as ``\p``. This change only affects the Windows platform. -- ``newAsyncNativeSocket`` is now named ``createAsyncNativeSocket`` - and it no longer raises an OS error but returns an ``osInvalidSocket`` when - creation fails. -- ``newNativeSocket`` is now named ``createNativeSocket``. -- The ``deprecated`` pragma now supports a user-definable warning message for procs. +### Library changes -```nim +- ``echo`` now works with strings that contain ``\0`` (the binary zero is not + shown) and ``nil`` strings are equal to empty strings. -proc bar {.deprecated: "use foo instead".} = - return +- JSON: Deprecated `getBVal`, `getFNum`, and `getNum` in favour of + `getBool`, `getFloat`, `getBiggestInt`. A new `getInt` procedure was also + added. -bar() -``` +- ``rationals.toRational`` now uses an algorithm based on continued fractions. + This means its results are more precise and it can't run into an infinite loop + anymore. + +- ``os.getEnv`` now takes an optional ``default`` parameter that tells ``getEnv`` + what to return if the environment variable does not exist. + +- The ``random`` procs in ``random.nim`` have all been deprecated. Instead use + the new ``rand`` procs. The module now exports the state of the random + number generator as type ``Rand`` so multiple threads can easily use their + own random number generators that do not require locking. For more information + about this rename see issue [#6934](https://github.com/nim-lang/Nim/issues/6934) + +- ``writeStackTrace`` is now proclaimed to have no IO effect (even though it does) + so that it is more useful for debugging purposes. -- The ``securehash`` module is now deprecated. Instead import ``std / sha1``. - ``db_mysql`` module: ``DbConn`` is now a ``distinct`` type that doesn't expose the details of the underlying ``PMySQL`` type. + +### Language additions + +- It is now possible to forward declare object types so that mutually + recursive types can be created across module boundaries. See + [package level objects](https://nim-lang.org/docs/manual.html#package-level-objects) + for more information. + +- Added support for casting between integers of same bitsize in VM (compile time and nimscript). + This allows to, among other things, reinterpret signed integers as unsigned. + +- Custom pragmas are now supported using pragma ``pragma``, please see language + manual for details. + - Standard library modules can now also be imported via the ``std`` pseudo-directory. This is useful in order to distinguish between standard library and nimble package imports: + ```nim + import std / [strutils, os, osproc] + import someNimblePackage / [strutils, os] + ``` + +### Language changes + +- The **unary** ``<`` is now deprecated, for ``.. <`` use ``..<`` for other usages + use the ``pred`` proc. + +- Bodies of ``for`` loops now get their own scope: + ```nim +# now compiles: +for i in 0..4: + let i = i + 1 + echo i +``` + +- To make Nim even more robust the system iterators ``..`` and ``countup`` + now only accept a single generic type ``T``. This means the following code + doesn't die with an "out of range" error anymore: -import std / [strutils, os, osproc] -import someNimblePackage / [strutils, os] +```nim +var b = 5.Natural +var a = -5 +for i in a..b: + echo i ``` -- The ``readPasswordFromStdin`` proc has been moved from the ``rdstdin`` - to the ``terminal`` module, thus it does not depend on linenoise anymore. +- ``atomic`` and ``generic`` are no longer keywords in Nim. ``generic`` used to be + an alias for ``concept``, ``atomic`` was not used for anything. + +- The memory manager now uses a variant of the TLSF algorithm that has much + better memory fragmentation behaviour. According + to [http://www.gii.upv.es/tlsf/](http://www.gii.upv.es/tlsf/) the maximum + fragmentation measured is lower than 25%. As a nice bonus ``alloc`` and + ``dealloc`` became O(1) operations. + +- The compiler is now more consistent in its treatment of ambiguous symbols: + Types that shadow procs and vice versa are marked as ambiguous (bug #6693). + +- codegenDecl pragma now works for the JavaScript backend. It returns an empty + string for function return type placeholders. + +- Extra semantic checks for procs with noreturn pragma: return type is not allowed, + statements after call to noreturn procs are no longer allowed. + +- Noreturn proc calls and raising exceptions branches are now skipped during common type + deduction in ``if`` and ``case`` expressions. The following code snippets now compile: + ```nim + import strutils + let str = "Y" + let a = case str: + of "Y": true + of "N": false + else: raise newException(ValueError, "Invalid boolean") + let b = case str: + of nil, "": raise newException(ValueError, "Invalid boolean") + elif str.startsWith("Y"): true + elif str.startsWith("N"): false + else: false + let c = if str == "Y": true + elif str == "N": false + else: + echo "invalid bool" + quit("this is the end") + ``` + +- Pragmas now support call syntax, for example: ``{.exportc"myname".}`` and + ``{.exportc("myname").}`` + +- The ``deprecated`` pragma now supports a user-definable warning message for procs. + + ```nim + proc bar {.deprecated: "use foo instead".} = + return + + bar() + ``` + +### Tool changes + +- The ``nim doc`` command is now an alias for ``nim doc2``, the second version of + the documentation generator. The old version 1 can still be accessed + via the new ``nim doc0`` command. + +- Nim's ``rst2html`` command now supports the testing of code snippets via an RST + extension that we called ``:test:``:: + + ```rst + .. code-block:: nim + :test: + # shows how the 'if' statement works + if true: echo "yes" + ``` + +### Compiler changes From 91cab6dbd3867db93e7fd266539d35288af3d190 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 28 Feb 2018 16:36:18 +0000 Subject: [PATCH 14/15] Add bugfixes list to changelog. --- changelog.md | 327 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 327 insertions(+) diff --git a/changelog.md b/changelog.md index ad737acffc4ae..1cd22c4da2c7b 100644 --- a/changelog.md +++ b/changelog.md @@ -330,3 +330,330 @@ for i in a..b: ``` ### Compiler changes + +### Bugfixes + +- Fixed "ReraiseError when using try/except within finally block" + ([#5871](https://github.com/nim-lang/Nim/issues/5871)) +- Fixed "Range type inference leads to counter-intuitive behvaiour" + ([#5854](https://github.com/nim-lang/Nim/issues/5854)) +- Fixed "JSON % operator can fail in extern procs with dynamic types" + ([#6385](https://github.com/nim-lang/Nim/issues/6385)) +- Fixed ""intVal is not accessible" in VM" + ([#6083](https://github.com/nim-lang/Nim/issues/6083)) +- Fixed "Add excl for OrderedSet" + ([#2467](https://github.com/nim-lang/Nim/issues/2467)) +- Fixed "newSeqOfCap actually doesn't reserve memory" + ([#6403](https://github.com/nim-lang/Nim/issues/6403)) +- Fixed "[Regression] Nim segfaults" + ([#6435](https://github.com/nim-lang/Nim/issues/6435)) +- Fixed "Seq assignment is slower than expected" + ([#6433](https://github.com/nim-lang/Nim/issues/6433)) +- Fixed "json module issues with empty dicts and lists" + ([#6438](https://github.com/nim-lang/Nim/issues/6438)) +- Fixed "mingw installed via finish.exe fails to link if Nim located in path with whitespace" + ([#6452](https://github.com/nim-lang/Nim/issues/6452)) +- Fixed "unittest.check does not perform short-circuit evaluation" + ([#5784](https://github.com/nim-lang/Nim/issues/5784)) +- Fixed "Error while concatenating an array of chars." + ([#5861](https://github.com/nim-lang/Nim/issues/5861)) +- Fixed "range initialization: [ProveInit] hint: Cannot prove that" + ([#6474](https://github.com/nim-lang/Nim/issues/6474)) +- Fixed "scanf can call procs with side-effects multiple times" + ([#6487](https://github.com/nim-lang/Nim/issues/6487)) +- Fixed "gcsafe detection problem" + ([#5620](https://github.com/nim-lang/Nim/issues/5620)) +- Fixed "C++ codegen: `mitems` generates invalid code." + ([#4910](https://github.com/nim-lang/Nim/issues/4910)) +- Fixed "strange runtime behavior on macOS" + ([#6496](https://github.com/nim-lang/Nim/issues/6496)) +- Fixed "stdtmpl: invalid indentation after a line ending in question mark" + ([#5070](https://github.com/nim-lang/Nim/issues/5070)) +- Fixed "Windows: NAN troubles on c backend" + ([#6511](https://github.com/nim-lang/Nim/issues/6511)) +- Fixed "lib/nim/system/cellsets.nim(33, 31) Error: type mismatch while attempting to compile for 16bit CPUs" + ([#3558](https://github.com/nim-lang/Nim/issues/3558)) +- Fixed "Can't compile dynlib with ``-d:useNimRtl`` and ``--threads:on``" + ([#5143](https://github.com/nim-lang/Nim/issues/5143)) +- Fixed "var s = @[0,1,2,...] can generate thousand of single assignments in C code" + ([#5007](https://github.com/nim-lang/Nim/issues/5007)) +- Fixed "`echo` discards everything after a null character" + ([#1137](https://github.com/nim-lang/Nim/issues/1137)) +- Fixed "Turn off reExtended by default" + ([#5627](https://github.com/nim-lang/Nim/issues/5627)) +- Fixed "Bad Links in docs/backends.html" + ([#5914](https://github.com/nim-lang/Nim/issues/5914)) +- Fixed "Index out of bounds error in db_postgres when executing non parameter-substituted queries containing "?"" + ([#6571](https://github.com/nim-lang/Nim/issues/6571)) +- Fixed "Please add pipe2 support to posix stdlib" + ([#6553](https://github.com/nim-lang/Nim/issues/6553)) +- Fixed "Return semantics vary depending on return style" + ([#6422](https://github.com/nim-lang/Nim/issues/6422)) +- Fixed "parsecsv.open reports SIGSEGV when calling 'open' on missing file" + ([#6148](https://github.com/nim-lang/Nim/issues/6148)) +- Fixed "VCC: Nim generates non-compilable code for system.nim" + ([#6606](https://github.com/nim-lang/Nim/issues/6606)) +- Fixed "Generic subtype matches worse than a generic" + ([#6526](https://github.com/nim-lang/Nim/issues/6526)) +- Fixed "formatFloat inconsistent scientific notation" + ([#6589](https://github.com/nim-lang/Nim/issues/6589)) +- Fixed "Generated c code calls function twice" + ([#6292](https://github.com/nim-lang/Nim/issues/6292)) +- Fixed "Range type inference leads to counter-intuitive behvaiour" + ([#5854](https://github.com/nim-lang/Nim/issues/5854)) +- Fixed "New backward indexing is too limited" + ([#6631](https://github.com/nim-lang/Nim/issues/6631)) +- Fixed "Table usage in a macro (SIGSEGV: Illegal storage access.)" + ([#1860](https://github.com/nim-lang/Nim/issues/1860)) +- Fixed "Incorrect deprecation error" + ([#6634](https://github.com/nim-lang/Nim/issues/6634)) +- Fixed "Wrong indices in arrays not starting with 0" + ([#6675](https://github.com/nim-lang/Nim/issues/6675)) +- Fixed "if expressions" + ([#6609](https://github.com/nim-lang/Nim/issues/6609)) +- Fixed "BackwardsIndex: converter + `[]` + unrelated type[^1]: lib/system.nim(3536, 3) Error" + ([#6692](https://github.com/nim-lang/Nim/issues/6692)) +- Fixed "BackwardsIndex: converter + `[]` + unrelated type[^1]: lib/system.nim(3536, 3) Error" + ([#6692](https://github.com/nim-lang/Nim/issues/6692)) +- Fixed "js backend 0.17.3: array bounds check for non zero based arrays is buggy" + ([#6532](https://github.com/nim-lang/Nim/issues/6532)) +- Fixed "HttpClient's new API doesn't work through a proxy for https URLs" + ([#6685](https://github.com/nim-lang/Nim/issues/6685)) +- Fixed "isServing isn't declared and isn't compiling" + ([#6707](https://github.com/nim-lang/Nim/issues/6707)) +- Fixed "[Regression] value out of range" + ([#6710](https://github.com/nim-lang/Nim/issues/6710)) + +- Fixed "Error when using `multisync` macro" + ([#6708](https://github.com/nim-lang/Nim/issues/6708)) + +- Fixed "formatFloat inconsistent scientific notation" + ([#6589](https://github.com/nim-lang/Nim/issues/6589)) +- Fixed "Using : (constructor arguments) for passing values to functions with default arguments causes a compiler crash." + ([#6765](https://github.com/nim-lang/Nim/issues/6765)) +- Fixed "In-place object initialization leads to vcc incompatible code" + ([#6757](https://github.com/nim-lang/Nim/issues/6757)) +- Fixed "Improve parseCookies doc" + ([#5721](https://github.com/nim-lang/Nim/issues/5721)) +- Fixed "Parser regression with nested do notation inside conditional" + ([#6166](https://github.com/nim-lang/Nim/issues/6166)) +- Fixed "Request for better error message" + ([#6776](https://github.com/nim-lang/Nim/issues/6776)) +- Fixed "Testament tester does not execute test with `exitcode` only" + ([#6775](https://github.com/nim-lang/Nim/issues/6775)) +- Fixed "JS integer division off by one" + ([#6753](https://github.com/nim-lang/Nim/issues/6753)) +- Fixed "Regression: cannot prove not nil" + ([#5781](https://github.com/nim-lang/Nim/issues/5781)) +- Fixed "SIGSEGV: Illegal storage access. (Attempt to read from nil?) in generic proc" + ([#6073](https://github.com/nim-lang/Nim/issues/6073)) +- Fixed "Request for better error message" + ([#6776](https://github.com/nim-lang/Nim/issues/6776)) +- Fixed "Nim #head: sorting via reference hangs compiler" + ([#6724](https://github.com/nim-lang/Nim/issues/6724)) +- Fixed "Cannot cast pointer to char in cpp" + ([#5979](https://github.com/nim-lang/Nim/issues/5979)) +- Fixed "asynchttpserver replies with several errors on single request" + ([#6386](https://github.com/nim-lang/Nim/issues/6386)) +- Fixed "object variants superclass trigger bad codegen" + ([#5521](https://github.com/nim-lang/Nim/issues/5521)) +- Fixed "JS integer division off by one" + ([#6753](https://github.com/nim-lang/Nim/issues/6753)) +- Fixed "js backend compiler crash with tables indexed by certain types" + ([#6568](https://github.com/nim-lang/Nim/issues/6568)) +- Fixed "Jsgen bug with is" + ([#6445](https://github.com/nim-lang/Nim/issues/6445)) +- Fixed "Subrange definition with ..<" + ([#6788](https://github.com/nim-lang/Nim/issues/6788)) +- Fixed "fields not initialized: array with enum index type as object field." + ([#6682](https://github.com/nim-lang/Nim/issues/6682)) +- Fixed "Can not delete data in table when table's data type is kind of "not nil"" + ([#6555](https://github.com/nim-lang/Nim/issues/6555)) +- Fixed "tables.nim: Cannot prove that 'n' is initialized" + ([#6121](https://github.com/nim-lang/Nim/issues/6121)) +- Fixed "issues with 'not nil' applied to a closure proc" + ([#6489](https://github.com/nim-lang/Nim/issues/6489)) +- Fixed "`not nil` not working in some cases" + ([#4686](https://github.com/nim-lang/Nim/issues/4686)) +- Fixed "Cannot prove '@[v]' is not nil" + ([#3993](https://github.com/nim-lang/Nim/issues/3993)) + +- Fixed "Feature: support TCP_NODELAY in net.sockets" + ([#6795](https://github.com/nim-lang/Nim/issues/6795)) +- Fixed "Code that makes the compiler throw an error message and then hangs" + ([#6820](https://github.com/nim-lang/Nim/issues/6820)) +- Fixed "Code that makes the compiler throw an error message and then hangs" + ([#6820](https://github.com/nim-lang/Nim/issues/6820)) +- Fixed "Inconsistent behavior with sequence and string slicing" + ([#6223](https://github.com/nim-lang/Nim/issues/6223)) +- Fixed "Wrong behavior of "split" (proc and iterator)" + ([#4377](https://github.com/nim-lang/Nim/issues/4377)) +- Fixed "[Documentation] Invalid module name: [foo, bar]" + ([#6831](https://github.com/nim-lang/Nim/issues/6831)) +- Fixed "The destructor is not called for temporary objects" + ([#4214](https://github.com/nim-lang/Nim/issues/4214)) +- Fixed "Destructors does not work with implicit items iterator in for loop" + ([#985](https://github.com/nim-lang/Nim/issues/985)) +- Fixed "Error in template when using the type of the parameter inside it" + ([#6756](https://github.com/nim-lang/Nim/issues/6756)) +- Fixed "should json.to() respect parent attributes?" + ([#5856](https://github.com/nim-lang/Nim/issues/5856)) +- Fixed "json 'to' macro can not marshalize into tuples" + ([#6095](https://github.com/nim-lang/Nim/issues/6095)) +- Fixed "json.to fails with seq[T]" + ([#6604](https://github.com/nim-lang/Nim/issues/6604)) +- Fixed "json.to() is not worth using compared to marshal.to[T]" + ([#5848](https://github.com/nim-lang/Nim/issues/5848)) +- Fixed "Memory not being released in time, running out of memory" + ([#6031](https://github.com/nim-lang/Nim/issues/6031)) +- Fixed "[Regression] Bad C codegen for generic code" + ([#6889](https://github.com/nim-lang/Nim/issues/6889)) +- Fixed "rollingFileLogger deletes file on every start." + ([#6264](https://github.com/nim-lang/Nim/issues/6264)) +- Fixed "Remove/deprecate securehash module." + ([#6033](https://github.com/nim-lang/Nim/issues/6033)) +- Fixed "[bug or not] object construction for seq[T] failed without space after colon" + ([#5999](https://github.com/nim-lang/Nim/issues/5999)) +- Fixed "issues with the random module" + ([#4726](https://github.com/nim-lang/Nim/issues/4726)) +- Fixed "Reassigning local var to seq of objects results in nil element in Object's seq field" + ([#668](https://github.com/nim-lang/Nim/issues/668)) +- Fixed "Compilation error with "newseq[string]"" + ([#6726](https://github.com/nim-lang/Nim/issues/6726)) +- Fixed "await inside array/dict literal produces invalid code - Part 2" + ([#6626](https://github.com/nim-lang/Nim/issues/6626)) +- Fixed "terminal.eraseline() gives OverflowError on Windows" + ([#6931](https://github.com/nim-lang/Nim/issues/6931)) +- Fixed "[Regression] `sequtils.any` conflicts with `system.any`" + ([#6932](https://github.com/nim-lang/Nim/issues/6932)) +- Fixed "C++ codegen: `mitems` generates invalid code." + ([#4910](https://github.com/nim-lang/Nim/issues/4910)) +- Fixed "seq.mitems produces invalid cpp codegen" + ([#6892](https://github.com/nim-lang/Nim/issues/6892)) +- Fixed "Concepts regression" + ([#6108](https://github.com/nim-lang/Nim/issues/6108)) +- Fixed "Generic iterable concept with array crashes compiler" + ([#6277](https://github.com/nim-lang/Nim/issues/6277)) +- Fixed "C code generation "‘a’ is a pointer; did you mean to use ‘->’?"" + ([#6462](https://github.com/nim-lang/Nim/issues/6462)) +- Fixed "`--NimblePath` fails if a `-` in path which is not followed by a number" + ([#6949](https://github.com/nim-lang/Nim/issues/6949)) +- Fixed ""not registered in the selector" in asyncfile.close() for something that clearly was registered" + ([#6906](https://github.com/nim-lang/Nim/issues/6906)) +- Fixed "strange frexp behavior" + ([#6353](https://github.com/nim-lang/Nim/issues/6353)) + +- Fixed "noreturn branches of case statements shouldn't contribute to type" + ([#6885](https://github.com/nim-lang/Nim/issues/6885)) +- Fixed "Type inference for 'if' statements changed" + ([#6980](https://github.com/nim-lang/Nim/issues/6980)) +- Fixed "newest asyncdispatch recursion" + ([#6100](https://github.com/nim-lang/Nim/issues/6100)) +- Fixed "Ambiguous identifier between set type and proc" + ([#6965](https://github.com/nim-lang/Nim/issues/6965)) + +- Fixed "Inconsistent behavior with sequence and string slicing" + ([#6223](https://github.com/nim-lang/Nim/issues/6223)) + +- Fixed "Unsupported OpenSSL library imported dynamically" + ([#5000](https://github.com/nim-lang/Nim/issues/5000)) +- Fixed "`nim check` segfaults" + ([#6972](https://github.com/nim-lang/Nim/issues/6972)) +- Fixed "GC deadlock" + ([#6988](https://github.com/nim-lang/Nim/issues/6988)) +- Fixed "Create a seq without memory initialization" + ([#6401](https://github.com/nim-lang/Nim/issues/6401)) +- Fixed "Fix bug for getch on Windows while using the arrow keys" + ([#6966](https://github.com/nim-lang/Nim/issues/6966)) +- Fixed "runnableExamples doesn't work in templates" + ([#7018](https://github.com/nim-lang/Nim/issues/7018)) +- Fixed "runnableExamples doesn't work with untyped statement blocks" + ([#7019](https://github.com/nim-lang/Nim/issues/7019)) + +- Fixed "Critical bug in parseBiggestFloat" + ([#7060](https://github.com/nim-lang/Nim/issues/7060)) +- Fixed "[RFC] strformat.% should be gone" + ([#7078](https://github.com/nim-lang/Nim/issues/7078)) +- Fixed "compiler crash on simple macro" + ([#7093](https://github.com/nim-lang/Nim/issues/7093)) +- Fixed "Make newlines sane again" + ([#7089](https://github.com/nim-lang/Nim/issues/7089)) +- Fixed "JS - Unicode enum string representation issue" + ([#6741](https://github.com/nim-lang/Nim/issues/6741)) +- Fixed "Strange behaviour of 0.17.3 (working ok in 0.17.2)" + ([#6989](https://github.com/nim-lang/Nim/issues/6989)) +- Fixed "Strange behaviour of 0.17.3 (working ok in 0.17.2)" + ([#6989](https://github.com/nim-lang/Nim/issues/6989)) +- Fixed "Compiler crash: try expression with infix as" + ([#7116](https://github.com/nim-lang/Nim/issues/7116)) +- Fixed "nimsuggest crash" + ([#7140](https://github.com/nim-lang/Nim/issues/7140)) +- Fixed "[RFC] Reintroduce readChar" + ([#7072](https://github.com/nim-lang/Nim/issues/7072)) +- Fixed "Copyright line needs updating" + ([#7129](https://github.com/nim-lang/Nim/issues/7129)) +- Fixed "-0.0 doesn't result in negative zero in VM" + ([#7079](https://github.com/nim-lang/Nim/issues/7079)) +- Fixed "Windows large filesize" + ([#7121](https://github.com/nim-lang/Nim/issues/7121)) +- Fixed "Securehash is not parsimonious with MD5 and other hash modules" + ([#6961](https://github.com/nim-lang/Nim/issues/6961)) +- Fixed "os.findExe() shouldn't look in current directory on posix, unless exe has a /" + ([#6939](https://github.com/nim-lang/Nim/issues/6939)) +- Fixed "`compiles(...)` with `fatal` pragma causes compiler to exit early" + ([#7080](https://github.com/nim-lang/Nim/issues/7080)) +- Fixed "NPE when compile macro that returns concrete value" + ([#5450](https://github.com/nim-lang/Nim/issues/5450)) +- Fixed "Using a variable of type `int | float` causes internal compiler error" + ([#6946](https://github.com/nim-lang/Nim/issues/6946)) +- Fixed "Unsigned integers could not be used as array indexes." + ([#7153](https://github.com/nim-lang/Nim/issues/7153)) +- Fixed "countdown with uint causes underflow" + ([#4220](https://github.com/nim-lang/Nim/issues/4220)) +- Fixed "Inconsistent method call syntax" + ([#7200](https://github.com/nim-lang/Nim/issues/7200)) +- Fixed "Impossible to create an empty const array" + ([#6853](https://github.com/nim-lang/Nim/issues/6853)) +- Fixed "Strange UINT handling" + ([#3985](https://github.com/nim-lang/Nim/issues/3985)) +- Fixed "Bad codegen when passing arg that is part of return value destination" + ([#6960](https://github.com/nim-lang/Nim/issues/6960)) +- Fixed "No info about gcsafety in error message when global var is accessed in async proc" + ([#6186](https://github.com/nim-lang/Nim/issues/6186)) +- Fixed "Resolving package vs. local import ambiguities" + ([#2819](https://github.com/nim-lang/Nim/issues/2819)) +- Fixed "Internal error with type() operator" + ([#3711](https://github.com/nim-lang/Nim/issues/3711)) +- Fixed "newAsyncSocket should raise an OS error plus other inconsistencies" + ([#4995](https://github.com/nim-lang/Nim/issues/4995)) +- Fixed "mapLiterals fails with negative values" + ([#7215](https://github.com/nim-lang/Nim/issues/7215)) +- Fixed "fmWrite doesn't truncate file with openAsync, unlike open()" + ([#5531](https://github.com/nim-lang/Nim/issues/5531)) +- Fixed "Move libsvm to an external nimble module" + ([#5786](https://github.com/nim-lang/Nim/issues/5786)) +- Fixed "Prevent acceptAddr gotcha with newSocket" + ([#7227](https://github.com/nim-lang/Nim/issues/7227)) +- Fixed "strtabs.getOrDefault is inconsistent with tables.getOrDefault" + ([#4265](https://github.com/nim-lang/Nim/issues/4265)) + +- Fixed "Code falling through into exception handler when no exception thrown." + ([#7232](https://github.com/nim-lang/Nim/issues/7232)) +- Fixed "the new generic inference rules are broken" + ([#7247](https://github.com/nim-lang/Nim/issues/7247)) +- Fixed "Odd `..<` regression" + ([#6992](https://github.com/nim-lang/Nim/issues/6992)) +- Fixed "Different proc type inferred from default parameter" + ([#4659](https://github.com/nim-lang/Nim/issues/4659)) +- Fixed "Different proc type inferred from default parameter" + ([#4659](https://github.com/nim-lang/Nim/issues/4659)) +- Fixed "Testament sometimes ignores test failures" + ([#7236](https://github.com/nim-lang/Nim/issues/7236)) +- Fixed "New Allocator Fails On >=4GB Requests" + ([#7120](https://github.com/nim-lang/Nim/issues/7120)) +- Fixed "User pragmas hide effect specifications from sempass2" + ([#7216](https://github.com/nim-lang/Nim/issues/7216)) +- Fixed "C++: SIGABRT instead of IndexError for out-of-bounds" + ([#6512](https://github.com/nim-lang/Nim/issues/6512)) +- Fixed "An uncaught exception in cpp mode doesn't show the exception name/msg" + ([#6431](https://github.com/nim-lang/Nim/issues/6431)) \ No newline at end of file From 51935c47b0f1c93df28c92fce96ba80501d561e0 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 28 Feb 2018 23:00:37 +0100 Subject: [PATCH 15/15] deprecate parseopt2 stdlib module --- changelog.md | 2 ++ lib/pure/parseopt2.nim | 1 + 2 files changed, 3 insertions(+) diff --git a/changelog.md b/changelog.md index 1cd22c4da2c7b..955648c20967e 100644 --- a/changelog.md +++ b/changelog.md @@ -215,6 +215,8 @@ styledEcho "Red on Green.", resetStyle - ``db_mysql`` module: ``DbConn`` is now a ``distinct`` type that doesn't expose the details of the underlying ``PMySQL`` type. +- ``parseopt2`` is now deprecated, use ``parseopt`` instead. + ### Language additions - It is now possible to forward declare object types so that mutually diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim index a2ff9bf0c0cdf..2b63663eb7dc8 100644 --- a/lib/pure/parseopt2.nim +++ b/lib/pure/parseopt2.nim @@ -17,6 +17,7 @@ ## 2. long option - ``--foo:bar``, ``--foo=bar`` or ``--foo`` ## 3. argument - everything else +{.deprecated.} {.push debugger: off.} include "system/inclrtl"