Merge branch 'devel' of github.com:nim-lang/Nim into devel

This commit is contained in:
Araq
2018-02-26 20:48:23 +01:00
20 changed files with 222 additions and 165 deletions

View File

@@ -241,9 +241,6 @@ styledEcho "Red on Green.", resetStyle
and it no longer raises an OS error but returns an ``osInvalidSocket`` when
creation fails.
- ``newNativeSocket`` is now named ``createNativeSocket``.
- Type inference for generic type parameters involving numeric types is now symetric. See
[Generic type inference for numeric types](https://nim-lang.org/docs/manual.html#generics-generic-type-inference-fornumeric-types)
for more information.
- The ``deprecated`` pragma now supports a user-definable warning message for procs.
```nim

View File

@@ -788,30 +788,13 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
# myDiv(4, 9);
# } catch (NimExceptionType1&) {
# body
# goto LA_END;
# } catch (NimExceptionType2&) {
# finallyPart()
# raise;
# goto LA_END;
# } catch (NimExceptionType3&) {goto LA1;}
# } catch (NimExceptionType4&) {goto LA1;}
# } catch (NimExceptionType5&) {goto LA2;}
# } catch (NimExceptionType6&) {goto LA2;}
# }
# catch(...) {
# // general handler
# goto LA_END;
# general_handler_body
# }
# {LA1:
# labeled_branch_body_LA1
# goto LA_END;
# }
# {LA2:
# labeled_branch_body_LA2
# finallyPart()
# raise;
# goto LA_END;
# }
# LA_END:
# finallyPart();
template genExceptBranchBody(body: PNode) {.dirty.} =
@@ -819,22 +802,19 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR_);$n")
expr(p, body, d)
linefmt(p, cpsStmts, "#popCurrentException();$n")
linefmt(p, cpsStmts, "goto $1;$n", end_label)
if not isEmptyType(t.typ) and d.k == locNone:
getTemp(p, t.typ, d)
genLineDir(p, t)
let end_label = getLabel(p)
discard cgsym(p.module, "Exception")
add(p.nestedTryStmts, t)
startBlock(p, "try {$n")
expr(p, t[0], d)
endBlock(p, ropecg(p.module, "}"))
endBlock(p)
let end_label = getLabel(p)
var catchAllPresent = false
var labeled_branches: seq[tuple[label: Rope, body: PNode]] = @[] # generated after labels discovered
inc p.inExceptBlock
for i in 1..<t.len:
@@ -849,20 +829,12 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
startBlock(p, "catch (...) {$n")
genExceptBranchBody(t[i][0])
endBlock(p)
elif t[i].len == 2:
startBlock(p, "catch ($1*) {$n", getTypeDesc(p.module, t[i][0].typ))
genExceptBranchBody(t[i][^1])
endBlock(p)
else:
# cpp can't catch multiple types in one statement so we need a label and goto
let label = getLabel(p)
labeled_branches.add((label, t[i][^1]))
for j in 0..t[i].len-2:
assert(t[i][j].kind == nkType)
linefmt(p, cpsStmts, "catch ($1*) {goto $2;}$n",
[getTypeDesc(p.module, t[i][j].typ), label])
startBlock(p, "catch ($1*) {$n", getTypeDesc(p.module, t[i][j].typ))
genExceptBranchBody(t[i][^1]) # exception handler body will duplicated for every type
endBlock(p)
if not catchAllPresent and t[^1].kind == nkFinally:
# finally requires catch all presence
@@ -871,14 +843,6 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
line(p, cpsStmts, ~"throw;$n")
endBlock(p)
# generate labeled branches bodies
for label, body in labeled_branches.items():
startBlock(p)
fixLabel(p, label)
genExceptBranchBody(body)
endBlock(p)
fixLabel(p, end_label)
dec p.inExceptBlock
discard pop(p.nestedTryStmts)

View File

@@ -151,6 +151,11 @@ proc complement*(a: PNode): PNode =
for i in countup(0, high(x)): x[i] = not x[i]
result = toTreeSet(x, a.typ, a.info)
proc deduplicate*(a: PNode): PNode =
var x: TBitSet
toBitSet(a, x)
result = toTreeSet(x, a.typ, a.info)
proc cardSet(s: PNode): BiggestInt =
# here we can do better than converting it into a compact set
# we just count the elements directly

View File

@@ -169,21 +169,24 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
else:
add(candidates, err.sym.getProcHeader(prefer))
add(candidates, "\n")
if err.firstMismatch != 0 and n.len > 2:
add(candidates, " first type mismatch at position: " & $err.firstMismatch &
"\n required type: ")
if err.firstMismatch != 0 and n.len > 1:
let cond = n.len > 2
if cond:
candidates.add(" first type mismatch at position: " & $err.firstMismatch &
"\n required type: ")
var wanted, got: PType = nil
if err.firstMismatch < err.sym.typ.len:
wanted = err.sym.typ.sons[err.firstMismatch]
candidates.add typeToString(wanted)
if cond: candidates.add typeToString(wanted)
else:
candidates.add "none"
if cond: candidates.add "none"
if err.firstMismatch < n.len:
candidates.add "\n but expression '"
candidates.add renderTree(n[err.firstMismatch])
candidates.add "' is of type: "
if cond:
candidates.add "\n but expression '"
candidates.add renderTree(n[err.firstMismatch])
candidates.add "' is of type: "
got = n[err.firstMismatch].typ
candidates.add typeToString(got)
if cond: candidates.add typeToString(got)
if wanted != nil and got != nil:
effectProblem(wanted, got, candidates)
candidates.add "\n"

View File

@@ -692,6 +692,12 @@ proc implicitIterator(c: PContext, it: string, arg: PNode): PNode =
result.add arg
result = semExprNoDeref(c, result, {efWantIterator})
proc isTrivalStmtExpr(n: PNode): bool =
for i in 0 .. n.len-2:
if n[i].kind notin {nkEmpty, nkCommentStmt}:
return false
result = true
proc semFor(c: PContext, n: PNode): PNode =
result = n
checkMinSonsLen(n, 3)
@@ -699,6 +705,9 @@ proc semFor(c: PContext, n: PNode): PNode =
openScope(c)
n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator})
var call = n.sons[length-2]
if call.kind == nkStmtListExpr and isTrivalStmtExpr(call):
call = call.lastSon
n.sons[length-2] = call
let isCallExpr = call.kind in nkCallKinds
if isCallExpr and call[0].kind == nkSym and
call[0].sym.magic in {mFields, mFieldPairs, mOmpParFor}:

View File

@@ -497,8 +497,8 @@ proc semCaseBranchSetElem(c: PContext, t, b: PNode,
proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
covered: var BiggestInt) =
for i in countup(0, sonsLen(branch) - 2):
let lastIndex = sonsLen(branch) - 2
for i in 0..lastIndex:
var b = branch.sons[i]
if b.kind == nkRange:
branch.sons[i] = b
@@ -516,14 +516,21 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
branch.sons[i] = skipConv(fitNode(c, t.sons[0].typ, r, r.info))
inc(covered)
else:
if r.kind == nkCurly:
r = r.deduplicate
# first element is special and will overwrite: branch.sons[i]:
branch.sons[i] = semCaseBranchSetElem(c, t, r[0], covered)
# other elements have to be added to ``branch``
for j in 1 ..< r.len:
branch.add(semCaseBranchSetElem(c, t, r[j], covered))
# caution! last son of branch must be the actions to execute:
var L = branch.len
swap(branch.sons[L-2], branch.sons[L-1])
swap(branch.sons[^2], branch.sons[^1])
checkForOverlap(c, t, i, branchIndex)
# Elements added above needs to be checked for overlaps.
for i in lastIndex.succ..(sonsLen(branch) - 2):
checkForOverlap(c, t, i, branchIndex)
proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,

View File

@@ -915,24 +915,25 @@ proc isCovariantPtr(c: var TCandidate, f, a: PType): bool =
else:
return false
proc maxNumericType(prev, candidate: PType): PType =
let c = candidate.skipTypes({tyRange})
template greater(s) =
if c.kind in s: result = c
case prev.kind
of tyInt: greater({tyInt64})
of tyInt8: greater({tyInt, tyInt16, tyInt32, tyInt64})
of tyInt16: greater({tyInt, tyInt32, tyInt64})
of tyInt32: greater({tyInt64})
when false:
proc maxNumericType(prev, candidate: PType): PType =
let c = candidate.skipTypes({tyRange})
template greater(s) =
if c.kind in s: result = c
case prev.kind
of tyInt: greater({tyInt64})
of tyInt8: greater({tyInt, tyInt16, tyInt32, tyInt64})
of tyInt16: greater({tyInt, tyInt32, tyInt64})
of tyInt32: greater({tyInt64})
of tyUInt: greater({tyUInt64})
of tyUInt8: greater({tyUInt, tyUInt16, tyUInt32, tyUInt64})
of tyUInt16: greater({tyUInt, tyUInt32, tyUInt64})
of tyUInt32: greater({tyUInt64})
of tyUInt: greater({tyUInt64})
of tyUInt8: greater({tyUInt, tyUInt16, tyUInt32, tyUInt64})
of tyUInt16: greater({tyUInt, tyUInt32, tyUInt64})
of tyUInt32: greater({tyUInt64})
of tyFloat32: greater({tyFloat64, tyFloat128})
of tyFloat64: greater({tyFloat128})
else: discard
of tyFloat32: greater({tyFloat64, tyFloat128})
of tyFloat64: greater({tyFloat128})
else: discard
proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
flags: TTypeRelFlags = {}): TTypeRelation =
@@ -1145,12 +1146,12 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
fRange = prev
let ff = f.sons[1].skipTypes({tyTypeDesc})
let aa = a.sons[1].skipTypes({tyTypeDesc})
if f.sons[0].kind != tyGenericParam and aa.kind == tyEmpty:
result = isGeneric
result = isGeneric
else:
result = typeRel(c, ff, aa)
if result < isGeneric:
if nimEnableCovariance and
trNoCovariance notin flags and
@@ -1631,13 +1632,15 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
# Special type binding rule for numeric types.
# See section "Generic type inference for numeric types" of the
# manual for further details:
let rebinding = maxNumericType(x.skipTypes({tyRange}), a)
if rebinding != nil:
put(c, f, rebinding)
result = isGeneric
else:
result = typeRel(c, x, a) # check if it fits
if result > isGeneric: result = isGeneric
when false:
let rebinding = maxNumericType(x.skipTypes({tyRange}), a)
if rebinding != nil:
put(c, f, rebinding)
result = isGeneric
else:
discard
result = typeRel(c, x, a) # check if it fits
if result > isGeneric: result = isGeneric
of tyStatic:
let prev = PType(idTableGet(c.bindings, f))
if prev == nil:

View File

@@ -713,29 +713,3 @@ definition):
But a ``bind`` is rarely useful because symbol binding from the definition
scope is the default.
Generic type inference for numeric types
----------------------------------------
A `numeric`:idx: type is any signed, unsigned integer type, floating point
type or a subrange thereof. Let ``maxNumericType(T1, T2)`` be the "greater"
type of ``T1`` and ``T2``, that is the type that uses more bits. For
example ``maxNumericType(int32, int64) == int64``. ``maxNumericType`` is only
defined for numeric types of the same class (signed, unsigned, floating point).
``maxNumericType`` strips away subranges,
``maxNumericType(subrangeof(int16), int8)`` produces ``int16`` not its
subrange. The definition ``maxNumericType`` is extended to take a variable
number of arguments in the obvious way;
``maxNumericType(x, y, z) == maxNumericType(maxNumericType(x, y), z)``.
A generic type parameter ``T`` that is bound to multiple numeric types ``N1``,
``N2``, ``N3``, ... during type checking is inferred to
be ``maxNumericType(N1, N2, N3, ...)``. This special type inference rule ensures
that the builtin arithmetic operators can be written in an intuitive way:
.. code-block:: nim
proc `@`[T: int|int16|int32](x, y: T): T
4'i32 @ 6'i64 # inferred to be of type ``int64``
4'i64 @ 6'i32 # inferred to be of type ``int64``

View File

@@ -955,6 +955,17 @@ proc `[]=`*[A](t: var CountTable[A], key: A, val: int) =
#t.data[h].key = key
#t.data[h].val = val
proc inc*[A](t: var CountTable[A], key: A, val = 1) =
## increments `t[key]` by `val`.
var index = rawGet(t, key)
if index >= 0:
inc(t.data[index].val, val)
if t.data[index].val == 0: dec(t.counter)
else:
if mustRehash(len(t.data), t.counter): enlarge(t)
rawInsert(t, t.data, key, val)
inc(t.counter)
proc initCountTable*[A](initialSize=64): CountTable[A] =
## creates a new count table that is empty.
##
@@ -969,7 +980,7 @@ proc toCountTable*[A](keys: openArray[A]): CountTable[A] =
## creates a new count table with every key in `keys` having a count
## of how many times it occurs in `keys`.
result = initCountTable[A](rightSize(keys.len))
for key in items(keys): result.inc key
for key in items(keys): result.inc(key)
proc `$`*[A](t: CountTable[A]): string =
## The `$` operator for count tables.
@@ -980,17 +991,6 @@ proc `==`*[A](s, t: CountTable[A]): bool =
## contain the same keys with the same count. Insert order does not matter.
equalsImpl(s, t)
proc inc*[A](t: var CountTable[A], key: A, val = 1) =
## increments `t[key]` by `val`.
var index = rawGet(t, key)
if index >= 0:
inc(t.data[index].val, val)
if t.data[index].val == 0: dec(t.counter)
else:
if mustRehash(len(t.data), t.counter): enlarge(t)
rawInsert(t, t.data, key, val)
inc(t.counter)
proc smallest*[A](t: CountTable[A]): tuple[key: A, val: int] =
## returns the (key,val)-pair with the smallest `val`. Efficiency: O(n)
assert t.len > 0
@@ -1088,6 +1088,10 @@ proc `[]=`*[A](t: CountTableRef[A], key: A, val: int) =
assert val > 0
t[][key] = val
proc inc*[A](t: CountTableRef[A], key: A, val = 1) =
## increments `t[key]` by `val`.
t[].inc(key, val)
proc newCountTable*[A](initialSize=64): CountTableRef[A] =
## creates a new count table that is empty.
##
@@ -1098,9 +1102,10 @@ proc newCountTable*[A](initialSize=64): CountTableRef[A] =
result[] = initCountTable[A](initialSize)
proc newCountTable*[A](keys: openArray[A]): CountTableRef[A] =
## creates a new count table with every key in `keys` having a count of 1.
## creates a new count table with every key in `keys` having a count
## of how many times it occurs in `keys`.
result = newCountTable[A](rightSize(keys.len))
for key in items(keys): result[key] = 1
for key in items(keys): result.inc(key)
proc `$`*[A](t: CountTableRef[A]): string =
## The `$` operator for count tables.
@@ -1114,10 +1119,6 @@ proc `==`*[A](s, t: CountTableRef[A]): bool =
elif isNil(t): result = false
else: result = s[] == t[]
proc inc*[A](t: CountTableRef[A], key: A, val = 1) =
## increments `t[key]` by `val`.
t[].inc(key, val)
proc smallest*[A](t: CountTableRef[A]): (A, int) =
## returns the (key,val)-pair with the smallest `val`. Efficiency: O(n)
t[].smallest
@@ -1316,7 +1317,6 @@ when isMainModule:
assert a == b
assert a == c
block: #6250
let
a = {3: 1}.toOrderedTable
@@ -1332,6 +1332,5 @@ when isMainModule:
assert((b == a) == true)
block: # CountTable.smallest
var t = initCountTable[int]()
for v in items([0, 0, 5, 5, 5]): t.inc(v)
let t = toCountTable([0, 0, 5, 5, 5])
doAssert t.smallest == (0, 2)

View File

@@ -507,7 +507,7 @@ proc request*(url: string, httpMethod: string, extraHeaders = "",
port = net.Port(443)
else:
raise newException(HttpRequestError,
"SSL support is not available. Cannot connect over SSL.")
"SSL support is not available. Cannot connect over SSL. Compile with -d:ssl to enable.")
if r.port != "":
port = net.Port(r.port.parseInt)
@@ -540,7 +540,8 @@ proc request*(url: string, httpMethod: string, extraHeaders = "",
"so a secure connection could not be established.")
sslContext.wrapConnectedSocket(s, handshakeAsClient, hostUrl.hostname)
else:
raise newException(HttpRequestError, "SSL support not available. Cannot connect via proxy over SSL")
raise newException(HttpRequestError, "SSL support not available. Cannot " &
"connect via proxy over SSL. Compile with -d:ssl to enable.")
else:
if timeout == -1:
s.connect(r.hostname, port)
@@ -1087,7 +1088,7 @@ proc newConnection(client: HttpClient | AsyncHttpClient,
if isSsl and not defined(ssl):
raise newException(HttpRequestError,
"SSL support is not available. Cannot connect over SSL.")
"SSL support is not available. Cannot connect over SSL. Compile with -d:ssl to enable.")
if client.connected:
client.close()
@@ -1137,7 +1138,7 @@ proc newConnection(client: HttpClient | AsyncHttpClient,
client.socket, handshakeAsClient, url.hostname)
else:
raise newException(HttpRequestError,
"SSL support is not available. Cannot connect over SSL.")
"SSL support is not available. Cannot connect over SSL. Compile with -d:ssl to enable.")
# May be connected through proxy but remember actual URL being accessed
client.currentURL = url
@@ -1333,4 +1334,4 @@ proc downloadFile*(client: AsyncHttpClient, url: string,
finally:
result.addCallback(
proc () = client.getBody = true
)
)

View File

@@ -430,8 +430,14 @@ when defineSsl:
raise newException(SSLError, "No error reported.")
if err == -1:
raiseOSError(osLastError())
var errStr = ErrErrorString(err, nil)
raise newException(SSLError, $errStr)
var errStr = $ErrErrorString(err, nil)
case err
of 336032814, 336032784:
errStr = "Please upgrade your OpenSSL library, it does not support the " &
"necessary protocols. OpenSSL error is: " & errStr
else:
discard
raise newException(SSLError, errStr)
proc getExtraData*(ctx: SSLContext, index: int): RootRef =
## Retrieves arbitrary data stored inside SSLContext.

View File

@@ -306,7 +306,7 @@ proc execProcesses*(cmds: openArray[string],
raiseOSError(err)
if rexit >= 0:
result = max(result, q[rexit].peekExitCode())
result = max(result, abs(q[rexit].peekExitCode()))
if afterRunEvent != nil: afterRunEvent(rexit, q[rexit])
close(q[rexit])
if i < len(cmds):
@@ -331,7 +331,7 @@ proc execProcesses*(cmds: openArray[string],
if beforeRunEvent != nil:
beforeRunEvent(i)
var p = startProcess(cmds[i], options=options + {poEvalCommand})
result = max(waitForExit(p), result)
result = max(abs(waitForExit(p)), result)
if afterRunEvent != nil: afterRunEvent(i, p)
close(p)

View File

@@ -32,7 +32,7 @@
## import parsecsv
## import os
## # Prepare a file
## var content = """One,Two,Three,Four
## let content = """One,Two,Three,Four
## 1,2,3,4
## 10,20,30,40
## 100,200,300,400
@@ -123,7 +123,7 @@ proc parseField(my: var CsvParser, a: var string) =
if buf[pos] == my.quote and my.quote != '\0':
inc(pos)
while true:
var c = buf[pos]
let c = buf[pos]
if c == '\0':
my.bufpos = pos # can continue after exception?
error(my, pos, my.quote & " expected")
@@ -153,7 +153,7 @@ proc parseField(my: var CsvParser, a: var string) =
inc(pos)
else:
while true:
var c = buf[pos]
let c = buf[pos]
if c == my.sep: break
if c in {'\c', '\l', '\0'}: break
add(a, c)
@@ -171,9 +171,9 @@ proc readRow*(my: var CsvParser, columns = 0): bool =
##
## Blank lines are skipped.
var col = 0 # current column
var oldpos = my.bufpos
let oldpos = my.bufpos
while my.buf[my.bufpos] != '\0':
var oldlen = my.row.len
let oldlen = my.row.len
if oldlen < col+1:
setLen(my.row, col+1)
my.row[col] = ""
@@ -208,16 +208,16 @@ proc close*(my: var CsvParser) {.inline.} =
proc readHeaderRow*(my: var CsvParser) =
## Reads the first row and creates a look-up table for column numbers
## See also `rowEntry <#rowEntry.CsvParser.string>`_.
var present = my.readRow()
let present = my.readRow()
if present:
my.headers = my.row
proc rowEntry*(my: var CsvParser, entry: string): string =
## Reads a specified `entry` from the current row.
proc rowEntry*(my: var CsvParser, entry: string): var string =
## Acceses a specified `entry` from the current row.
##
## Assumes that `readHeaderRow <#readHeaderRow.CsvParser>`_ has already been
## called.
var index = my.headers.find(entry)
let index = my.headers.find(entry)
if index >= 0:
result = my.row[index]
@@ -237,14 +237,14 @@ when isMainModule:
import os
import strutils
block: # Tests for reading the header row
var content = "One,Two,Three,Four\n1,2,3,4\n10,20,30,40,\n100,200,300,400\n"
let content = "One,Two,Three,Four\n1,2,3,4\n10,20,30,40,\n100,200,300,400\n"
writeFile("temp.csv", content)
var p: CsvParser
p.open("temp.csv")
p.readHeaderRow()
while p.readRow():
var zeros = repeat('0', p.currRow-2)
let zeros = repeat('0', p.currRow-2)
doAssert p.rowEntry("One") == "1" & zeros
doAssert p.rowEntry("Two") == "2" & zeros
doAssert p.rowEntry("Three") == "3" & zeros

View File

@@ -372,7 +372,7 @@ proc cursorForward*(f: File, count=1) =
inc(p.x, count)
setCursorPos(h, p.x, p.y)
else:
f.write("{stylePrefix}{count}C")
f.write(fmt"{stylePrefix}{count}C")
proc cursorBackward*(f: File, count=1) =
## Moves the cursor backward by `count` columns.
@@ -382,7 +382,7 @@ proc cursorBackward*(f: File, count=1) =
dec(p.x, count)
setCursorPos(h, p.x, p.y)
else:
f.write("{stylePrefix}{count}D")
f.write(fmt"{stylePrefix}{count}D")
when true:
discard

View File

@@ -1917,7 +1917,7 @@ proc `$` *(x: float): string {.magic: "FloatToStr", noSideEffect.}
proc `$` *(x: bool): string {.magic: "BoolToStr", noSideEffect.}
## The stringify operator for a boolean argument. Returns `x`
## converted to the string "false" or "true".
#
proc `$` *(x: char): string {.magic: "CharToStr", noSideEffect.}
## The stringify operator for a character argument. Returns `x`
## converted to a string.

View File

@@ -0,0 +1,50 @@
discard """
output: '''
OK
OK
OK
'''
"""
type Kind = enum A, B
var k = A
template reject(b) =
static: doAssert(not compiles(b))
reject:
var i = 2
case i
of [1, 1]: discard
else: discard
reject:
var i = 2
case i
of 1, { 1..2 }: discard
else: discard
reject:
var i = 2
case i
of { 1, 1 }: discard
of { 1, 1 }: discard
else: discard
reject:
case k
of [A, A]: discard
var i = 2
case i
of { 1, 1 }: discard
of { 2, 2 }: echo "OK"
else: discard
case i
of { 10..30, 15..25, 5..15, 25..35 }: discard
else: echo "OK"
case k
of {A, A..A}: echo "OK"
of B: discard

View File

@@ -3,7 +3,9 @@ discard """
output: '''foo
bar
Need odd and >= 3 digits##
baz'''
baz
caught
'''
"""
# bug #1888
@@ -15,3 +17,21 @@ try:
except ValueError:
echo getCurrentExceptionMsg(), "##"
echo "baz"
# bug 7232
try:
discard
except KeyError, ValueError:
echo "except handler" # should not be invoked
#bug 7239
try:
try:
raise newException(ValueError, "asdf")
except KeyError, ValueError:
raise
except:
echo "caught"

View File

@@ -1,12 +1,21 @@
discard """
output: '''int64
int64'''
output: '''false'''
"""
import typetraits
when false:
import typetraits
proc `@`[T: SomeInteger](x, y: T): T = x
proc `@`[T: SomeInteger](x, y: T): T = x
echo(type(5'i64 @ 6'i32))
echo(type(5'i64 @ 6'i32))
echo(type(5'i32 @ 6'i64))
echo(type(5'i32 @ 6'i64))
import sets
# bug #7247
type
n8 = range[0'i8..127'i8]
var tab = initSet[n8]()
echo tab.contains(8)

View File

@@ -2,7 +2,12 @@ discard """
output: '''true
3
4
5'''
5
0
1
2
3
4'''
cmd: "nim $target --gc:none --hints:on --warnings:off $options $file"
"""
@@ -55,3 +60,7 @@ echo "true"
# bug #1560
for i in @[3, 4, 5]:
echo($i)
# bug #6992
for i in 0 ..< 5u32:
echo i

View File

@@ -294,7 +294,6 @@ proc compilerOutputTests(test: TTest, target: TTarget, given: var TSpec,
proc testSpec(r: var TResults, test: TTest, target = targetC) =
let tname = test.name.addFileExt(".nim")
#echo "TESTING ", tname
inc(r.total)
var expected: TSpec
if test.action != actionRunNoSpec:
expected = parseSpec(tname)
@@ -305,12 +304,14 @@ proc testSpec(r: var TResults, test: TTest, target = targetC) =
if expected.err == reIgnored:
r.addResult(test, target, "", "", reIgnored)
inc(r.skipped)
inc(r.total)
return
if expected.targets == {}:
expected.targets.incl(target)
for target in expected.targets:
inc(r.total)
if target notin targets:
r.addResult(test, target, "", "", reIgnored)
inc(r.skipped)
@@ -490,7 +491,7 @@ proc main() =
else: echo r, r.data
backend.close()
var failed = r.total - r.passed - r.skipped
if failed > 0:
if failed != 0:
echo "FAILURE! total: ", r.total, " passed: ", r.passed, " skipped: ", r.skipped
quit(QuitFailure)