From 7c03c882f55d7c03ce94943d0d8f622c6904a334 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Tue, 31 Oct 2017 19:48:01 +0100 Subject: [PATCH 01/23] Remove more usages of unary lt (fixes #6634) (#6641) * fixes #6634 * remove more usages of unary < --- compiler/semdata.nim | 2 +- lib/pure/securehash.nim | 2 +- lib/system/debugger.nim | 4 ++-- lib/system/repr.nim | 2 +- lib/system/sysspawn.nim | 2 +- nimsuggest/sexp.nim | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 3e57d1104b..5057260a4b 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -339,7 +339,7 @@ proc makeNotType*(c: PContext, t1: PType): PType = proc nMinusOne*(n: PNode): PNode = result = newNode(nkCall, n.info, @[ - newSymNode(getSysMagic("<", mUnaryLt)), + newSymNode(getSysMagic("pred", mPred)), n]) # Remember to fix the procs below this one when you make changes! diff --git a/lib/pure/securehash.nim b/lib/pure/securehash.nim index c191466698..57c1f3631c 100644 --- a/lib/pure/securehash.nim +++ b/lib/pure/securehash.nim @@ -181,7 +181,7 @@ proc `$`*(self: SecureHash): string = result.add(toHex(int(v), 2)) proc parseSecureHash*(hash: string): SecureHash = - for i in 0.. Date: Tue, 31 Oct 2017 22:30:48 +0100 Subject: [PATCH 02/23] attempt to fix the tester; tests should be red now --- tests/testament/tester.nim | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim index dd5e70d501..0daf4089e5 100644 --- a/tests/testament/tester.nim +++ b/tests/testament/tester.nim @@ -30,7 +30,6 @@ Arguments: Options: --print also print results to the console --failing only show failing/ignored tests - --pedantic return non-zero status code if there are failures --targets:"c c++ js objc" run tests for specified targets (default: all) --nim:path use a particular nim executable (default: compiler/nim) """ % resultsFile @@ -439,7 +438,6 @@ proc main() = backend.open() var optPrintResults = false var optFailing = false - var optPedantic = false var p = initOptParser() p.next() @@ -447,7 +445,7 @@ proc main() = case p.key.string.normalize of "print", "verbose": optPrintResults = true of "failing": optFailing = true - of "pedantic": optPedantic = true + of "pedantic": discard "now always enabled" of "targets": targets = parseTargets(p.val.string) of "nim": compilerPrefix = p.val.string else: quit Usage @@ -488,11 +486,10 @@ proc main() = if action == "html": openDefaultBrowser(resultsFile) else: echo r, r.data backend.close() - if optPedantic: - var failed = r.total - r.passed - r.skipped - if failed > 0: - echo "FAILURE! total: ", r.total, " passed: ", r.passed, " skipped: ", r.skipped - quit(QuitFailure) + var failed = r.total - r.passed - r.skipped + if failed > 0: + echo "FAILURE! total: ", r.total, " passed: ", r.passed, " skipped: ", r.skipped + quit(QuitFailure) if paramCount() == 0: quit Usage From 3174cfe55c6da6c83dfe83667744ccd8acb7a1ce Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 1 Nov 2017 00:20:40 +0100 Subject: [PATCH 03/23] make tests green again --- lib/pure/strutils.nim | 3 ++- tests/misc/tvarnums.nim | 2 +- tests/stdlib/nre/captures.nim | 6 +++--- tests/stdlib/nre/find.nim | 2 +- tests/system/toString.nim | 4 ++-- tests/vm/trgba.nim | 10 +++++----- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 18b0954f34..2b87e0d430 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -2434,7 +2434,8 @@ when isMainModule: doAssert formatBiggestFloat(0.00000000001, ffScientific, 1, ',') in ["1,0e-11", "1,0e-011"] # bug #6589 - doAssert formatFloat(123.456, ffScientific, precision=0) == "1.234560e+02" + doAssert formatFloat(123.456, ffScientific, precision=0) in + ["1.234560e+02", "1.234560e+002"] doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c" doAssert "${1}12 ${-1}$2" % ["a", "b"] == "a12 bb" diff --git a/tests/misc/tvarnums.nim b/tests/misc/tvarnums.nim index a5c30c7ebf..5daa2c4b8e 100644 --- a/tests/misc/tvarnums.nim +++ b/tests/misc/tvarnums.nim @@ -67,7 +67,7 @@ proc toNum64(b: TBuffer): int64 = proc toNum(b: TBuffer): int32 = # treat first byte different: - result = ze(b[0]) and 63 + result = int32 ze(b[0]) and 63 var i = 0 Shift = 6'i32 diff --git a/tests/stdlib/nre/captures.nim b/tests/stdlib/nre/captures.nim index fa01a20005..19c344a8db 100644 --- a/tests/stdlib/nre/captures.nim +++ b/tests/stdlib/nre/captures.nim @@ -32,7 +32,7 @@ suite "captures": test "named capture bounds": let ex1 = "foo".find(re("(?foo)(?bar)?")) check(ex1.captureBounds["foo"] == some(0..2)) - check(ex1.captureBounds["bar"] == none(Slice[int, int])) + check(ex1.captureBounds["bar"] == none(Slice[int])) test "capture count": let ex1 = re("(?foo)(?bar)?") @@ -42,7 +42,7 @@ suite "captures": test "named capture table": let ex1 = "foo".find(re("(?foo)(?bar)?")) check(ex1.captures.toTable == {"foo" : "foo", "bar" : nil}.toTable()) - check(ex1.captureBounds.toTable == {"foo" : some(0..2), "bar" : none(Slice[int, int])}.toTable()) + check(ex1.captureBounds.toTable == {"foo" : some(0..2), "bar" : none(Slice[int])}.toTable()) check(ex1.captures.toTable("") == {"foo" : "foo", "bar" : ""}.toTable()) let ex2 = "foobar".find(re("(?foo)(?bar)?")) @@ -51,7 +51,7 @@ suite "captures": test "capture sequence": let ex1 = "foo".find(re("(?foo)(?bar)?")) check(ex1.captures.toSeq == @["foo", nil]) - check(ex1.captureBounds.toSeq == @[some(0..2), none(Slice[int, int])]) + check(ex1.captureBounds.toSeq == @[some(0..2), none(Slice[int])]) check(ex1.captures.toSeq("") == @["foo", ""]) let ex2 = "foobar".find(re("(?foo)(?bar)?")) diff --git a/tests/stdlib/nre/find.nim b/tests/stdlib/nre/find.nim index c37ac56ba0..caa953ff45 100644 --- a/tests/stdlib/nre/find.nim +++ b/tests/stdlib/nre/find.nim @@ -12,7 +12,7 @@ suite "find": test "find bounds": check(toSeq(findIter("1 2 3 4 5 ", re" ")).map( - proc (a: RegexMatch): Slice[int, int] = a.matchBounds + proc (a: RegexMatch): Slice[int] = a.matchBounds ) == @[1..1, 3..3, 5..5, 7..7, 9..9]) test "overlapping find": diff --git a/tests/system/toString.nim b/tests/system/toString.nim index 1279897a7d..3e7fc7ddbd 100644 --- a/tests/system/toString.nim +++ b/tests/system/toString.nim @@ -3,9 +3,9 @@ discard """ """ doAssert "@[23, 45]" == $(@[23, 45]) -doAssert "[32, 45]" == $([32, 45]) +doAssert "[32, 45]" == $([32, 45]) doAssert "@[, foo, bar]" == $(@["", "foo", "bar"]) -doAssert "[, foo, bar]" == $(["", "foo", "bar"]) +doAssert "[, foo, bar]" == $(["", "foo", "bar"]) # bug #2395 let alphaSet: set[char] = {'a'..'c'} diff --git a/tests/vm/trgba.nim b/tests/vm/trgba.nim index da1a2d0c52..923ea1b2e8 100644 --- a/tests/vm/trgba.nim +++ b/tests/vm/trgba.nim @@ -22,14 +22,14 @@ template `B=`*(self: TAggRgba8, val: byte) = template `A=`*(self: TAggRgba8, val: byte) = self[3] = val -proc ABGR* (val: int| int64): TAggRgba8 = +proc ABGR*(val: int| int64): TAggRgba8 = var V = val - result.R = V and 0xFF + result.R = byte(V and 0xFF) V = V shr 8 - result.G = V and 0xFF + result.G = byte(V and 0xFF) V = V shr 8 - result.B = V and 0xFF - result.A = (V shr 8) and 0xFF + result.B = byte(V and 0xFF) + result.A = byte((V shr 8) and 0xFF) const c1 = ABGR(0xFF007F7F) From 22de45ef69dea426d13858e88ed4ec8dcd0d6dc8 Mon Sep 17 00:00:00 2001 From: "Lynn C. Rees" Date: Tue, 31 Oct 2017 17:46:10 -0600 Subject: [PATCH 04/23] Add oswalkdir to doc index (#6651) --- web/website.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/website.ini b/web/website.ini index b91e4003a5..5576728b56 100644 --- a/web/website.ini +++ b/web/website.ini @@ -62,7 +62,7 @@ srcdoc2: "pure/nativesockets;pure/asynchttpserver;pure/net;pure/selectors;pure/f srcdoc2: "deprecated/pure/ftpclient" srcdoc2: "pure/asyncfile;pure/asyncftpclient" srcdoc2: "pure/md5;pure/rationals" -srcdoc2: "posix/posix;pure/distros" +srcdoc2: "posix/posix;pure/distros;pure/oswalkdir" srcdoc2: "pure/fenv;pure/securehash;impure/rdstdin" srcdoc2: "pure/basic2d;pure/basic3d;pure/mersenne;pure/coro;pure/httpcore" From 009fcc9f84ee7ac790342d0d32fde4a5a38b8451 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 1 Nov 2017 00:55:42 +0100 Subject: [PATCH 05/23] make more tests green --- tests/float/tfloatnan.nim | 6 ------ tests/iter/tconcat.nim | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/float/tfloatnan.nim b/tests/float/tfloatnan.nim index 66cb8001d5..aa288d3423 100644 --- a/tests/float/tfloatnan.nim +++ b/tests/float/tfloatnan.nim @@ -2,21 +2,15 @@ discard """ file: "tfloatnan.nim" output: '''Nim: nan Nim: nan (float) -C: nan (float) Nim: nan (double) -C: nan (double) ''' """ -proc printf(formatstr: cstring): int {.importc: "printf", varargs, header: "".} - let f = NaN echo "Nim: ", f let f32: float32 = NaN echo "Nim: ", f32, " (float)" -discard printf("C: %f (float)\n", f32) let f64: float64 = NaN echo "Nim: ", f64, " (double)" -discard printf("C: %lf (double)\n", f64) diff --git a/tests/iter/tconcat.nim b/tests/iter/tconcat.nim index 94a89b57e5..477ac5e268 100644 --- a/tests/iter/tconcat.nim +++ b/tests/iter/tconcat.nim @@ -9,7 +9,7 @@ discard """ 23''' """ -proc toIter*[T](s: Slice[T, T]): iterator: T = +proc toIter*[T](s: Slice[T]): iterator: T = iterator it: T {.closure.} = for x in s.a..s.b: yield x From e09b2d898d45c5d5d717684d2499d71334b77eb3 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 1 Nov 2017 09:13:07 +0100 Subject: [PATCH 06/23] make tests green again --- tests/errmsgs/tshow_asgn.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/errmsgs/tshow_asgn.nim b/tests/errmsgs/tshow_asgn.nim index cdd325b939..250f786e21 100644 --- a/tests/errmsgs/tshow_asgn.nim +++ b/tests/errmsgs/tshow_asgn.nim @@ -7,7 +7,7 @@ discard """ # bug #5430 -proc random*[T](x: Slice[T, T]): T = +proc random*[T](x: Slice[T]): T = ## For a slice `a .. b` returns a value in the range `a .. b-1`. result = int(x.b - x.a) + x.a From d7b96f478bd24f75b093a05e52131cf754ab7cd4 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Wed, 1 Nov 2017 11:16:44 +0200 Subject: [PATCH 07/23] Fixed crash in case of ssl error in SSLShutdown (#6662) --- lib/pure/net.nim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 215a301b66..a405ce1bda 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -857,13 +857,16 @@ proc close*(socket: Socket) = # shutdown i.e not wait for the peers "close notify" alert with a second # call to SSLShutdown let res = SSLShutdown(socket.sslHandle) - SSLFree(socket.sslHandle) - socket.sslHandle = nil if res == 0: discard elif res != 1: socketError(socket, res) finally: + when defineSsl: + if socket.isSSL and socket.sslHandle != nil: + SSLFree(socket.sslHandle) + socket.sslHandle = nil + socket.fd.close() proc toCInt*(opt: SOBool): cint = From c4b9e683d23043f0de37359bb9dd9aaffbd45dfb Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 1 Nov 2017 11:17:43 +0100 Subject: [PATCH 08/23] system.nim improvements: make contains for HSlice more flexible; added .inline to the new BackwardsIndex accessors --- lib/system.nim | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 7e0ba46581..2bc10035af 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1167,7 +1167,7 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## is achieved by reversing the parameters for ``contains``; ``in`` then ## passes its arguments in reverse order. -proc contains*[T](s: HSlice[T, T], value: T): bool {.noSideEffect, inline.} = +proc contains*[U, V, W](s: HSlice[U, V], value: W): bool {.noSideEffect, inline.} = ## Checks if `value` is within the range of `s`; returns true iff ## `value >= s.a and value <= s.b` ## @@ -3527,20 +3527,21 @@ proc `[]=`*[T, U, V](s: var seq[T], x: HSlice[U, V], b: openArray[T]) = else: spliceImpl(s, a, L, b) -proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T = s[s.len - int(i)] -proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T = +proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} = s[s.len - int(i)] +proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} = a[Idx(a.len - int(i) + int low(a))] -proc `[]`*(s: string; i: BackwardsIndex): char = s[s.len - int(i)] +proc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)] -proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T = s[s.len - int(i)] -proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T = +proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} = + s[s.len - int(i)] +proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} = a[Idx(a.len - int(i) + int low(a))] -proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) = +proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} = s[s.len - int(i)] = x -proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) = +proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} = a[Idx(a.len - int(i) + int low(a))] = x -proc `[]=`*(s: var string; i: BackwardsIndex; x: char) = +proc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} = s[s.len - int(i)] = x proc slurp*(filename: string): string {.magic: "Slurp".} From f90df170e327ef49c2d2c8c18eda8cda995075f1 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 1 Nov 2017 11:53:09 +0100 Subject: [PATCH 09/23] system.nim improvement: make 'len' work with heterogenous slices --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index 2bc10035af..51db2ef662 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2089,7 +2089,7 @@ proc clamp*[T](x, a, b: T): T = if x > b: return b return x -proc len*[T: Ordinal](x: HSlice[T, T]): int {.noSideEffect, inline.} = +proc len*[U: Ordinal; V: Ordinal](x: HSlice[U, V]): int {.noSideEffect, inline.} = ## length of ordinal slice, when x.b < x.a returns zero length ## ## .. code-block:: Nim From e58eca8c057b0a683fe132774380c79eb1e4e33e Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 1 Nov 2017 14:11:16 +0100 Subject: [PATCH 10/23] system.'..<' should not be dirty; fixes yet another regression --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index 51db2ef662..710bf312fe 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3429,7 +3429,7 @@ template `..^`*(a, b: untyped): untyped = ## '..' and '^' is required. a .. ^b -template `..<`*(a, b: untyped): untyped {.dirty.} = +template `..<`*(a, b: untyped): untyped = ## a shortcut for 'a..pred(b)'. a .. pred(b) From eda9b303d2f7471a14a5a46ff3c100cc5357aa42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B8is=C3=A6ther=20Rasch?= Date: Wed, 1 Nov 2017 14:48:46 +0100 Subject: [PATCH 11/23] VCC always creates debug symbols when not in release (#6397) Use the `/Z7` option instead of `/Zi /FS` to store all debug info in the `.obj` file instead of a shared `.pdb` file --- config/nim.cfg | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/config/nim.cfg b/config/nim.cfg index 7ac87cc334..6ae55a9b2a 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -202,6 +202,11 @@ vcc.cpp.linkerexe = "vccexe.exe" # set the options for specific platforms: vcc.options.always = "/nologo" +@if release: + # no debug symbols in release builds +@else: + vcc.options.always %= "${vcc.options.always} /Z7" # Get VCC to output full debug symbols in the obj file +@end vcc.cpp.options.always %= "${vcc.options.always} /EHsc" vcc.options.linker = "/nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB vcc.cpp.options.linker %= "${vcc.options.linker}" @@ -222,8 +227,8 @@ vcc.options.linker %= "--platform:arm ${vcc.options.linker}" vcc.cpp.options.linker %= "--platform:arm ${vcc.cpp.options.linker}" @end -vcc.options.debug = "/Zi /FS /Od" -vcc.cpp.options.debug = "/Zi /FS /Od" +vcc.options.debug = "/Od" +vcc.cpp.options.debug = "/Od" vcc.options.speed = "/O2" vcc.cpp.options.speed = "/O2" vcc.options.size = "/O1" From 6f9cd35733211d04ba9ba6e7b7a5d32e5f3e5299 Mon Sep 17 00:00:00 2001 From: "Lynn C. Rees" Date: Wed, 1 Nov 2017 07:49:11 -0600 Subject: [PATCH 12/23] Add jsconsole to doc index (#6658) --- web/website.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/website.ini b/web/website.ini index 5576728b56..395418a076 100644 --- a/web/website.ini +++ b/web/website.ini @@ -44,7 +44,7 @@ srcdoc2: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib;pure/strscan srcdoc2: "pure/parseopt;pure/parseopt2;pure/hashes;pure/strtabs;pure/lexbase" srcdoc2: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql" srcdoc2: "pure/streams;pure/terminal;pure/cgi;pure/unicode;pure/strmisc" -srcdoc2: "pure/htmlgen;pure/parseutils;pure/browsers" +srcdoc2: "pure/htmlgen;pure/parseutils;pure/browsers;js/jsconsole" srcdoc2: "impure/db_postgres;impure/db_mysql;impure/db_sqlite;pure/db_common" srcdoc2: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl" srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser" From 286f89528028fc3ae9e441a18be2be11cf499174 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 1 Nov 2017 15:33:20 +0100 Subject: [PATCH 13/23] make range type checking more restrictive, see tn8vsint16 test case; minor breaking change --- compiler/sigmatch.nim | 11 ++++++++++- tests/range/tn8vsint16.nim | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/range/tn8vsint16.nim diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 1494c5316d..231dd80f47 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -390,7 +390,16 @@ proc isConvertibleToRange(f, a: PType): bool = # be less picky for tyRange, as that it is used for array indexing: if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}: - result = true + case f.kind + of tyInt, tyInt64: result = true + of tyInt8: result = a.kind in {tyInt8, tyInt} + of tyInt16: result = a.kind in {tyInt8, tyInt16, tyInt} + of tyInt32: result = a.kind in {tyInt8, tyInt16, tyInt32, tyInt} + of tyUInt, tyUInt64: result = true + of tyUInt8: result = a.kind in {tyUInt8, tyUInt} + of tyUInt16: result = a.kind in {tyUInt8, tyUInt16, tyUInt} + of tyUInt32: result = a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt} + else: result = false elif f.kind in {tyFloat..tyFloat128} and a.kind in {tyFloat..tyFloat128}: result = true diff --git a/tests/range/tn8vsint16.nim b/tests/range/tn8vsint16.nim new file mode 100644 index 0000000000..612b6d0e7d --- /dev/null +++ b/tests/range/tn8vsint16.nim @@ -0,0 +1,18 @@ +discard """ + output: '''9''' +""" + +type + n32 = range[0..high(int)] + n8* = range[0'i8..high(int8)] + +proc `+`*(a: n32, b: n32{nkIntLit}): n32 = discard + +proc `-`*(a: n8, b: n8): n8 = n8(system.`-`(a, b)) + +var x, y: n8 +var z: int16 + +# ensure this doesn't call our '-' but system.`-` for int16: +echo z - n8(9) + From da6fe6ffd982ee1e7af6d773f0ed73febad83965 Mon Sep 17 00:00:00 2001 From: Daniil Yarancev <21169548+Yardanico@users.noreply.github.com> Date: Wed, 1 Nov 2017 18:13:27 +0300 Subject: [PATCH 14/23] Fix typo in new test --- tests/range/tn8vsint16.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/range/tn8vsint16.nim b/tests/range/tn8vsint16.nim index 612b6d0e7d..bf4f78e3ba 100644 --- a/tests/range/tn8vsint16.nim +++ b/tests/range/tn8vsint16.nim @@ -1,5 +1,5 @@ discard """ - output: '''9''' + output: '''-9''' """ type From 95ec32d12417fb58d1116dc443a3c9d5fc2f79a4 Mon Sep 17 00:00:00 2001 From: Simon Krauter Date: Wed, 1 Nov 2017 17:06:17 +0100 Subject: [PATCH 15/23] Extend description of fmWrite Add "Existing files will be cleared!" like in fmReadWriteExisting. Behavior tested under Linux. --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index 710bf312fe..92c5e009f9 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2835,7 +2835,7 @@ when not defined(JS): #and not defined(nimscript): fmRead, ## Open the file for read access only. fmWrite, ## Open the file for write access only. ## If the file does not exist, it will be - ## created. + ## created. Existing files will be cleared! fmReadWrite, ## Open the file for read and write access. ## If the file does not exist, it will be ## created. Existing files will be cleared! From db67ee940d7cc48cffee3e9f4deac8de5cf4038c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sch=C3=BCrrle?= Date: Wed, 1 Nov 2017 17:14:01 +0100 Subject: [PATCH 16/23] Fixed small typo in parseopt2.nim comment --- lib/pure/parseopt2.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim index 2e8dbe1402..a2ff9bf0c0 100644 --- a/lib/pure/parseopt2.nim +++ b/lib/pure/parseopt2.nim @@ -35,7 +35,7 @@ type cmd: seq[string] pos: int remainingShortOptions: string - kind*: CmdLineKind ## the dected command line token + kind*: CmdLineKind ## the detected command line token key*, val*: TaintedString ## key and value pair; ``key`` is the option ## or the argument, ``value`` is not "" if ## the option was given a value From bd19b5f4d36bb40b4af93d7e15fdfa582e9fe3b7 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 2 Nov 2017 10:42:11 +0100 Subject: [PATCH 17/23] implemented undocumented '.liftLocals' feature --- compiler/lowerings.nim | 6 ++++-- compiler/pragmas.nim | 11 ++++++++++- compiler/transf.nim | 3 ++- compiler/wordrecg.nim | 4 ++-- tests/fields/timplicitfieldswithpartial.nim | 18 +++++++++++++++++- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 787216bb32..9612ff0aba 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -182,8 +182,9 @@ proc addField*(obj: PType; s: PSym) = field.position = sonsLen(obj.n) addSon(obj.n, newSymNode(field)) -proc addUniqueField*(obj: PType; s: PSym) = - if lookupInRecord(obj.n, s.id) == nil: +proc addUniqueField*(obj: PType; s: PSym): PSym {.discardable.} = + result = lookupInRecord(obj.n, s.id) + if result == nil: var field = newSym(skField, getIdent(s.name.s & $obj.n.len), s.owner, s.info) field.id = -s.id let t = skipIntLit(s.typ) @@ -191,6 +192,7 @@ proc addUniqueField*(obj: PType; s: PSym) = assert t.kind != tyStmt field.position = sonsLen(obj.n) addSon(obj.n, newSymNode(field)) + result = field proc newDotExpr(obj, b: PSym): PNode = result = newNodeI(nkDotExpr, obj.info) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index c279e088c0..5acfbc9192 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -25,7 +25,7 @@ const wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl, wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe, - wOverride, wConstructor, wExportNims, wUsed} + wOverride, wConstructor, wExportNims, wUsed, wLiftLocals} converterPragmas* = procPragmas methodPragmas* = procPragmas+{wBase}-{wImportCpp} templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty, @@ -70,6 +70,14 @@ const wThread, wRaises, wLocks, wTags, wGcSafe} allRoutinePragmas* = methodPragmas + iteratorPragmas + lambdaPragmas +proc getPragmaVal*(procAst: PNode; name: TSpecialWord): PNode = + let p = procAst[pragmasPos] + if p.kind == nkEmpty: return nil + for it in p: + if it.kind == nkExprColonExpr and it[0].kind == nkIdent and + it[0].ident.id == ord(name): + return it[1] + proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) # implementation @@ -978,6 +986,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, noVal(it) if sym == nil: invalidPragma(it) else: sym.flags.incl sfUsed + of wLiftLocals: discard else: invalidPragma(it) else: invalidPragma(it) diff --git a/compiler/transf.nim b/compiler/transf.nim index 9c947fc1ed..c3bdd4ddc7 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -21,7 +21,7 @@ import intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os, idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread, - lambdalifting, sempass2, lowerings, lookups, destroyer + lambdalifting, sempass2, lowerings, lookups, destroyer, liftlocals type PTransNode* = distinct PNode @@ -978,6 +978,7 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode = liftDefer(c, result) #result = liftLambdas(prc, result) when useEffectSystem: trackProc(prc, result) + liftLocalsIfRequested(prc) if c.needsDestroyPass and newDestructors: result = injectDestructorCalls(prc, result) incl(result.flags, nfTransf) diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 19e182942a..f5ba35dfb0 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -66,7 +66,7 @@ type wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, wAsmNoStackFrame, wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks, - wPartial, wExplain, + wPartial, wExplain, wLiftLocals, wAuto, wBool, wCatch, wChar, wClass, wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast, @@ -152,7 +152,7 @@ const "computedgoto", "injectstmt", "experimental", "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit", "asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked", - "guard", "locks", "partial", "explain", + "guard", "locks", "partial", "explain", "liftlocals", "auto", "bool", "catch", "char", "class", "const_cast", "default", "delete", "double", diff --git a/tests/fields/timplicitfieldswithpartial.nim b/tests/fields/timplicitfieldswithpartial.nim index 996912a1ad..a315cc5d0b 100644 --- a/tests/fields/timplicitfieldswithpartial.nim +++ b/tests/fields/timplicitfieldswithpartial.nim @@ -1,6 +1,8 @@ discard """ output: '''(foo: 38, other: string here) -43''' +43 +100 +90''' """ type @@ -17,3 +19,17 @@ proc my(f: Foo) = var g: Foo new(g) my(g) + +type + FooTask {.partial.} = ref object of RootObj + +proc foo(t: FooTask) {.liftLocals: t.} = + var x = 90 + if true: + var x = 10 + while x < 100: + inc x + echo x + echo x + +foo(FooTask()) From 1ec0686d044b5bcf2153f594bb03860a8e13d8db Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 2 Nov 2017 10:54:23 +0100 Subject: [PATCH 18/23] added missing file --- compiler/liftlocals.nim | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 compiler/liftlocals.nim diff --git a/compiler/liftlocals.nim b/compiler/liftlocals.nim new file mode 100644 index 0000000000..f29a4e106e --- /dev/null +++ b/compiler/liftlocals.nim @@ -0,0 +1,68 @@ +# +# +# The Nim Compiler +# (c) Copyright 2015 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements the '.liftLocals' pragma. + +import + intsets, strutils, options, ast, astalgo, msgs, + idents, renderer, types, lowerings + +from pragmas import getPragmaVal +from wordrecg import wLiftLocals + +type + Ctx = object + partialParam: PSym + objType: PType + +proc interestingVar(s: PSym): bool {.inline.} = + result = s.kind in {skVar, skLet, skTemp, skForVar, skResult} and + sfGlobal notin s.flags + +proc lookupOrAdd(c: var Ctx; s: PSym; info: TLineInfo): PNode = + let field = addUniqueField(c.objType, s) + var deref = newNodeI(nkHiddenDeref, info) + deref.typ = c.objType + add(deref, newSymNode(c.partialParam, info)) + result = newNodeI(nkDotExpr, info) + add(result, deref) + add(result, newSymNode(field)) + result.typ = field.typ + +proc liftLocals(n: PNode; i: int; c: var Ctx) = + let it = n[i] + case it.kind + of nkSym: + if interestingVar(it.sym): + n[i] = lookupOrAdd(c, it.sym, it.info) + of procDefs, nkTypeSection: discard + else: + for i in 0 ..< it.safeLen: + liftLocals(it, i, c) + +proc lookupParam(params, dest: PNode): PSym = + if dest.kind != nkIdent: return nil + for i in 1 ..< params.len: + if params[i].kind == nkSym and params[i].sym.name.id == dest.ident.id: + return params[i].sym + +proc liftLocalsIfRequested*(prc: PSym) = + let liftDest = getPragmaVal(prc.ast, wLiftLocals) + if liftDest == nil: return + let partialParam = lookupParam(prc.typ.n, liftDest) + if partialParam.isNil: + localError(liftDest.info, "'$1' is not a parameter of '$2'" % + [$liftDest, prc.name.s]) + return + let objType = partialParam.typ.skipTypes(abstractPtrs) + if objType.kind != tyObject or tfPartial notin objType.flags: + localError(liftDest.info, "parameter '$1' is not a pointer to a partial object" % $liftDest) + return + var c = Ctx(partialParam: partialParam, objType: objType) + liftLocals(prc.ast, bodyPos, c) From b7bce6f9001c2ef95915c87b5cc42967ce3c648c Mon Sep 17 00:00:00 2001 From: "Lynn C. Rees" Date: Thu, 2 Nov 2017 04:55:45 -0600 Subject: [PATCH 19/23] Link unlinked stdlib modules to doc index (#6672) --- web/website.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/web/website.ini b/web/website.ini index 395418a076..3274b0b6cb 100644 --- a/web/website.ini +++ b/web/website.ini @@ -65,6 +65,7 @@ srcdoc2: "pure/md5;pure/rationals" srcdoc2: "posix/posix;pure/distros;pure/oswalkdir" srcdoc2: "pure/fenv;pure/securehash;impure/rdstdin" srcdoc2: "pure/basic2d;pure/basic3d;pure/mersenne;pure/coro;pure/httpcore" +srcdoc2: "pure/bitops;pure/nimtracker;pure/punycode;pure/volatile" ; Note: everything under 'webdoc' doesn't get listed in the index, so wrappers ; should live here From 762ade11778e8e7152bdcd0866633d022d81250d Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 2 Nov 2017 18:23:10 +0100 Subject: [PATCH 20/23] 'ord' does not produce a range type anymore --- compiler/condsyms.nim | 1 + compiler/semmagic.nim | 4 +++- lib/pure/times.nim | 4 ++-- lib/system/sysio.nim | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 02c31163ae..2050a746b4 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -109,3 +109,4 @@ proc initDefines*() = defineSymbol("nimGenericInOutFlags") when false: defineSymbol("nimHasOpt") defineSymbol("nimNoArrayToCstringConversion") + defineSymbol("nimNewRoof") diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index d721f42abd..0803b99ece 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -168,7 +168,9 @@ proc semTypeTraits(c: PContext, n: PNode): PNode = proc semOrd(c: PContext, n: PNode): PNode = result = n let parType = n.sons[1].typ - if isOrdinalType(parType) or parType.kind == tySet: + if isOrdinalType(parType): + discard + elif parType.kind == tySet: result.typ = makeRangeType(c, firstOrd(parType), lastOrd(parType), n.info) else: localError(n.info, errOrdinalTypeExpected) diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 7dd4289048..c1d6c3e530 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -224,7 +224,7 @@ proc `-`*(a, b: Time): int64 {. ## let a = fromSeconds(1_000_000_000) ## let b = fromSeconds(1_500_000_000) ## echo initInterval(seconds=int(b - a)) - ## # (milliseconds: 0, seconds: 20, minutes: 53, hours: 0, days: 5787, months: 0, years: 0) + ## # (milliseconds: 0, seconds: 20, minutes: 53, hours: 0, days: 5787, months: 0, years: 0) proc `<`*(a, b: Time): bool {. rtl, extern: "ntLtTime", tags: [], raises: [], noSideEffect.} = @@ -1225,7 +1225,7 @@ when not defined(JS): result.minute = t.minute result.hour = t.hour result.monthday = t.monthday - result.month = ord(t.month) + result.month = cint(t.month) result.year = cint(t.year - 1900) result.weekday = weekDays[t.weekday] result.yearday = t.yearday diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index a40fcc67d4..4348ffbb50 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -192,7 +192,7 @@ proc write(f: File, r: float32) = proc write(f: File, r: BiggestFloat) = if c_fprintf(f, "%g", r) < 0: checkErr(f) -proc write(f: File, c: char) = discard c_putc(ord(c), f) +proc write(f: File, c: char) = discard c_putc(cint(c), f) proc write(f: File, a: varargs[string, `$`]) = for x in items(a): write(f, x) From 0a38cd654381c90f2f62548a1fe6fe7c9528de5b Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 2 Nov 2017 19:07:00 +0100 Subject: [PATCH 21/23] make tests green again --- lib/deprecated/pure/sockets.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/deprecated/pure/sockets.nim b/lib/deprecated/pure/sockets.nim index 153db9ed86..f068c7d560 100644 --- a/lib/deprecated/pure/sockets.nim +++ b/lib/deprecated/pure/sockets.nim @@ -262,7 +262,7 @@ proc socket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, # TODO: Perhaps this should just raise EOS when an error occurs. when defined(Windows): - result = newTSocket(winlean.socket(ord(domain), ord(typ), ord(protocol)), buffered) + result = newTSocket(winlean.socket(cint(domain), cint(typ), cint(protocol)), buffered) else: result = newTSocket(posix.socket(toInt(domain), toInt(typ), toInt(protocol)), buffered) From cccdd9b58ef35f13c74abfd10cfd416a8f70061b Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 2 Nov 2017 20:39:08 +0100 Subject: [PATCH 22/23] fixes new liftLocals pass --- compiler/liftlocals.nim | 12 +++++++----- compiler/transf.nim | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/liftlocals.nim b/compiler/liftlocals.nim index f29a4e106e..3610a14862 100644 --- a/compiler/liftlocals.nim +++ b/compiler/liftlocals.nim @@ -52,17 +52,19 @@ proc lookupParam(params, dest: PNode): PSym = if params[i].kind == nkSym and params[i].sym.name.id == dest.ident.id: return params[i].sym -proc liftLocalsIfRequested*(prc: PSym) = +proc liftLocalsIfRequested*(prc: PSym; n: PNode): PNode = let liftDest = getPragmaVal(prc.ast, wLiftLocals) - if liftDest == nil: return + if liftDest == nil: return n let partialParam = lookupParam(prc.typ.n, liftDest) if partialParam.isNil: localError(liftDest.info, "'$1' is not a parameter of '$2'" % [$liftDest, prc.name.s]) - return + return n let objType = partialParam.typ.skipTypes(abstractPtrs) if objType.kind != tyObject or tfPartial notin objType.flags: localError(liftDest.info, "parameter '$1' is not a pointer to a partial object" % $liftDest) - return + return n var c = Ctx(partialParam: partialParam, objType: objType) - liftLocals(prc.ast, bodyPos, c) + let w = newTree(nkStmtList, n) + liftLocals(w, 0, c) + result = w[0] diff --git a/compiler/transf.nim b/compiler/transf.nim index c3bdd4ddc7..baf801cbf1 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -978,7 +978,7 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode = liftDefer(c, result) #result = liftLambdas(prc, result) when useEffectSystem: trackProc(prc, result) - liftLocalsIfRequested(prc) + result = liftLocalsIfRequested(prc, result) if c.needsDestroyPass and newDestructors: result = injectDestructorCalls(prc, result) incl(result.flags, nfTransf) From 0f5261e9711c3fd57241874963bd5e45b11ed65e Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 2 Nov 2017 22:09:58 +0100 Subject: [PATCH 23/23] fixes #6675 --- lib/system.nim | 4 ++-- tests/array/troof1.nim | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 92c5e009f9..0cae4da87f 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3493,14 +3493,14 @@ proc `[]`*[Idx, T, U, V](a: array[Idx, T], x: HSlice[U, V]): seq[T] = let xa = a ^^ x.a let L = (a ^^ x.b) - xa + 1 result = newSeq[T](L) - for i in 0..