From a2b2bc1a36a8526fa33e013057a65ae1b7d86b79 Mon Sep 17 00:00:00 2001
From: Tomohiro
Date: Mon, 2 Jul 2018 07:46:56 +0900
Subject: [PATCH 1/8] Fixed #8173 (#8175)
---
lib/pure/ospaths.nim | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/pure/ospaths.nim b/lib/pure/ospaths.nim
index 905a659255..d9097d4192 100644
--- a/lib/pure/ospaths.nim
+++ b/lib/pure/ospaths.nim
@@ -449,6 +449,9 @@ proc unixToNativePath*(path: string, drive=""): string {.
when defined(unix):
result = path
else:
+ if path.len == 0:
+ return ""
+
var start: int
if path[0] == '/':
# an absolute path
@@ -462,7 +465,7 @@ proc unixToNativePath*(path: string, drive=""): string {.
else:
result = $DirSep
start = 1
- elif path[0] == '.' and path[1] == '/':
+ elif path[0] == '.' and (path.len == 1 or path[1] == '/'):
# current directory
result = $CurDir
start = 2
From 2c98b4943efb48cec01a63154bdf2cfb9da61714 Mon Sep 17 00:00:00 2001
From: LemonBoy
Date: Mon, 2 Jul 2018 00:49:03 +0200
Subject: [PATCH 2/8] Fix crash with static and anonymous procs (#8171)
Fixes #6077
---
compiler/semtypes.nim | 2 +-
tests/statictypes/tstatictypes.nim | 9 +++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index dfd4247054..17420111f1 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -873,7 +873,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
if base.isMetaType and procKind == skMacro:
localError(c.config, info, errMacroBodyDependsOnGenericTypes % paramName)
result = addImplicitGeneric(c.newTypeWithSons(tyStatic, @[base]))
- result.flags.incl({tfHasStatic, tfUnresolved})
+ if result != nil: result.flags.incl({tfHasStatic, tfUnresolved})
of tyTypeDesc:
if tfUnresolved notin paramType.flags:
diff --git a/tests/statictypes/tstatictypes.nim b/tests/statictypes/tstatictypes.nim
index 789bd75886..2a3b7332df 100644
--- a/tests/statictypes/tstatictypes.nim
+++ b/tests/statictypes/tstatictypes.nim
@@ -107,3 +107,12 @@ when true:
assert aw2.data.high == 6
assert aw3.data.high == 9
+# #6077
+block:
+ type
+ Backend = enum
+ Cpu
+
+ Tensor[B: static[Backend]; T] = object
+
+ BackProp[B: static[Backend],T] = proc (gradient: Tensor[B,T]): Tensor[B,T]
From c79f488027239d1a43582cc52f0688b23cf504fb Mon Sep 17 00:00:00 2001
From: Tomohiro
Date: Tue, 3 Jul 2018 00:14:26 +0900
Subject: [PATCH 3/8] Fix os.unixToNativePath proc returns wrong result(#8179)
(#8181)
* Fix os.unixToNativePath proc returns wrong result(#8179)
* Add tests for unixToNativePath
---
lib/pure/ospaths.nim | 2 +-
tests/stdlib/tospaths.nim | 41 +++++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 tests/stdlib/tospaths.nim
diff --git a/lib/pure/ospaths.nim b/lib/pure/ospaths.nim
index d9097d4192..96996bba7c 100644
--- a/lib/pure/ospaths.nim
+++ b/lib/pure/ospaths.nim
@@ -468,7 +468,7 @@ proc unixToNativePath*(path: string, drive=""): string {.
elif path[0] == '.' and (path.len == 1 or path[1] == '/'):
# current directory
result = $CurDir
- start = 2
+ start = when doslikeFileSystem: 1 else: 2
else:
result = ""
start = 0
diff --git a/tests/stdlib/tospaths.nim b/tests/stdlib/tospaths.nim
new file mode 100644
index 0000000000..0ac7729d92
--- /dev/null
+++ b/tests/stdlib/tospaths.nim
@@ -0,0 +1,41 @@
+discard """
+ file: "tospaths.nim"
+ output: ""
+"""
+# test the ospaths module
+
+import os
+
+doAssert unixToNativePath("") == ""
+doAssert unixToNativePath(".") == $CurDir
+doAssert unixToNativePath("..") == $ParDir
+doAssert isAbsolute(unixToNativePath("/"))
+doAssert isAbsolute(unixToNativePath("/", "a"))
+doAssert isAbsolute(unixToNativePath("/a"))
+doAssert isAbsolute(unixToNativePath("/a", "a"))
+doAssert isAbsolute(unixToNativePath("/a/b"))
+doAssert isAbsolute(unixToNativePath("/a/b", "a"))
+doAssert unixToNativePath("a/b") == joinPath("a", "b")
+
+when defined(macos):
+ doAssert unixToNativePath("./") == ":"
+ doAssert unixToNativePath("./abc") == ":abc"
+ doAssert unixToNativePath("../abc") == "::abc"
+ doAssert unixToNativePath("../../abc") == ":::abc"
+ doAssert unixToNativePath("/abc", "a") == "abc"
+ doAssert unixToNativePath("/abc/def", "a") == "abc:def"
+elif doslikeFileSystem:
+ doAssert unixToNativePath("./") == ".\\"
+ doAssert unixToNativePath("./abc") == ".\\abc"
+ doAssert unixToNativePath("../abc") == "..\\abc"
+ doAssert unixToNativePath("../../abc") == "..\\..\\abc"
+ doAssert unixToNativePath("/abc", "a") == "a:\\abc"
+ doAssert unixToNativePath("/abc/def", "a") == "a:\\abc\\def"
+else:
+ #Tests for unix
+ doAssert unixToNativePath("./") == "./"
+ doAssert unixToNativePath("./abc") == "./abc"
+ doAssert unixToNativePath("../abc") == "../abc"
+ doAssert unixToNativePath("../../abc") == "../../abc"
+ doAssert unixToNativePath("/abc", "a") == "/abc"
+ doAssert unixToNativePath("/abc/def", "a") == "/abc/def"
From e63369f2b9ea7b0e714c12d187d7c9671caf828a Mon Sep 17 00:00:00 2001
From: zargot
Date: Mon, 2 Jul 2018 18:07:24 +0200
Subject: [PATCH 4/8] asyncftpclient: add missing file.close to retrFile
---
lib/pure/asyncftpclient.nim | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/pure/asyncftpclient.nim b/lib/pure/asyncftpclient.nim
index 019a18f553..3d6a9a015a 100644
--- a/lib/pure/asyncftpclient.nim
+++ b/lib/pure/asyncftpclient.nim
@@ -304,6 +304,7 @@ proc retrFile*(ftp: AsyncFtpClient, file, dest: string,
raise newException(ReplyError, "Reply has no file size.")
await getFile(ftp, destFile, fileSize, onProgressChanged)
+ destFile.close()
proc doUpload(ftp: AsyncFtpClient, file: File,
onProgressChanged: ProgressChangedProc) {.async.} =
From 70cf286a220940b86b8f8e5b7209ac55981cf8a8 Mon Sep 17 00:00:00 2001
From: genotrance
Date: Mon, 2 Jul 2018 15:53:00 -0500
Subject: [PATCH 5/8] Test case for #6281 (#8190)
---
tests/errmsgs/t6281.nim | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 tests/errmsgs/t6281.nim
diff --git a/tests/errmsgs/t6281.nim b/tests/errmsgs/t6281.nim
new file mode 100644
index 0000000000..59fda50776
--- /dev/null
+++ b/tests/errmsgs/t6281.nim
@@ -0,0 +1,9 @@
+discard """
+errormsg: "invalid type: 'SomeNumber' in this context: 'seq[SomeNumber]' for var"
+line: 6
+"""
+
+var seqwat: seq[SomeNumber] = @[]
+
+proc foo(x: SomeNumber) =
+ seqwat.add(x)
\ No newline at end of file
From 681d8e0749fd4374c3cc904ef27a5f600f3c4bb5 Mon Sep 17 00:00:00 2001
From: Vindaar
Date: Tue, 3 Jul 2018 01:56:36 +0200
Subject: [PATCH 6/8] Deprecate 'c', 'C' prefix for octal literals, fixes #8082
(#8178)
* deprecate `0c`, `0C` prefix for octal literals
Deprecates the previously allowed syntax of `0c` and `0C` as a prefix for
octal literals to bring the literals in line with the behavior of
`parseOct` from parseutils.
* add `msgKind` arg to `lexMessageLitNum` for deprecation messages
* change literal tests to check all valid integer literals
Also adds the `tinvaligintegerlit3` test to test for the (still)
invalid `0O` prefix.
---
changelog.md | 2 ++
compiler/lexer.nim | 27 ++++++++++++-----
doc/manual.rst | 4 +--
lib/posix/posix.nim | 40 ++++++++++++-------------
tests/lexer/tintegerliterals.nim | 9 ++++++
tests/lexer/tinvalidintegerliteral3.nim | 7 +++++
tests/misc/tunsignedmisc.nim | 6 ++--
7 files changed, 62 insertions(+), 33 deletions(-)
create mode 100644 tests/lexer/tintegerliterals.nim
create mode 100644 tests/lexer/tinvalidintegerliteral3.nim
diff --git a/changelog.md b/changelog.md
index bbe5261249..0943d78364 100644
--- a/changelog.md
+++ b/changelog.md
@@ -20,6 +20,8 @@
- The parser now warns about inconsistent spacing around binary operators as
these can easily be confused with unary operators. This warning will likely
become an error in the future.
+- The ``'c`` and ``'C'`` prefix for octal literals is now deprecated to
+ bring the language in line with the standard library (e.g. ``parseOct``).
#### Breaking changes in the standard library
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index 375bf227dd..9727d16a7e 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -359,9 +359,8 @@ proc getNumber(L: var TLexer, result: var TToken) =
inc(pos)
L.bufpos = pos
- proc lexMessageLitNum(L: var TLexer, msg: string, startpos: int) =
+ proc lexMessageLitNum(L: var TLexer, msg: string, startpos: int, msgKind = errGenerated) =
# Used to get slightly human friendlier err messages.
- # Note: the erroneous 'O' char in the character set is intentional
const literalishChars = {'A'..'F', 'a'..'f', '0'..'9', 'X', 'x', 'o', 'O',
'c', 'C', 'b', 'B', '_', '.', '\'', 'd', 'i', 'u'}
var msgPos = L.bufpos
@@ -380,7 +379,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
add(t.literal, L.buf[L.bufpos])
matchChars(L, t, {'0'..'9'})
L.bufpos = msgPos
- lexMessage(L, errGenerated, msg % t.literal)
+ lexMessage(L, msgKind, msg % t.literal)
var
startpos, endpos: int
@@ -388,7 +387,8 @@ proc getNumber(L: var TLexer, result: var TToken) =
isBase10 = true
numDigits = 0
const
- baseCodeChars = {'X', 'x', 'o', 'c', 'C', 'b', 'B'}
+ # 'c', 'C' is deprecated
+ baseCodeChars = {'X', 'x', 'o', 'b', 'B', 'c', 'C'}
literalishChars = baseCodeChars + {'A'..'F', 'a'..'f', '0'..'9', '_', '\''}
floatTypes = {tkFloatLit, tkFloat32Lit, tkFloat64Lit, tkFloat128Lit}
result.tokType = tkIntLit # int literal until we know better
@@ -398,17 +398,27 @@ proc getNumber(L: var TLexer, result: var TToken) =
tokenBegin(result, startPos)
# First stage: find out base, make verifications, build token literal string
- if L.buf[L.bufpos] == '0' and L.buf[L.bufpos + 1] in baseCodeChars + {'O'}:
+ # {'c', 'C'} is added for deprecation reasons to provide a clear error message
+ if L.buf[L.bufpos] == '0' and L.buf[L.bufpos + 1] in baseCodeChars + {'c', 'C', 'O'}:
isBase10 = false
eatChar(L, result, '0')
case L.buf[L.bufpos]
+ of 'c', 'C':
+ lexMessageLitNum(L,
+ "$1 will soon be invalid for oct literals; Use '0o' " &
+ "for octals. 'c', 'C' prefix",
+ startpos,
+ warnDeprecated)
+ eatChar(L, result, 'c')
+ numDigits = matchUnderscoreChars(L, result, {'0'..'7'})
of 'O':
- lexMessageLitNum(L, "$1 is not a valid number; did you mean octal? Then use one of '0o', '0c' or '0C'.", startpos)
+ lexMessageLitNum(L, "$1 is an invalid int literal; For octal literals " &
+ "use the '0o' prefix.", startpos)
of 'x', 'X':
eatChar(L, result, 'x')
numDigits = matchUnderscoreChars(L, result, {'0'..'9', 'a'..'f', 'A'..'F'})
- of 'o', 'c', 'C':
- eatChar(L, result, 'c')
+ of 'o':
+ eatChar(L, result, 'o')
numDigits = matchUnderscoreChars(L, result, {'0'..'7'})
of 'b', 'B':
eatChar(L, result, 'b')
@@ -511,6 +521,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
if L.buf[pos] != '_':
xi = `shl`(xi, 1) or (ord(L.buf[pos]) - ord('0'))
inc(pos)
+ # 'c', 'C' is deprecated
of 'o', 'c', 'C':
result.base = base8
while pos < endpos:
diff --git a/doc/manual.rst b/doc/manual.rst
index 28fbfb1990..5ca6da22e1 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -413,7 +413,7 @@ Numerical constants are of a single type and have the form::
bindigit = '0'..'1'
HEX_LIT = '0' ('x' | 'X' ) hexdigit ( ['_'] hexdigit )*
DEC_LIT = digit ( ['_'] digit )*
- OCT_LIT = '0' ('o' | 'c' | 'C') octdigit ( ['_'] octdigit )*
+ OCT_LIT = '0' 'o' octdigit ( ['_'] octdigit )*
BIN_LIT = '0' ('b' | 'B' ) bindigit ( ['_'] bindigit )*
INT_LIT = HEX_LIT
@@ -444,7 +444,7 @@ Numerical constants are of a single type and have the form::
As can be seen in the productions, numerical constants can contain underscores
for readability. Integer and floating point literals may be given in decimal (no
-prefix), binary (prefix ``0b``), octal (prefix ``0o`` or ``0c``) and hexadecimal
+prefix), binary (prefix ``0b``), octal (prefix ``0o``) and hexadecimal
(prefix ``0x``) notation.
There exists a literal for each numerical type that is
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index 97b4124ec4..c230e65985 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -36,26 +36,26 @@
# platforms - where do they come from and why are they here?
when false:
const
- C_IRUSR = 0c000400 ## Read by owner.
- C_IWUSR = 0c000200 ## Write by owner.
- C_IXUSR = 0c000100 ## Execute by owner.
- C_IRGRP = 0c000040 ## Read by group.
- C_IWGRP = 0c000020 ## Write by group.
- C_IXGRP = 0c000010 ## Execute by group.
- C_IROTH = 0c000004 ## Read by others.
- C_IWOTH = 0c000002 ## Write by others.
- C_IXOTH = 0c000001 ## Execute by others.
- C_ISUID = 0c004000 ## Set user ID.
- C_ISGID = 0c002000 ## Set group ID.
- C_ISVTX = 0c001000 ## On directories, restricted deletion flag.
- C_ISDIR = 0c040000 ## Directory.
- C_ISFIFO = 0c010000 ##FIFO.
- C_ISREG = 0c100000 ## Regular file.
- C_ISBLK = 0c060000 ## Block special.
- C_ISCHR = 0c020000 ## Character special.
- C_ISCTG = 0c110000 ## Reserved.
- C_ISLNK = 0c120000 ## Symbolic link.
- C_ISSOCK = 0c140000 ## Socket.
+ C_IRUSR = 0o000400 ## Read by owner.
+ C_IWUSR = 0o000200 ## Write by owner.
+ C_IXUSR = 0o000100 ## Execute by owner.
+ C_IRGRP = 0o000040 ## Read by group.
+ C_IWGRP = 0o000020 ## Write by group.
+ C_IXGRP = 0o000010 ## Execute by group.
+ C_IROTH = 0o000004 ## Read by others.
+ C_IWOTH = 0o000002 ## Write by others.
+ C_IXOTH = 0o000001 ## Execute by others.
+ C_ISUID = 0o004000 ## Set user ID.
+ C_ISGID = 0o002000 ## Set group ID.
+ C_ISVTX = 0o001000 ## On directories, restricted deletion flag.
+ C_ISDIR = 0o040000 ## Directory.
+ C_ISFIFO = 0o010000 ##FIFO.
+ C_ISREG = 0o100000 ## Regular file.
+ C_ISBLK = 0o060000 ## Block special.
+ C_ISCHR = 0o020000 ## Character special.
+ C_ISCTG = 0o110000 ## Reserved.
+ C_ISLNK = 0o120000 ## Symbolic link.
+ C_ISSOCK = 0o140000 ## Socket.
const
MM_NULLLBL* = nil
diff --git a/tests/lexer/tintegerliterals.nim b/tests/lexer/tintegerliterals.nim
new file mode 100644
index 0000000000..7420db144d
--- /dev/null
+++ b/tests/lexer/tintegerliterals.nim
@@ -0,0 +1,9 @@
+# test the valid literals
+assert 0b10 == 2
+assert 0B10 == 2
+assert 0x10 == 16
+assert 0X10 == 16
+assert 0o10 == 8
+# the following is deprecated:
+assert 0c10 == 8
+assert 0C10 == 8
diff --git a/tests/lexer/tinvalidintegerliteral3.nim b/tests/lexer/tinvalidintegerliteral3.nim
new file mode 100644
index 0000000000..9c2fe69df5
--- /dev/null
+++ b/tests/lexer/tinvalidintegerliteral3.nim
@@ -0,0 +1,7 @@
+discard """
+ file: "tinvalidintegerliteral3.nim"
+ line: 7
+ errormsg: "0O5 is an invalid int literal; For octal literals use the '0o' prefix."
+"""
+
+echo 0O5
diff --git a/tests/misc/tunsignedmisc.nim b/tests/misc/tunsignedmisc.nim
index fc02eee195..b2a3849cf6 100644
--- a/tests/misc/tunsignedmisc.nim
+++ b/tests/misc/tunsignedmisc.nim
@@ -9,7 +9,7 @@ discard """
# 8 bit
let ref1 = 128'u8 shr 7
let hex1 = 0x80'u8 shr 7
-let oct1 = 0c200'u8 shr 7
+let oct1 = 0o200'u8 shr 7
let dig1 = 0b10000000'u8 shr 7
doAssert(ref1 == 1)
@@ -20,7 +20,7 @@ doAssert(ref1 == dig1)
# 16 bit
let ref2 = 32768'u16 shr 15
let hex2 = 0x8000'u16 shr 15
-let oct2 = 0c100000'u16 shr 15
+let oct2 = 0o100000'u16 shr 15
let dig2 = 0b1000000000000000'u16 shr 15
doAssert(ref2 == 1)
@@ -31,7 +31,7 @@ doAssert(ref2 == dig2)
# 32 bit
let ref3 = 2147483648'u32 shr 31
let hex3 = 0x80000000'u32 shr 31
-let oct3 = 0c20000000000'u32 shr 31
+let oct3 = 0o20000000000'u32 shr 31
let dig3 = 0b10000000000000000000000000000000'u32 shr 31
doAssert(ref3 == 1)
From 426e5c2d1f0c0a607fb5384f9ef700c45d3332f8 Mon Sep 17 00:00:00 2001
From: Timothee Cour
Date: Tue, 3 Jul 2018 03:19:46 -0700
Subject: [PATCH 7/8] simplify typetraits.nim test (#8193)
---
lib/pure/typetraits.nim | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim
index 2047abda45..e9579e8247 100644
--- a/lib/pure/typetraits.nim
+++ b/lib/pure/typetraits.nim
@@ -59,9 +59,4 @@ proc supportsCopyMem*(t: typedesc): bool {.magic: "TypeTrait".}
when isMainModule:
- # echo type(42)
- import streams
- var ss = newStringStream()
- ss.write($type(42)) # needs `$`
- ss.setPosition(0)
- doAssert ss.readAll() == "int"
+ doAssert $type(42) == "int"
From ab47a870bce94cb33c66f2b27ecb1c62f48ae783 Mon Sep 17 00:00:00 2001
From: LemonBoy
Date: Tue, 3 Jul 2018 15:10:12 +0200
Subject: [PATCH 8/8] Error out if vararg match isn't an exact one (#8186)
Fixes #8172
---
compiler/sigmatch.nim | 12 +++++++++++-
tests/typerel/t8172.nim | 11 +++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
create mode 100644 tests/typerel/t8172.nim
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 84e59349ec..523783b361 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -2308,6 +2308,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
m.firstMismatch = f
return
if m.baseTypeMatch:
+ assert formal.typ.kind == tyVarargs
#assert(container == nil)
if container.isNil:
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
@@ -2321,10 +2322,19 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
# pick the formal from the end, so that 'x, y, varargs, z' works:
f = max(f, formalLen - n.len + a + 1)
- else:
+ elif formal.typ.kind != tyVarargs or container == nil:
setSon(m.call, formal.position + 1, arg)
inc(f)
container = nil
+ else:
+ # we end up here if the argument can be converted into the varargs
+ # formal (eg. seq[T] -> varargs[T]) but we have already instantiated
+ # a container
+ assert arg.kind == nkHiddenStdConv
+ localError(c.config, n.sons[a].info, "cannot convert $1 to $2" % [
+ typeToString(n.sons[a].typ), typeToString(formal.typ) ])
+ m.state = csNoMatch
+ return
checkConstraint(n.sons[a])
inc(a)
diff --git a/tests/typerel/t8172.nim b/tests/typerel/t8172.nim
new file mode 100644
index 0000000000..8e0b32932c
--- /dev/null
+++ b/tests/typerel/t8172.nim
@@ -0,0 +1,11 @@
+discard """
+ line: 11
+ errormsg: "cannot convert array[0..0, string] to varargs[string]"
+"""
+
+proc f(v: varargs[string]) =
+ echo(v)
+
+f("b", "c") # Works
+f(["b", "c"]) # Works
+f("b", ["c"]) # Fails