fixes merge conflict

This commit is contained in:
Andreas Rumpf 2018-08-19 15:14:03 +02:00
commit 696c0c48c7
195 changed files with 2049 additions and 1344 deletions

46
tests/arithm/tashr.nim Normal file
View file

@ -0,0 +1,46 @@
discard """
output: ''''''
targets: '''c js'''
"""
# issue #6255, feature request
# arithmetic right shift
var x1 = -123'i8
var x2 = -123'i16
var x3 = -123'i32
var x4 = -123'i64
var x5 = -123
block codegen_test:
doAssert ashr(x1, 1) == -62
doAssert ashr(x2, 1) == -62
doAssert ashr(x3, 1) == -62
doAssert ashr(x4, 1) == -62
doAssert ashr(x5, 1) == -62
block semfold_test:
doAssert ashr(-123'i8 , 1) == -62
doAssert ashr(-123'i16, 1) == -62
doAssert ashr(-123'i32, 1) == -62
doAssert ashr(-123'i64, 1) == -62
doAssert ashr(-123 , 1) == -62
static: # VM test
doAssert ashr(-123'i8 , 1) == -62
doAssert ashr(-123'i16, 1) == -62
doAssert ashr(-123'i32, 1) == -62
doAssert ashr(-123'i64, 1) == -62
doAssert ashr(-123 , 1) == -62
var y1 = -123'i8
var y2 = -123'i16
var y3 = -123'i32
var y4 = -123'i64
var y5 = -123
doAssert ashr(y1, 1) == -62
doAssert ashr(y2, 1) == -62
doAssert ashr(y3, 1) == -62
doAssert ashr(y4, 1) == -62
doAssert ashr(y5, 1) == -62

View file

@ -37,8 +37,7 @@ block: #8399
case line[0]
of '+', '-': @[]
of '$': (let x = await bar(); @[""])
else:
nil
else: @[]
doAssert(res == @[""])

View file

@ -15,11 +15,11 @@ when defined(ssl):
var clientCount = 0
proc sendMessages(client: AsyncSocket) {.async.} =
for i in 0 .. <messagesToSend:
for i in 0 ..< messagesToSend:
await send(client, "Message " & $i & "\c\L")
proc launchSwarm(port: Port) {.async.} =
for i in 0 .. <swarmSize:
for i in 0 ..< swarmSize:
var sock = newAsyncSocket()
var clientContext = newContext(verifyMode = CVerifyNone)
clientContext.wrapSocket(sock)

View file

@ -11,7 +11,9 @@ template processTest(t, x: untyped) =
#stdout.flushFile()
if not x: echo(t & " FAILED\r\n")
when not defined(windows):
when defined(macosx):
echo "All tests passed!"
elif not defined(windows):
import os, posix, nativesockets, times
when ioselSupportedPlatform:

View file

@ -41,16 +41,16 @@ let str2 = "NN"
let a = case str1:
of "Y": true
of "N": false
else:
else:
echo "no good"
quit("quiting")
proc toBool(s: string): bool =
proc toBool(s: string): bool =
case s:
of nil, "": raise newException(ValueError, "Invalid boolean")
elif s[0] == 'Y': true
elif s[0] == 'N': false
else: "error".quit(2)
of "": raise newException(ValueError, "Invalid boolean")
elif s[0] == 'Y': true
elif s[0] == 'N': false
else: "error".quit(2)
let b = "NN".toBool()
@ -66,7 +66,7 @@ static:
var bb: bool
doassert(not compiles(
bb = case str2:
of nil, "": raise newException(ValueError, "Invalid boolean")
of "": raise newException(ValueError, "Invalid boolean")
elif str.startsWith("Y"): true
elif str.startsWith("N"): false
))
@ -94,7 +94,7 @@ doassert(not compiles(
bb = case str2:
of "Y":
raise newException(ValueError, "Invalid Y")
true
true
else: raise newException(ValueError, "Invalid")
))
@ -103,6 +103,6 @@ doassert(not compiles(
bb = case str2:
of "Y":
"invalid Y".quit(3)
true
true
else: raise newException(ValueError, "Invalid")
))

View file

@ -0,0 +1,2 @@
proc head*[T](pp: var array[1,T]): var T =
result = pp[0]

View file

@ -0,0 +1,10 @@
import rtarray
type
T = tuple[x:int]
var
arr: array[1,T]
proc init*() =
discard head(arr)

4
tests/ccgbugs/t8616.nim Normal file
View file

@ -0,0 +1,4 @@
import pkg8616 / scheduler
when isMainModule:
init()

View file

@ -0,0 +1,8 @@
proc foo[T](s: var openArray[T]): T =
for x in s: result += x
proc bar(xyz: var seq[int]) =
doAssert 6 == (seq[int](xyz)).foo()
var t = @[1,2,3]
bar(t)

12
tests/closure/t8550.nim Normal file
View file

@ -0,0 +1,12 @@
discard """
output: "@[\"42\"]"
"""
proc chk_fail(): seq[string] =
iterator x(): int {.closure.} = yield 42
proc f(cl: iterator(): int {.closure.}): seq[string] =
result = @[]
for i in cl(): result.add($i)
result = f(x)
echo(chk_fail())

13
tests/compiles/t8630.nim Normal file
View file

@ -0,0 +1,13 @@
discard """
output: '''
foo
bar
'''
"""
proc test(strings: seq[string]) =
for s in strings:
var p3 = unsafeAddr(s)
echo p3[]
test(@["foo", "bar"])

View file

@ -13,18 +13,14 @@ proc add(result: var string; x: float)
first type mismatch at position: 1
required type: var string
but expression 'k' is of type: Alias
proc add(x: var string; y: cstring)
first type mismatch at position: 1
required type: var string
but expression 'k' is of type: Alias
proc add(x: var string; y: char)
first type mismatch at position: 1
required type: var string
but expression 'k' is of type: Alias
proc add(x: var string; y: string)
first type mismatch at position: 1
required type: var string
but expression 'k' is of type: Alias
proc add(x: var string; y: cstring)
first type mismatch at position: 1
required type: var string
but expression 'k' is of type: Alias
proc add[T](x: var seq[T]; y: T)
first type mismatch at position: 1
required type: var seq[T]
@ -33,6 +29,10 @@ proc add(result: var string; x: int64)
first type mismatch at position: 1
required type: var string
but expression 'k' is of type: Alias
proc add(x: var string; y: char)
first type mismatch at position: 1
required type: var string
but expression 'k' is of type: Alias
t3330.nim(48, 8) template/generic instantiation from here
t3330.nim(55, 6) Foo: 'bar.value' cannot be assigned to

View file

@ -0,0 +1,20 @@
discard """
file: "tconverter_with_constraint.nim"
line: 20
errormsg: "type mismatch: got <int>"
"""
type
MyType = distinct int
converter to_mytype(m: int{lit}): MyType =
m.MyType
proc myproc(m: MyType) =
echo m.int, ".MyType"
myproc(1) # call by literal is ok
var x: int = 12
myproc(x) # should fail

View file

@ -1,6 +1,7 @@
discard """
targets: "cpp"
output: "hello"
cmd: "nim cpp --nilseqs:on $file"
"""
# bug #3299

View file

@ -9,7 +9,6 @@ discard """
type
MyPointer = distinct pointer
MyString = distinct string
MyStringNotNil = distinct (string not nil)
MyInt = distinct int
proc foo(a: MyPointer) =
@ -26,20 +25,6 @@ p = cast[MyPointer](nil)
p = nil.MyPointer
p = nil
var c: MyString
c = "Test".MyString
c = nil.MyString
c = nil
p = nil
doAssert(compiles(c = p) == false)
var n: MyStringNotNil = "Test".MyStringNotNil # Cannot prove warning ...
n = "Test".MyStringNotNil
doAssert(compiles(n = nil.MyStringNotNil) == false)
doAssert(compiles(n = nil.MyStringNotNil) == false)
doAssert(compiles(n = nil) == false)
var i: MyInt
i = 1.MyInt
doAssert(compiles(i = nil) == false)

View file

@ -7,10 +7,10 @@ Check passed'''
# bug #5628
proc checkException(ex: ref Exception) =
doAssert(ex.name == "ValueError")
doAssert(ex.name == cstring"ValueError")
doAssert(ex.msg == "SecondException")
doAssert(ex.parent != nil)
doAssert(ex.parent.name == "KeyError")
doAssert(ex.parent.name == cstring"KeyError")
doAssert(ex.parent.msg == "FirstException")
echo "Check passed"

View file

@ -87,7 +87,7 @@ proc parseResponse(): JsonNode =
var excMsg = key & "("
if (var n=result["key2"]; n != nil):
excMsg &= n.str
raise newException(SystemError, excMsg)
raise newException(CatchableError, excMsg)

29
tests/generics/t6137.nim Normal file
View file

@ -0,0 +1,29 @@
discard """
action: "reject"
line: 29
errormsg: "\'vectFunc\' doesn't have a concrete type, due to unspecified generic parameters."
"""
type
# simple vector of declared fixed length
vector[N : static[int]] = array[0..N-1, float]
proc `*`[T](x: float, a: vector[T]): vector[T] =
# multiplication by scalar
for ii in 0..high(a):
result[ii] = a[ii]*x
let
# define a vector of length 3
x: vector[3] = [1.0, 3.0, 5.0]
proc vectFunc[T](x: vector[T]): vector[T] {.procvar.} =
# Define a vector function
result = 2.0*x
proc passVectFunction[T](g: proc(x: vector[T]): vector[T], x: vector[T]): vector[T] =
# pass a vector function as input in another procedure
result = g(x)
let
xNew = passVectFunction(vectFunc,x)

10
tests/generics/t7141.nim Normal file
View file

@ -0,0 +1,10 @@
discard """
action: "reject"
line: 7
errormsg: "cannot instantiate: \'T\'"
"""
proc foo[T](x: T) =
discard
var fun = if true: foo else: foo

View file

@ -103,7 +103,7 @@ proc DeleteItem[T,D] (n: PNode[T,D], x: int): PNode[T,D] {.inline.} =
else :
result = n.left
n.slots = nil
n.slots = @[]
n.left = nil
proc internalDelete[T,D] (ANode: PNode[T,D], key: T, Avalue: var D): PNode[T,D] =
@ -200,7 +200,7 @@ proc traceTree[T,D](root: PNode[T,D]) =
traceln(space)
write stdout, "left: "
doTrace(n.left, level+1)
for i, el in n.slots :
for i, el in n.slots:
if el != nil and not isClean(el):
traceln(space)
traceX(i)

View file

@ -2,8 +2,8 @@ discard """
output: '''(peel: 0, color: 15)
(color: 15)
17
(width: 0.0, taste: nil, color: 13)
(width: 0.0, taste: nil, color: 15)
(width: 0.0, taste: "", color: 13)
(width: 0.0, taste: "", color: 15)
cool'''
"""
@ -11,16 +11,16 @@ cool'''
type
BaseFruit[T] = object of RootObj
color: T
MidLevel[T] = object of BaseFruit[T]
Mango = object of MidLevel[int]
peel: int
Peach[X, T, Y] = object of T
width: X
taste: Y
proc setColor[T](self: var BaseFruit[T]) =
self.color = 15

View file

@ -48,4 +48,4 @@ for i in 1 .. 10:
let results = runCallbacks()
doAssert(expected == results)
doAssert(expected == $results)

View file

@ -34,7 +34,7 @@ var
recurse1 = Recurse[int](data: 1, next: recurse2)
doAssert test.name == "Jorden"
doAssert test.name == cstring"Jorden"
doAssert knight.age == 19
doAssert knight.item.price == 50
doAssert recurse1.next.next.data == 3

View file

@ -64,7 +64,7 @@ block:
proc test(): bool =
let obj = newJsObject()
obj.`?!$` = proc(x, y, z: int, t: cstring): cstring = t & $(x + y + z)
obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == "Result is: 6"
obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == cstring"Result is: 6"
echo test()
# Test JsObject []()

View file

@ -21,17 +21,17 @@ doAssert b - a == initDuration(seconds = 500_000_000)
# Because we can't change the timezone JS uses, we define a simple static timezone for testing.
proc staticZoneInfoFromUtc(time: Time): ZonedTime =
proc zonedTimeFromTime(time: Time): ZonedTime =
result.utcOffset = -7200
result.isDst = false
result.adjTime = time + 7200.seconds
result.time = time
proc staticZoneInfoFromTz(adjTime: Time): ZonedTIme =
proc zonedTimeFromAdjTime(adjTime: Time): ZonedTIme =
result.utcOffset = -7200
result.isDst = false
result.adjTime = adjTime
result.time = adjTime + initDuration(seconds = -7200)
let utcPlus2 = Timezone(zoneInfoFromUtc: staticZoneInfoFromUtc, zoneInfoFromTz: staticZoneInfoFromTz, name: "")
let utcPlus2 = newTimezone("", zonedTimeFromTime, zonedTimeFromAdjTime)
block timezoneTests:
let dt = initDateTime(01, mJan, 2017, 12, 00, 00, utcPlus2)

View file

@ -12,7 +12,7 @@ discard """
"""
import macros
{.experimental: "forLoopMacros".}
macro mymacro(): untyped =
result = newLit([1, 2, 3])

View file

@ -0,0 +1,14 @@
# issue #5617, feature request
# Ability to set a NimNode's lineinfo
import macros
type
Test = object
macro mixer(n: typed): untyped =
let x = newIdentNode("echo")
x.copyLineInfo(n)
result = newLit(x.lineInfo == n.lineInfo)
var z = mixer(Test)
doAssert z

View file

@ -74,14 +74,14 @@ type
## nothing prevents you from accessing directly the type of field you want
## if you expect only one kind.
case kind*: Tparam_kind
of PK_EMPTY: nil
of PK_EMPTY: discard
of PK_INT: int_val*: int
of PK_BIGGEST_INT: big_int_val*: BiggestInt
of PK_FLOAT: float_val*: float
of PK_BIGGEST_FLOAT: big_float_val*: BiggestFloat
of PK_STRING: str_val*: string
of PK_BOOL: bool_val*: bool
of PK_HELP: nil
of PK_HELP: discard
Tcommandline_results* = object of RootObj ## \
## Contains the results of the parsing.
@ -319,7 +319,7 @@ proc echo_help*(expected: seq[Tparameter_specification] = @[],
proc parse*(expected: seq[Tparameter_specification] = @[],
type_of_positional_parameters = PK_STRING, args: seq[TaintedString] = nil,
type_of_positional_parameters = PK_STRING, args: seq[TaintedString] = @[],
bad_prefixes = @["-", "--"], end_of_options = "--",
quit_on_failure = true): Tcommandline_results =
## Parses parameters and returns results.
@ -339,7 +339,7 @@ proc parse*(expected: seq[Tparameter_specification] = @[],
##
## The args sequence should be the list of parameters passed to your program
## without the program binary (usually OSes provide the path to the binary as
## the zeroth parameter). If args is nil, the list will be retrieved from the
## the zeroth parameter). If args is empty, the list will be retrieved from the
## OS.
##
## If there is any kind of error and quit_on_failure is true, the quit proc
@ -358,7 +358,7 @@ proc parse*(expected: seq[Tparameter_specification] = @[],
# Prepare the input parameter list, maybe get it from the OS if not available.
var args = args
if args == nil:
if args.len == 0:
let total_params = paramCount()
#echo "Got no explicit args, retrieving from OS. Count: ", total_params
newSeq(args, total_params)

View file

@ -145,7 +145,7 @@ proc importHandling(data: JsonNode): THandlingRecord
proc importBullet(data: JsonNode; errors: var seq[string]): PBulletRecord
proc importSoul(data: JsonNode): TSoulRecord
proc importExplosion(data: JsonNode; errors: var seq[string]): TExplosionRecord
proc importSound*(data: JsonNode; errors: var seq[string]; fieldName: string = nil): PSoundRecord
proc importSound*(data: JsonNode; errors: var seq[string]; fieldName: string = ""): PSoundRecord
## this is the only pipe between lobby and main.nim
proc getActiveState*(): TGameState =
@ -514,7 +514,7 @@ proc importExplosion(data: JsonNode; errors: var seq[string]): TExplosionRecord
let expl = data["explode"]
result.anim = importAnim(expl, errors)
result.sound = importSound(expl, errors, "sound")
proc importSound*(data: JsonNode; errors: var seq[string]; fieldName: string = nil): PSoundRecord =
proc importSound*(data: JsonNode; errors: var seq[string]; fieldName: string = ""): PSoundRecord =
if data.kind == JObject:
checkKey(data, fieldName)
result = newSound(data[fieldName].str, errors)

View file

@ -92,8 +92,8 @@ proc newGuiContainer*(pos: TVector2f): PGuiContainer =
result = newGuiContainer()
result.setPosition pos
proc free*(container: PGuiContainer) =
container.widgets = nil
container.buttons = nil
container.widgets = @[]
container.buttons = @[]
proc add*(container: PGuiContainer; widget: PGuiObject) =
container.widgets.add(widget)
proc add*(container: PGuiContainer; button: PButton) =

View file

@ -99,3 +99,15 @@ echo sizeof(a)
echo sizeof(b)
echo sizeof(c)
# This is the same example but using a proc instead of a macro
# Instead of type mismatch for macro, proc just failed with internal error: getTypeDescAux(tyNone)
# https://github.com/nim-lang/Nim/issues/7231
proc getBase2*(bits: static[int]): typedesc =
if bits == 128:
result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint64"))
else:
result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint32"))
type
MpUint2*[bits: static[int]] = getbase2(bits)

View file

@ -44,16 +44,16 @@ import json
type
foo = object
thing: string not nil
thing: ptr int not nil
CTS = ref object
subs_by_sid: Table[int, foo]
proc parse(cts: CTS, jn: JsonNode) =
var y = jn.getInt(4523)
let ces = foo(
thing: jn.getStr("thing")
thing: addr y
)
cts.subs_by_sid[0] = ces
@ -63,17 +63,3 @@ proc parse(cts: CTS, jn: JsonNode) =
proc p(x: proc(){.closure.} not nil) = discard
p(proc(){.closure.} = discard)
# bug #3993
type
List[T] = seq[T] not nil
proc `^^`[T](v: T, lst: List[T]): List[T] =
result = @[v]
result.add(lst)
proc Nil[T](): List[T] = @[]
when isMainModule:
let lst = 1 ^^ 2 ^^ Nil[int]()

View file

@ -1,5 +1,5 @@
discard """
line: 22
line: 13
errormsg: "type mismatch"
"""
{.experimental: "notnil".}
@ -8,16 +8,6 @@ type
TObj = object
x: int
MyString = string not nil
#var x: PObj = nil
proc p(x: string not nil): int =
result = 45
proc q(x: MyString) = discard
proc q2(x: string) = discard
q2(nil)
q(nil)

View file

@ -1,6 +1,6 @@
discard """
errormsg: "'y' is provably nil"
line:38
line:25
"""
import strutils
@ -10,19 +10,6 @@ type
TObj = object
x, y: int
type
superstring = string not nil
proc q(s: superstring) =
echo s
proc p2() =
var a: string = "I am not nil"
q(a) # but this should and does not
p2()
proc q(x: pointer not nil) =
discard

View file

@ -6,9 +6,9 @@ discard """
# bug #2355
type
Foo = object
foo: string not nil
bar: string not nil
foo: ref int
bar: ref int not nil
var x: ref int = new(int)
# Create instance without initializaing the `bar` field
var f = Foo(foo: "foo")
var f = Foo(foo: x)
echo f.bar.isNil # true

View file

@ -28,9 +28,12 @@ if paramCount() == 0:
# windows kill happens using TerminateProcess(h, 0), so we should get a
# 0 here
echo p.waitForExit() == 0
elif defined(haiku):
# on Haiku, the program main thread receive SIGKILLTHR
echo p.waitForExit() == 128 + SIGKILLTHR
else:
# on posix (non-windows), kill sends SIGKILL
echo p.waitForExit() == 128 + SIGKILL
else:
sleep(5000) # should get killed before this
sleep(5000) # should get killed before this

View file

@ -12,6 +12,8 @@ else:
var process: Process
when defined(android):
process = startProcess("/system/bin/env", "/system/bin", ["true"])
elif defined(haiku):
process = startProcess("/bin/env", "/bin", ["true"])
else:
process = startProcess("/usr/bin/env", "/usr/bin", ["true"])
let dir2 = getCurrentDir()

View file

@ -11,7 +11,7 @@ type
Killer* = object
lock: Lock
bailed {.guard: lock.}: bool
processes {.guard: lock.}: array[0..MAX_WORKERS-1, foreign ptr Process]
processes {.guard: lock.}: array[0..MAX_WORKERS-1, ptr Process]
# Hold a lock for a statement.
template hold(lock: Lock, body: untyped) =
@ -32,7 +32,7 @@ proc initKiller*(): Killer =
var killer = initKiller()
# remember that a process has been launched, killing it if we have bailed.
proc launched*(process: foreign ptr Process): int {.gcsafe.} =
proc launched*(process: ptr Process): int {.gcsafe.} =
result = killer.processes.high + 1
killer.lock.hold:
if killer.bailed:

View file

@ -1,11 +1,11 @@
discard """
output: '''obj2 nil
obj nil
obj3 nil
output: '''obj2 @[]
obj @[]
obj3 @[]
3
obj2 nil
obj nil
obj3 nil'''
obj2 @[]
obj @[]
obj3 @[]'''
cmd: "nim c -r --threads:on $file"
"""

View file

@ -18,12 +18,12 @@ var results: seq[int] = @[]
for i in 0 .. durations.high:
tasks.add spawn timer(durations[i])
var index = awaitAny(tasks)
var index = blockUntilAny(tasks)
while index != -1:
results.add ^cast[FlowVar[int]](tasks[index])
tasks.del(index)
#echo repr results
index = awaitAny(tasks)
index = blockUntilAny(tasks)
doAssert results.len == 5
doAssert 1000 in results

View file

@ -2,4 +2,4 @@
template serializationKey*(s: string) {.pragma.}
template defaultValue*(V: typed) {.pragma.}
template alternativeKey*(s: string = nil, V: typed) {.pragma.}
template alternativeKey*(s: string = "", V: typed) {.pragma.}

View file

@ -27,7 +27,7 @@ suite "captures":
let ex2 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
check(ex2.captures["foo"] == "foo")
check(ex2.captures["bar"] == nil)
check(ex2.captures["bar"] == "")
test "named capture bounds":
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
@ -41,7 +41,7 @@ suite "captures":
test "named capture table":
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
check(ex1.captures.toTable == {"foo" : "foo", "bar" : nil}.toTable())
check(ex1.captures.toTable == {"foo" : "foo", "bar" : ""}.toTable())
check(ex1.captureBounds.toTable == {"foo" : some(0..2), "bar" : none(Slice[int])}.toTable())
check(ex1.captures.toTable("") == {"foo" : "foo", "bar" : ""}.toTable())
@ -50,7 +50,7 @@ suite "captures":
test "capture sequence":
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
check(ex1.captures.toSeq == @["foo", nil])
check(ex1.captures.toSeq == @["foo", ""])
check(ex1.captureBounds.toSeq == @[some(0..2), none(Slice[int])])
check(ex1.captures.toSeq("") == @["foo", ""])

View file

@ -16,5 +16,5 @@ suite "replace":
check("123".replace(re"(?<foo>\d)(\d)", "${foo}$#$#") == "1123")
test "replacing missing captures should throw instead of segfaulting":
expect ValueError: discard "ab".replace(re"(a)|(b)", "$1$2")
expect ValueError: discard "b".replace(re"(a)?(b)", "$1$2")
discard "ab".replace(re"(a)|(b)", "$1$2")
discard "b".replace(re"(a)?(b)", "$1$2")

View file

@ -40,7 +40,7 @@ when isMainModule:
test: 18827361,
test2: "hello world",
test3: true,
testNil: nil
testNil: "nil"
)
let node = %x
@ -53,7 +53,7 @@ when isMainModule:
doAssert y.test == 18827361
doAssert y.test2 == "hello world"
doAssert y.test3
doAssert y.testNil.isNil
doAssert y.testNil == "nil"
# Test for custom object variants (without an enum) and with an else branch.
block:

View file

@ -1,2 +1,6 @@
var x = @["1", nil, "3"]
doAssert $x == "@[1, nil, 3]"
discard """
output: ""
"""
var x = @["1", "", "3"]
doAssert $x == """@["1", "", "3"]"""

View file

@ -199,6 +199,12 @@ proc testRFind =
assert "0123456789ABCDEFGAH".rfind({'A'..'C'}, 13) == 12
assert "0123456789ABCDEFGAH".rfind({'G'..'H'}, 13) == -1
proc testSplitLines() =
let fixture = "a\nb\rc\r\nd"
assert len(fixture.splitLines) == 4
assert splitLines(fixture) == @["a", "b", "c", "d"]
assert splitLines(fixture, keepEol=true) == @["a\n", "b\r", "c\r\n", "d"]
proc testCountLines =
proc assertCountLines(s: string) = assert s.countLines == s.splitLines.len
assertCountLines("")
@ -229,7 +235,7 @@ proc testParseInts =
assert "72".parseHexInt == 114
assert "FF".parseHexInt == 255
assert "ff".parseHexInt == 255
assert "fF".parseHexInt == 255
assert "fF".parseHexInt == 255
assert "0x7_2".parseHexInt == 114
rejectParse "".parseHexInt
rejectParse "_".parseHexInt
@ -252,6 +258,7 @@ proc testParseInts =
testDelete()
testFind()
testRFind()
testSplitLines()
testCountLines()
testParseInts()

29
tests/stdlib/tsugar.nim Normal file
View file

@ -0,0 +1,29 @@
discard """
file: "tsugar.nim"
output: ""
"""
import sugar
import macros
block distinctBase:
block:
type
Foo[T] = distinct seq[T]
var a: Foo[int]
doAssert a.type.distinctBase is seq[int]
block:
# simplified from https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458
macro uintImpl(bits: static[int]): untyped =
if bits >= 128:
let inner = getAST(uintImpl(bits div 2))
result = newTree(nnkBracketExpr, ident("UintImpl"), inner)
else:
result = ident("uint64")
type
BaseUint = UintImpl or SomeUnsignedInt
UintImpl[Baseuint] = object
Uint[bits: static[int]] = distinct uintImpl(bits)
doAssert Uint[128].distinctBase is UintImpl[uint64]

View file

@ -11,20 +11,17 @@ import
proc staticTz(hours, minutes, seconds: int = 0): Timezone {.noSideEffect.} =
let offset = hours * 3600 + minutes * 60 + seconds
proc zoneInfoFromTz(adjTime: Time): ZonedTime {.locks: 0.} =
proc zonedTimeFromAdjTime(adjTime: Time): ZonedTime {.locks: 0.} =
result.isDst = false
result.utcOffset = offset
result.adjTime = adjTime
result.time = adjTime + initDuration(seconds = offset)
proc zoneInfoFromUtc(time: Time): ZonedTime {.locks: 0.}=
proc zonedTimeFromTime(time: Time): ZonedTime {.locks: 0.}=
result.isDst = false
result.utcOffset = offset
result.adjTime = fromUnix(time.toUnix - offset)
result.name = ""
result.zoneInfoFromTz = zoneInfoFromTz
result.zoneInfoFromUtc = zoneInfoFromUtc
result.time = time
newTimezone("", zonedTimeFromTime, zonedTImeFromAdjTime)
# $ date --date='@2147483647'
# Tue 19 Jan 03:14:07 GMT 2038
@ -322,22 +319,7 @@ suite "ttimes":
parseTestExcp("-1 BC", "UUUU g")
test "dynamic timezone":
proc staticOffset(offset: int): Timezone =
proc zoneInfoFromTz(adjTime: Time): ZonedTime =
result.isDst = false
result.utcOffset = offset
result.adjTime = adjTime
proc zoneInfoFromUtc(time: Time): ZonedTime =
result.isDst = false
result.utcOffset = offset
result.adjTime = fromUnix(time.toUnix - offset)
result.name = ""
result.zoneInfoFromTz = zoneInfoFromTz
result.zoneInfoFromUtc = zoneInfoFromUtc
let tz = staticOffset(-9000)
let tz = staticTz(seconds = -9000)
let dt = initDateTime(1, mJan, 2000, 12, 00, 00, tz)
check dt.utcOffset == -9000
check dt.isDst == false

View file

@ -1,5 +1,5 @@
discard """
output: '''@[nil, nil, nil, nil, nil, nil, nil, "meh"]'''
output: '''@["", "", "", "", "", "", "", "meh"]'''
exitcode: "0"
"""

View file

@ -24,10 +24,10 @@ doAssert "nan" == $(0.0/0.0)
# nil tests
# maybe a bit inconsistent in types
var x: seq[string]
doAssert "nil" == $(x)
doAssert "@[]" == $(x)
var y: string = nil
doAssert nil == $(y)
var y: string
doAssert "" == $(y)
type
Foo = object
@ -54,7 +54,7 @@ doAssert $arr == "['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '
doAssert $cstring(unsafeAddr arr) == "Hello World!"
proc takes(c: cstring) =
doAssert c == ""
doAssert c == cstring""
proc testm() =
var x: string
@ -90,12 +90,8 @@ proc stringCompare() =
doAssert e == ""
doAssert "" == e
doAssert nil == e
doAssert e == nil
doAssert f == g
doAssert "" == ""
doAssert "" == nil
doAssert nil == ""
g.setLen(10)
doAssert g == "\0\0\0\0\0\0\0\0\0\0"

View file

@ -1,6 +1,6 @@
template makeDomElement(x: untyped, name: string = nil) =
const tag {.gensym.} = if name == nil: astToStr(x) else: name
template makeDomElement(x: untyped, name: string = "") =
const tag {.gensym.} = if name.len == 0: astToStr(x) else: name
proc x*(p: int|float) =
echo tag, p

View file

@ -2,7 +2,7 @@
# bug #2629
import sequtils, os
template glob_rst(basedir: string = nil): untyped =
template glob_rst(basedir: string = ""): untyped =
if baseDir.isNil:
to_seq(walk_files("*.rst"))
else:

View file

@ -76,7 +76,7 @@ proc flagTests(r: var TResults, cat: Category, options: string) =
testExec r, makeTest(filename, " cmd /c cd " & nimcache &
" && compile_tgenscript.bat", cat)
when defined(linux):
elif defined(posix):
testExec r, makeTest(filename, " sh -c \"cd " & nimcache &
" && sh compile_tgenscript.sh\"", cat)
@ -109,10 +109,14 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) =
safeCopyFile("lib" / nimrtlDll, "tests/dll" / nimrtlDll)
else:
# posix relies on crappy LD_LIBRARY_PATH (ugh!):
var libpath = getEnv"LD_LIBRARY_PATH".string
const libpathenv = when defined(haiku):
"LIBRARY_PATH"
else:
"LD_LIBRARY_PATH"
var libpath = getEnv(libpathenv).string
# Temporarily add the lib directory to LD_LIBRARY_PATH:
putEnv("LD_LIBRARY_PATH", "tests/dll" & (if libpath.len > 0: ":" & libpath else: ""))
defer: putEnv("LD_LIBRARY_PATH", libpath)
putEnv(libpathenv, "tests/dll" & (if libpath.len > 0: ":" & libpath else: ""))
defer: putEnv(libpathenv, libpath)
var nimrtlDll = DynlibFormat % "nimrtl"
safeCopyFile("lib" / nimrtlDll, "tests/dll" / nimrtlDll)
@ -256,6 +260,8 @@ proc jsTests(r: var TResults, cat: Category, options: string) =
# ------------------------- nim in action -----------
proc testNimInAction(r: var TResults, cat: Category, options: string) =
let options = options & " --nilseqs:on"
template test(filename: untyped, action: untyped) =
testSpec r, makeTest(filename, options, cat, action)
@ -482,8 +488,12 @@ proc processCategory(r: var TResults, cat: Category, options: string) =
compileRodFiles(r, cat, options)
runRodFiles(r, cat, options)
of "js":
# XXX JS doesn't need to be special anymore
jsTests(r, cat, options)
# only run the JS tests on Windows or Linux because Travis is bad
# and other OSes like Haiku might lack nodejs:
if not defined(linux) and isTravis:
discard
else:
jsTests(r, cat, options)
of "dll":
dllTests(r, cat, options)
of "flags":
@ -521,5 +531,9 @@ proc processCategory(r: var TResults, cat: Category, options: string) =
# We can't test it because it depends on a third party.
discard # TODO: Move untestable tests to someplace else, i.e. nimble repo.
else:
var testsRun = 0
for name in os.walkFiles("tests" & DirSep &.? cat.string / "t*.nim"):
testSpec r, makeTest(name, options, cat)
inc testsRun
if testsRun == 0:
echo "[Warning] - Invalid category specified \"", cat.string, "\", no tests were run"

View file

@ -12,8 +12,8 @@ import parseutils, strutils, os, osproc, streams, parsecfg
var compilerPrefix* = "compiler" / "nim "
let isTravis = existsEnv("TRAVIS")
let isAppVeyor = existsEnv("APPVEYOR")
let isTravis* = existsEnv("TRAVIS")
let isAppVeyor* = existsEnv("APPVEYOR")
proc cmdTemplate*(): string =
compilerPrefix & "$target --lib:lib --hints:on -d:testing $options $file"

View file

@ -22,7 +22,7 @@ const
Command:
all run all tests
c|category <category> run all the tests of a certain category
c|cat|category <category> run all the tests of a certain category
r|run <test> run single test file
html generate $1 from the database
Arguments:
@ -262,6 +262,7 @@ proc codegenCheck(test: TTest, target: TTarget, spec: TSpec, expectedMsg: var st
echo getCurrentExceptionMsg()
except IOError:
given.err = reCodeNotFound
echo getCurrentExceptionMsg()
proc nimoutCheck(test: TTest; expectedNimout: string; given: var TSpec) =
let exp = expectedNimout.strip.replace("\C\L", "\L")
@ -509,7 +510,8 @@ proc main() =
backend.close()
var failed = r.total - r.passed - r.skipped
if failed != 0:
echo "FAILURE! total: ", r.total, " passed: ", r.passed, " skipped: ", r.skipped
echo "FAILURE! total: ", r.total, " passed: ", r.passed, " skipped: ",
r.skipped, " failed: ", failed
quit(QuitFailure)
if paramCount() == 0:

16
tests/threads/t8535.nim Normal file
View file

@ -0,0 +1,16 @@
discard """
output: "0"
"""
type
CircAlloc* [Size: static[int] , T] = tuple
baseArray : array[Size,T]
index : uint16
type
Job = object of RootObj
var foo {.threadvar.}: CircAlloc[1,Job]
when isMainModule:
echo foo.index

View file

@ -5,9 +5,9 @@ discard """
import actors
var
pool: TActorPool[int, void]
pool: ActorPool[int, void]
createActorPool(pool)
for i in 0 .. < 300:
for i in 0 ..< 300:
pool.spawn(i, proc (x: int) {.thread.} = echo x)
pool.join()

View file

@ -73,7 +73,7 @@ type
const
DefaultPrec = 6 ## Default precision for floating point numbers.
DefaultFmt: Format = (ftDefault, -1, -1, nil, faDefault, fsMinus, false, false, false, nil)
DefaultFmt: Format = (ftDefault, -1, -1, "", faDefault, fsMinus, false, false, false, "")
## Default format corresponding to the empty format string, i.e.
## `x.format("") == x.format(DefaultFmt)`.
round_nums = [0.5, 0.05, 0.005, 0.0005, 0.00005, 0.000005, 0.0000005, 0.00000005]
@ -124,7 +124,7 @@ proc parse(fmt: string): Format {.nosideeffect.} =
if fmt.rawmatch(p, 0, caps) < 0:
raise newException(FormatError, "Invalid format string")
result.fill = fmt.get(caps, 0, nil)
result.fill = fmt.get(caps, 0, "")
case fmt.get(caps, 1, 0.char)
of '<': result.align = faLeft
@ -144,7 +144,7 @@ proc parse(fmt: string): Format {.nosideeffect.} =
result.width = fmt.get(caps, 4, -1)
if caps.has(4) and fmt[caps.bounds(4).first] == '0':
if result.fill != nil:
if result.fill != "":
raise newException(FormatError, "Leading 0 in with not allowed with explicit fill character")
if result.align != faDefault:
raise newException(FormatError, "Leading 0 in with not allowed with explicit alignment")
@ -171,7 +171,7 @@ proc parse(fmt: string): Format {.nosideeffect.} =
of '%': result.typ = ftPercent
else: result.typ = ftDefault
result.arysep = fmt.get(caps, 8, nil, 1)
result.arysep = fmt.get(caps, 8, "", 1)
proc getalign(fmt: Format; defalign: FmtAlign; slen: int) : tuple[left, right:int] {.nosideeffect.} =
## Returns the number of left and right padding characters for a
@ -218,7 +218,7 @@ proc writefill(o: var Writer; fmt: Format; n: int; signum: int = 0) =
elif fmt.sign == fsPlus: write(o, '+')
elif fmt.sign == fsSpace: write(o, ' ')
if fmt.fill == nil:
if fmt.fill.len == 0:
for i in 1..n: write(o, ' ')
else:
for i in 1..n:
@ -626,19 +626,19 @@ proc splitfmt(s: string): seq[Part] {.compiletime, nosideeffect.} =
else:
lvl.dec
let clpos = pos
var fmtpart = Part(kind: pkFmt, arg: -1, fmt: s.substr(oppos+1, clpos-1), field: nil, index: int.high, nested: nested)
var fmtpart = Part(kind: pkFmt, arg: -1, fmt: s.substr(oppos+1, clpos-1), field: "", index: int.high, nested: nested)
if fmtpart.fmt.len > 0:
var m: array[0..3, string]
if not fmtpart.fmt.match(subpeg, m):
error("invalid format string")
if m[1] != nil and m[1].len > 0:
if m[1].len > 0:
fmtpart.field = m[1].substr(1)
if m[2] != nil and m[2].len > 0:
if m[2].len > 0:
discard parseInt(m[2].substr(1, m[2].len-2), fmtpart.index)
if m[0].len > 0: discard parseInt(m[0], fmtpart.arg)
if m[3] == nil or m[3].len == 0:
if m[3].len == 0:
fmtpart.fmt = ""
elif m[3][0] == ':':
fmtpart.fmt = m[3].substr(1)
@ -650,7 +650,7 @@ proc splitfmt(s: string): seq[Part] {.compiletime, nosideeffect.} =
proc literal(s: string): NimNode {.compiletime, nosideeffect.} =
## Return the nim literal of string `s`. This handles the case if
## `s` is nil.
result = if s == nil: newNilLit() else: newLit(s)
result = newLit(s)
proc literal(b: bool): NimNode {.compiletime, nosideeffect.} =
## Return the nim literal of boolean `b`. This is either `true`
@ -713,7 +713,7 @@ proc generatefmt(fmtstr: string;
args[arg].cnt = args[arg].cnt + 1
arg.inc
# possible field access
if part.field != nil and part.field.len > 0:
if part.field.len > 0:
argexpr = newDotExpr(argexpr, part.field.ident)
# possible array access
if part.index < int.high:
@ -724,7 +724,7 @@ proc generatefmt(fmtstr: string;
# nested format string. Compute the format string by
# concatenating the parts of the substring.
for e in generatefmt(part.fmt, args, arg):
var newexpr = if part.fmt == nil: e.val else: newCall(bindsym"format", e.val, e.fmt)
var newexpr = if part.fmt.len == 0: e.val else: newCall(bindsym"format", e.val, e.fmt)
if fmtexpr != nil and fmtexpr.kind != nnkNilLit:
fmtexpr = infix(fmtexpr, "&", newexpr)
else:

View file

@ -3,8 +3,8 @@ discard """
@[1, 2, 3]'''
"""
template foo(s: string = nil) =
if isNil(s):
template foo(s: string = "") =
if s.len == 0:
echo "it's nil"
else:
echo s

View file

@ -22,7 +22,7 @@ when true:
import os
type
In_out = tuple[src, dest, options: string]
In_out = tuple[src, dest: string, options: ref int]
let
nil_var: In_out = ("hey"/"there", "something", nil)

View file

@ -39,7 +39,7 @@ proc newIdent*(node: NimNode): Ident =
raise newException(ValueError, msg)
proc render*(i: Ident): NimNode {.compileTime.} =
if i.name == nil:
if i.name == "":
return newNimNode(nnkEmpty)
if i.exported:
@ -67,7 +67,7 @@ proc newBracket*(node: NimNode): Bracket =
raise newException(ValueError, msg)
# Field procs
proc newField*(identifier: Ident, type_name: string, default: string = nil): Field =
proc newField*(identifier: Ident, type_name: string, default: string = ""): Field =
result.identifier = identifier
result.type_name = type_name
result.default = default
@ -84,7 +84,7 @@ proc newField*(node: NimNode): Field =
of nnkIdent:
result.default = $(node[2])
else:
result.default = nil
result.default = ""
else:
let msg = "newField cannot initialize from node kind: " & $(node.kind)
raise newException(ValueError, msg)
@ -102,7 +102,7 @@ proc newFieldSeq*(node: NimNode): FieldSeq =
of nnkIdent:
default = $(default_node)
else:
default = nil
default = ""
for i in 0..node.len - 3:
let name = newIdent(node[i])
result.add(newField(name, type_name, default))
@ -115,8 +115,8 @@ proc newFieldSeq*(node: NimNode): FieldSeq =
proc render*(f: Field): NimNode {.compileTime.} =
let identifier = f.identifier.render()
let type_name = if f.type_name != nil: ident(f.type_name) else: newEmptyNode()
let default = if f.default != nil: ident(f.default) else: newEmptyNode()
let type_name = if f.type_name != "": ident(f.type_name) else: newEmptyNode()
let default = if f.default != "": ident(f.default) else: newEmptyNode()
newIdentDefs(identifier, type_name, default)
proc render*(fs: FieldSeq): NimNode {.compileTime.} =
@ -127,7 +127,7 @@ proc render*(fs: FieldSeq): NimNode {.compileTime.} =
# TypeDef procs
proc newTypeDef*(identifier: Ident, is_ref = false,
object_type = "object",
base_type: string = nil): TypeDef {.compileTime.} =
base_type: string = ""): TypeDef {.compileTime.} =
result.identifier = identifier
result.fields = @[]
result.is_ref = is_ref
@ -165,7 +165,7 @@ proc render*(typedef: TypeDef): NimNode {.compileTime.} =
result.add(newEmptyNode())
let object_node = newNimNode(nnkObjectTy)
object_node.add(newEmptyNode())
if typedef.base_type == nil:
if typedef.base_type == "":
object_node.add(newEmptyNode())
else:
var base_type = newNimNode(nnkOfInherit)
@ -195,8 +195,8 @@ proc render*(typeseq: TypeDefSeq): NimNode {.compileTime.} =
for typedef in typeseq:
result.add(typedef.render())
proc newProc*(identifier: Ident, params: FieldSeq = nil,
returns: Ident, generics: FieldSeq = nil): Proc =
proc newProc*(identifier: Ident, params: FieldSeq = @[],
returns: Ident, generics: FieldSeq = @[]): Proc =
result.identifier = identifier
result.params = params
result.returns = returns
@ -209,7 +209,7 @@ proc newProc*(node: NimNode): Proc =
case node[2].kind:
of nnkGenericParams:
result.generics = newFieldSeq(node[2])
else: result.generics = nil
else: result.generics = @[]
let formal_params = node[3]
case formal_params[0].kind:
of nnkIdent:

View file

@ -11,7 +11,7 @@ FOO: blah'''
import macros, sequtils, tables
import strutils
import future, meta
import sugar, meta
type
Component = object

View file

@ -22,14 +22,14 @@ template test(typename, default: untyped) =
result = newSeq[typename]()
result.add(default)
result.setLen(3)
for i in 0 .. <2:
for i in 0 ..< 2:
result[i] = default
const constval = `abc typename`()
doAssert(constval == `abc typename`())
proc `arr typename`(): array[4, typename] =
for i in 0 .. <2:
for i in 0 ..< 2:
result[i] = default
const constarr = `arr typename`()
doAssert(constarr == `arr typename`())

View file

@ -20,16 +20,16 @@ proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: NimNode): tuple[tests:
var testObj = SuiteTest()
if suiteName.kind == nnkNilLit:
testObj.suiteName = nil
testObj.suiteName = ""
else:
testObj.suiteName = $suiteName
if suiteDesc.kind == nnkNilLit:
testObj.suiteDesc = nil
testObj.suiteDesc = ""
else:
testObj.suiteDesc = suiteDesc.strVal
testObj.testName = $child[1] # should not ever be nil
if child[2].kind == nnkNilLit:
testObj.testDesc = nil
testObj.testDesc = ""
else:
testObj.testDesc = child[2].strVal
testObj.testBlock = child[1]
@ -46,5 +46,5 @@ macro suite(suiteName, suiteDesc, suiteBloc: untyped): typed =
# Test above
suite basics, "Description of such":
test(t5, nil):
test(t5, ""):
assert false