Merge branch 'devel' into uint-range-checks

This commit is contained in:
Araq 2019-09-02 10:27:35 +02:00
commit e765687646
116 changed files with 2434 additions and 2820 deletions

View file

@ -143,5 +143,5 @@ block tsubrange:
var level: n16 = 1
let maxLevel: n16 = 1
level = min(level + 2, maxLevel)
level = min(level + 2, maxLevel).n16
doAssert level == 1

View file

@ -6,6 +6,74 @@ action: compile
import ../ast_pattern_matching
template expectNimNode(arg: untyped): NimNode = arg
## This template here is just to be injected by `myquote`, so that
## a nice error message appears when the captured symbols are not of
## type `NimNode`.
proc substitudeComments(symbols, values, n: NimNode): NimNode =
## substitudes all nodes of kind nnkCommentStmt to parameter
## symbols. Consumes the argument `n`.
if n.kind == nnkCommentStmt:
values.add newCall(bindSym"newCommentStmtNode", newLit(n.strVal))
# Gensym doesn't work for parameters. These identifiers won't
# clash unless an argument is constructed to clash here.
symbols.add ident("comment" & $values.len & "_XObBdOnh6meCuJK2smZV")
return symbols[^1]
for i in 0 ..< n.len:
n[i] = substitudeComments(symbols, values, n[i])
return n
macro myquote*(args: varargs[untyped]): untyped =
expectMinLen(args, 1)
# This is a workaround for #10430 where comments are removed in
# template expansions. This workaround lifts all comments
# statements to be arguments of the temporary template.
let extraCommentSymbols = newNimNode(nnkBracket)
let extraCommentGenExpr = newNimNode(nnkBracket)
let body = substitudeComments(
extraCommentSymbols, extraCommentGenExpr, args[^1]
)
let formalParams = nnkFormalParams.newTree(ident"untyped")
for i in 0 ..< args.len-1:
formalParams.add nnkIdentDefs.newTree(
args[i], ident"untyped", newEmptyNode()
)
for sym in extraCommentSymbols:
formalParams.add nnkIdentDefs.newTree(
sym, ident"untyped", newEmptyNode()
)
let templateSym = genSym(nskTemplate)
let templateDef = nnkTemplateDef.newTree(
templateSym,
newEmptyNode(),
newEmptyNode(),
formalParams,
nnkPragma.newTree(ident"dirty"),
newEmptyNode(),
args[^1]
)
let templateCall = newCall(templateSym)
for i in 0 ..< args.len-1:
let symName = args[i]
# identifiers and quoted identifiers are allowed.
if symName.kind == nnkAccQuoted:
symName.expectLen 1
symName[0].expectKind nnkIdent
else:
symName.expectKind nnkIdent
templateCall.add newCall(bindSym"expectNimNode", symName)
for expr in extraCommentGenExpr:
templateCall.add expr
let getAstCall = newCall(bindSym"getAst", templateCall)
result = newStmtList(templateDef, getAstCall)
macro testAddrAst(arg: typed): bool =
arg.expectKind nnkStmtListExpr
arg[0].expectKind(nnkVarSection)
@ -49,34 +117,35 @@ static:
echo "OK"
testPattern nnkIntLit(intVal = 42) , 42
testPattern nnkInt8Lit(intVal = 42) , 42'i8
testPattern nnkInt16Lit(intVal = 42) , 42'i16
testPattern nnkInt32Lit(intVal = 42) , 42'i32
testPattern nnkInt64Lit(intVal = 42) , 42'i64
testPattern nnkUInt8Lit(intVal = 42) , 42'u8
testPattern nnkUInt16Lit(intVal = 42) , 42'u16
testPattern nnkUInt32Lit(intVal = 42) , 42'u32
testPattern nnkUInt64Lit(intVal = 42) , 42'u64
#testPattern nnkFloat64Lit(floatVal = 42.0) , 42.0
testPattern nnkFloat32Lit(floatVal = 42.0) , 42.0'f32
#testPattern nnkFloat64Lit(floatVal = 42.0) , 42.0'f64
testPattern nnkStrLit(strVal = "abc") , "abc"
testPattern nnkRStrLit(strVal = "abc") , r"abc"
testPattern nnkTripleStrLit(strVal = "abc") , """abc"""
testPattern nnkCharLit(intVal = 32) , ' '
testPattern nnkNilLit() , nil
testPattern nnkIdent(strVal = "myIdentifier") , myIdentifier
testPattern nnkIntLit(intVal = 42), 42
testPattern nnkInt8Lit(intVal = 42), 42'i8
testPattern nnkInt16Lit(intVal = 42), 42'i16
testPattern nnkInt32Lit(intVal = 42), 42'i32
testPattern nnkInt64Lit(intVal = 42), 42'i64
testPattern nnkUInt8Lit(intVal = 42), 42'u8
testPattern nnkUInt16Lit(intVal = 42), 42'u16
testPattern nnkUInt32Lit(intVal = 42), 42'u32
testPattern nnkUInt64Lit(intVal = 42), 42'u64
#testPattern nnkFloat64Lit(floatVal = 42.0), 42.0
testPattern nnkFloat32Lit(floatVal = 42.0), 42.0'f32
#testPattern nnkFloat64Lit(floatVal = 42.0), 42.0'f64
testPattern nnkStrLit(strVal = "abc"), "abc"
testPattern nnkRStrLit(strVal = "abc"), r"abc"
testPattern nnkTripleStrLit(strVal = "abc"), """abc"""
testPattern nnkCharLit(intVal = 32), ' '
testPattern nnkNilLit(), nil
testPattern nnkIdent(strVal = "myIdentifier"), myIdentifier
testPatternFail nnkInt8Lit(intVal = 42), 42'i16
testPatternFail nnkInt16Lit(intVal = 42), 42'i8
testPatternFail nnkInt8Lit(intVal = 42) , 42'i16
testPatternFail nnkInt16Lit(intVal = 42) , 42'i8
# this should be just `block` but it doesn't work that way anymore because of VM.
macro scope(arg: untyped): untyped =
let procSym = genSym(nskProc)
result = quote do:
proc `procSym`(): void {.compileTime.} =
proc `procSym`() {.compileTime.} =
`arg`
`procSym`()
@ -85,7 +154,7 @@ static:
## Command call
scope:
let ast = quote do:
let ast = myquote:
echo "abc", "xyz"
ast.matchAst:
@ -95,7 +164,7 @@ static:
## Call with ``()``
scope:
let ast = quote do:
let ast = myquote:
echo("abc", "xyz")
ast.matchAst:
@ -140,7 +209,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
? "xyz"
ast.matchAst(err):
@ -155,7 +224,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
proc identifier*
ast[0].matchAst(err):
@ -185,7 +254,7 @@ static:
## Call with raw string literal
scope:
let ast = quote do:
let ast = myquote:
echo"abc"
@ -230,7 +299,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
cast[T](x)
ast.matchAst:
@ -242,7 +311,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
x.y
ast.matchAst:
@ -264,7 +333,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
(1, 2, (3))
ast.matchAst:
@ -276,7 +345,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
{1, 2, 3}
ast.matchAst:
@ -285,7 +354,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
{a: 3, b: 5}
ast.matchAst:
@ -300,7 +369,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
[1, 2, 3]
ast.matchAst:
@ -312,7 +381,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
1..3
ast.matchAst:
@ -328,7 +397,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
if cond1: expr1 elif cond2: expr2 else: expr3
ast.matchAst:
@ -343,7 +412,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
## This is a comment
## This is part of the first comment
stmt1
@ -357,12 +426,12 @@ static:
):
echo "ok"
else:
echo "NOT OK!!!"
echo "warning!"
echo ast.treeRepr
echo "TEST causes no fail, because of a regression in Nim."
scope:
let ast = quote do:
let ast = myquote:
{.emit: "#include <stdio.h>".}
ast.matchAst:
@ -375,7 +444,7 @@ static:
echo "ok"
scope:
let ast = quote do:
let ast = myquote:
{.pragma: cdeclRename, cdecl.}
ast.matchAst:
@ -391,7 +460,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
if cond1:
stmt1
elif cond2:
@ -413,7 +482,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
x = 42
ast.matchAst:
@ -423,7 +492,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
stmt1
stmt2
stmt3
@ -439,7 +508,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
case expr1
of expr2, expr3..expr4:
stmt1
@ -464,7 +533,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
while expr1:
stmt1
@ -477,7 +546,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
for ident1, ident2 in expr1:
stmt1
@ -490,7 +559,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
try:
stmt1
except e1, e2:
@ -517,7 +586,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
return expr1
ast.matchAst:
@ -528,7 +597,7 @@ static:
## Continue statement
scope:
let ast = quote do:
let ast = myquote:
continue
ast.matchAst:
@ -539,7 +608,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
break otherLocation
ast.matchAst:
@ -550,10 +619,12 @@ static:
scope:
let ast = quote do:
template blockStatement {.dirty.} =
block name:
discard
let ast = getAst(blockStatement())
ast.matchAst:
of nnkBlockStmt(ident"name", nnkStmtList):
echo "ok"
@ -562,7 +633,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
asm """some asm"""
ast.matchAst:
@ -576,7 +647,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
import math
ast.matchAst:
@ -585,7 +656,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
import math except pow
ast.matchAst:
@ -594,7 +665,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
import strutils as su
ast.matchAst:
@ -611,7 +682,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
from math import pow
ast.matchAst:
@ -622,7 +693,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
export unsigned
ast.matchAst:
@ -631,7 +702,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
export math except pow # we're going to implement our own exponentiation
ast.matchAst:
@ -642,7 +713,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
include blocks
ast.matchAst:
@ -653,7 +724,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
var a = 3
ast.matchAst:
@ -670,7 +741,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
let a = 3
ast.matchAst:
@ -687,7 +758,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
const a = 3
ast.matchAst:
@ -704,7 +775,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
type A = int
ast.matchAst:
@ -719,7 +790,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
type MyInt = distinct int
ast.peelOff({nnkTypeSection}).matchAst:
@ -735,7 +806,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
type A[T] = expr1
ast.matchAst:
@ -757,7 +828,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
type IO = object of RootObj
ast.peelOff(nnkTypeSection).matchAst:
@ -840,7 +911,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
type X = enum
First
@ -853,7 +924,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
type Con = concept x,y,z
(x & y & z) is string
@ -865,7 +936,7 @@ static:
scope:
let astX = quote do:
let astX = myquote:
type
A[T: static[int]] = object
@ -880,7 +951,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
type MyProc[T] = proc(x: T)
ast.peelOff({nnkStmtList, nnkTypeSection}).matchAst(err):
@ -952,7 +1023,7 @@ static:
proc hello*[T: SomeInteger](x: int = 3, y: float32): int {.inline.} = discard
scope:
var ast = quote do:
var ast = myquote:
proc foobar(a, b: int): void
ast = ast[3]
@ -971,7 +1042,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
proc hello(): var int
ast[3].matchAst: # subAst
@ -986,7 +1057,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
iterator nonsense[T](x: seq[T]): float {.closure.} =
discard
@ -998,7 +1069,7 @@ static:
scope:
let ast = quote do:
let ast = myquote:
converter toBool(x: float): bool
ast.matchAst:
@ -1008,7 +1079,7 @@ static:
## Template declaration
scope:
let ast = quote do:
let ast = myquote:
template optOpt{expr1}(a: int): int
ast.matchAst:

View file

@ -12,4 +12,7 @@ proc f3(_: typedesc) = discard
f3(typeof(nil))
proc f4[T](_: T) = discard
f4(nil)
f4(nil)
proc f5(): typeof(nil) = nil
discard f5()

View file

@ -0,0 +1,18 @@
discard """
cmd: '''nim c --newruntime $file'''
output: '''
showing original type, length, and contents seq[int] 1 @[42]
copy length and contents 1 @[42]
'''
"""
proc test() =
var sq1 = @[42]
echo "showing original type, length, and contents ", sq1.typeof, " ", sq1.len, " ", sq1
doAssert cast[int](sq1[0].unsafeAddr) != 0
var sq2 = sq1 # copy of original
echo "copy length and contents ", sq2.len, " ", sq2
doAssert cast[int](sq2[0].unsafeAddr) != 0
doAssert cast[int](sq1[0].unsafeAddr) != 0
test()

View file

@ -0,0 +1,14 @@
discard """
errmsg: "cannot bind another '=destroy' to: Obj; previous declaration was constructed here implicitly: tdestructor_too_late.nim(7, 16)"
"""
type Obj* = object
v*: int
proc something(this: sink Obj) =
discard
proc `=destroy`(this: var Obj) =
echo "igotdestroyed"
this.v = -1
var test* = Obj(v: 42)

View file

@ -175,4 +175,19 @@ proc myfuncLoop(x: int): MySeqNonCopyable =
var cc = newMySeq(i, 5.0)
result = cc
discard myfuncLoop(3)
discard myfuncLoop(3)
#------------------------------------------------------------
# Move into table via openarray
#------------------------------------------------------------
type
TableNonCopyable = object
x: seq[(string, MySeqNonCopyable)]
proc toTable(pairs: sink openArray[(string, MySeqNonCopyable)]): TableNonCopyable =
discard
let mytable = {"a": newMySeq(2, 5.0)}.toTable

View file

@ -75,5 +75,13 @@ proc selfAssign =
selfAssign()
# bug #11833
type FooAt = object
proc testWrongAt() =
var x = @[@[FooAt()]]
testWrongAt()
let (a, d) = allocCounters()
discard cprintf("%ld new: %ld\n", a - unpairedEnvAllocs() - d, allocs)

View file

@ -2,7 +2,6 @@ discard """
cmd: '''nim c --newruntime $file'''
output: '''@[1]
@[116, 101, 115, 116]
test
@[1953719668, 875770417]'''
"""
@ -13,7 +12,7 @@ echo cast[seq[uint8]](@[1])
echo cast[seq[uint8]]("test")
discard cast[string](@[116'u8, 101, 115, 116])
echo cast[string](@[116'u8, 101, 115, 116])
#echo cast[string](@[116'u8, 101, 115, 116, 0])
var a = cast[seq[uint32]]("test1234")
a.setLen(2)
echo a

View file

@ -13,3 +13,18 @@ echo a.str
beforeCodeReload:
echo " 2: before!"
# testing a construct of 2 functions in the same module which reference each other
# https://github.com/nim-lang/Nim/issues/11608
proc rec_1(depth: int)
proc rec_2(depth: int) =
rec_1(depth + 1)
proc rec_1(depth: int) =
if depth < 3:
rec_2(depth)
else:
echo("max mutual recursion reached!")
# https://github.com/nim-lang/Nim/issues/11996
let rec_2_func_ref = rec_2
rec_2_func_ref(0)

View file

@ -29,6 +29,7 @@ main: hasAnyModuleChanged? true
0: before - improved!
main: before
2: random string
max mutual recursion reached!
1
bar
0: after - closure iterator: 0

17
tests/errmsgs/t5870.nim Normal file
View file

@ -0,0 +1,17 @@
discard """
errormsg: "invalid type for const: seq[SomeRefObj]"
line: 14
"""
# bug #5870
type SomeRefObj = ref object of RootObj
someIntMember: int
proc createSomeRefObj(v: int): SomeRefObj=
result.new()
result.someIntMember = v
const compileTimeSeqOfRefObjs = @[createSomeRefObj(100500), createSomeRefObj(2)]
for i in 0..1:
echo compileTimeSeqOfRefObjs[i].someIntMember

View file

@ -36,7 +36,7 @@ tsigmatch.nim(143, 13) Error: type mismatch: got <array[0..0, proc (x: int){.gcs
but expected one of:
proc takesFuncs(fs: openArray[proc (x: int) {.gcsafe, locks: 0.}])
first type mismatch at position: 1
required type for fs: openarray[proc (x: int){.closure, gcsafe, locks: 0.}]
required type for fs: openArray[proc (x: int){.closure, gcsafe, locks: 0.}]
but expression '[proc (x: int) {.gcsafe, locks: 0.} = echo [x]]' is of type: array[0..0, proc (x: int){.gcsafe, locks: 0.}]
expression: takesFuncs([proc (x: int) {.gcsafe, locks: 0.} = echo [x]])

View file

@ -6,11 +6,11 @@ twrong_at_operator.nim(22, 30) Error: type mismatch: got <array[0..0, type int]>
but expected one of:
proc `@`[T](a: openArray[T]): seq[T]
first type mismatch at position: 1
required type for a: openarray[T]
required type for a: openArray[T]
but expression '[int]' is of type: array[0..0, type int]
proc `@`[IDX, T](a: array[IDX, T]): seq[T]
proc `@`[IDX, T](a: sink array[IDX, T]): seq[T]
first type mismatch at position: 1
required type for a: array[IDX, T]
required type for a: sink array[IDX, T]
but expression '[int]' is of type: array[0..0, type int]
expression: @[int]

View file

@ -27,13 +27,11 @@ method eval(e: ref TPlusExpr): int =
proc newLit(x: int): ref TLiteral =
new(result)
{.watchpoint: result.}
result.x = x
result.op1 = $getOccupiedMem()
proc newPlus(a, b: ref TExpr): ref TPlusExpr =
new(result)
{.watchpoint: result.}
result.a = a
result.b = b
result.op2 = $getOccupiedMem()

View file

@ -110,7 +110,7 @@ proc setNestingLevel(self: ref SimpleLoop, level: int) =
self.nestingLevel = level
if level == 0: self.isRoot = true
var loop_counter: int = 0
var loopCounter: int = 0
type
Lsg = object
@ -119,8 +119,8 @@ type
proc createNewLoop(self: var Lsg): ref SimpleLoop =
result = newSimpleLoop()
loop_counter += 1
result.counter = loop_counter
loopCounter += 1
result.counter = loopCounter
proc addLoop(self: var Lsg, l: ref SimpleLoop) =
self.loops.add l
@ -170,13 +170,13 @@ proc union(self: ref UnionFindNode, unionFindNode: ref UnionFindNode) =
const
BB_TOP = 0 # uninitialized
BB_NONHEADER = 1 # a regular BB
BB_REDUCIBLE = 2 # reducible loop
BB_SELF = 3 # single BB loop
BB_IRREDUCIBLE = 4 # irreducible loop
BB_DEAD = 5 # a dead BB
BB_LAST = 6 # Sentinel
BB_TOP = 0 # uninitialized
BB_NONHEADER = 1 # a regular BB
BB_REDUCIBLE = 2 # reducible loop
BB_SELF = 3 # single BB loop
BB_IRREDUCIBLE = 4 # irreducible loop
BB_DEAD = 5 # a dead BB
BB_LAST = 6 # Sentinel
# # Marker for uninitialized nodes.
UNVISITED = -1
@ -196,7 +196,9 @@ proc newHavlakLoopFinder(cfg: Cfg, lsg: Lsg): HavlakLoopFinder =
proc isAncestor(w: int, v: int, last: seq[int]): bool =
w <= v and v <= last[w]
proc dfs(currentNode: ref BasicBlock, nodes: var seq[ref UnionFindNode], number: var Table[ref BasicBlock, int], last: var seq[int], current: int): int =
proc dfs(currentNode: ref BasicBlock, nodes: var seq[ref UnionFindNode],
number: var Table[ref BasicBlock, int],
last: var seq[int], current: int): int =
var stack = @[(currentNode, current)]
while stack.len > 0:
let (currentNode, current) = stack.pop()
@ -215,13 +217,13 @@ proc findLoops(self: var HavlakLoopFinder): int =
if startNode == nil: return 0
var size = self.cfg.getNumNodes
var nonBackPreds = newSeq[HashSet[int]]()
var backPreds = newSeq[seq[int]]()
var number = initTable[ref BasicBlock, int]()
var header = newSeq[int](size)
var types = newSeq[int](size)
var last = newSeq[int](size)
var nodes = newSeq[ref UnionFindNode]()
var nonBackPreds = newSeq[HashSet[int]]()
var backPreds = newSeq[seq[int]]()
var number = initTable[ref BasicBlock, int]()
var header = newSeq[int](size)
var types = newSeq[int](size)
var last = newSeq[int](size)
var nodes = newSeq[ref UnionFindNode]()
for i in 1..size:
nonBackPreds.add initSet[int](1)

View file

@ -27,3 +27,62 @@ for a in items(arr):
echo ""
#--------------------------------------------------------------------
# Lent iterators
#--------------------------------------------------------------------
type
NonCopyable = object
x: int
proc `=destroy`(o: var NonCopyable) =
discard
proc `=copy`(dst: var NonCopyable, src: NonCopyable) {.error.}
proc `=sink`(dst: var NonCopyable, src: NonCopyable) =
dst.x = src.x
iterator lentItems[T](a: openarray[T]): lent T =
for i in 0..a.high:
yield a[i]
iterator lentPairs[T](a: array[0..1, T]): tuple[key: int, val: lent T] =
for i in 0..a.high:
yield (i, a[i])
let arr1 = [1, 2, 3]
let arr2 = @["a", "b", "c"]
let arr3 = [NonCopyable(x: 1), NonCopyable(x: 2)]
let arr4 = @[(1, "a"), (2, "b"), (3, "c")]
var accum: string
for x in lentItems(arr1):
accum &= $x
doAssert(accum == "123")
accum = ""
for x in lentItems(arr2):
accum &= $x
doAssert(accum == "abc")
accum = ""
for val in lentItems(arr3):
accum &= $val.x
doAssert(accum == "12")
accum = ""
for i, val in lentPairs(arr3):
accum &= $i & "-" & $val.x & " "
doAssert(accum == "0-1 1-2 ")
accum = ""
for i, val in lentItems(arr4):
accum &= $i & "-" & $val & " "
doAssert(accum == "1-a 2-b 3-c ")
accum = ""
for (i, val) in lentItems(arr4):
accum &= $i & "-" & $val & " "
doAssert(accum == "1-a 2-b 3-c ")

View file

@ -48,3 +48,27 @@ doAssert hasDefault2(int) == "int"
doAssert hasDefault2(string) == "string"
doAssert hasDefault2() == "string"
# bug #9195
type
Error = enum
erA, erB, erC
Result[T, U] = object
x: T
u: U
PB = object
proc decodeUVarint*(itzzz: typedesc[SomeUnsignedInt],
data: openArray[char]): Result[itzzz, Error] =
result = Result[itzzz, Error](x: 0, u: erC)
discard decodeUVarint(uint32, "abc")
type
X = object
Y[T] = object
proc testObj(typ: typedesc[object]): Y[typ] =
discard
discard testObj(X)

View file

@ -14,3 +14,32 @@ block: # isNamedTuple
doAssert not Foo3.isNamedTuple
doAssert not Foo4.isNamedTuple
doAssert not (1,).type.isNamedTuple
proc typeToString*(t: typedesc, prefer = "preferTypeName"): string {.magic: "TypeTrait".}
## Returns the name of the given type, with more flexibility than `name`,
## and avoiding the potential clash with a variable named `name`.
## prefer = "preferResolved" will resolve type aliases recursively.
# Move to typetraits.nim once api stabilized.
block: # typeToString
type MyInt = int
type
C[T0, T1] = object
type C2=C # alias => will resolve as C
type C2b=C # alias => will resolve as C (recursively)
type C3[U,V] = C[V,U]
type C4[X] = C[X,X]
template name2(T): string = typeToString(T, "preferResolved")
doAssert MyInt.name2 == "int"
doAssert C3[MyInt, C2b].name2 == "C3[int, C]"
# C3 doesn't get resolved to C, not an alias (nor does C4)
doAssert C2b[MyInt, C4[cstring]].name2 == "C[int, C4[cstring]]"
doAssert C4[MyInt].name2 == "C4[int]"
when BiggestFloat is float and cint is int:
doAssert C2b[cint, BiggestFloat].name2 == "C3[int, C3[float, int32]]"
template name3(T): string = typeToString(T, "preferMixed")
doAssert MyInt.name3 == "MyInt{int}"
doAssert (tuple[a: MyInt, b: float]).name3 == "tuple[a: MyInt{int}, b: float]"
doAssert (tuple[a: C2b[MyInt, C4[cstring]], b: cint, c: float]).name3 ==
"tuple[a: C2b{C}[MyInt{int}, C4[cstring]], b: cint{int32}, c: float]"

View file

@ -48,7 +48,6 @@ echo(["a", "b", "c", "d"].len)
for x in items(["What's", "your", "name", "?", ]):
echo(x)
var `name` = readLine(stdin)
{.breakpoint.}
echo("Hi " & thallo.name & "!\n")
debug(name)

View file

@ -1,5 +1,7 @@
discard """
output: '''(x: "string here", a: 1)'''
output: '''(x: "string here", a: 1)
b is 5
x is 12'''
"""
proc simple[T](a: T) =
@ -28,3 +30,35 @@ proc test(baz: int, qux: var int): int =
var x1 = 456
discard test(123, x1)
# bug #11958
proc foo() =
var a = 5
proc bar() {.nimcall.} =
var b = 5
for k, v in fieldpairs(locals()):
echo k, " is ", v
bar()
foo()
proc foo2() =
var a = 5
proc bar2() {.nimcall.} =
for k, v in fieldpairs(locals()):
echo k, " is ", v
bar2()
foo2()
proc foo3[T](y: T) =
var a = 5
proc bar2[T](x: T) {.nimcall.} =
for k, v in fieldpairs(locals()):
echo k, " is ", v
bar2(y)
foo3(12)

View file

@ -1,4 +1,5 @@
discard """
targets: "c cpp"
output: '''
body executed
body executed
@ -7,6 +8,14 @@ macros api OK
'''
"""
# This is for travis. The keyword ``alignof`` only exists in ``c++11``
# and newer. On travis gcc does not default to c++11 yet.
when defined(cpp) and not defined(windows):
{.passC: "-std=c++11".}
# Object offsets are different for inheritance objects when compiling
# to c++.
type
TMyEnum = enum
tmOne, tmTwo, tmThree, tmFour
@ -143,6 +152,14 @@ type
ValueA
ValueB
# Must have more than 32 elements so that set[MyEnum33] will become compile to an int64.
MyEnum33 {.pure.} = enum
Value1, Value2, Value3, Value4, Value5, Value6,
Value7, Value8, Value9, Value10, Value11, Value12,
Value13, Value14, Value15, Value16, Value17, Value18,
Value19, Value20, Value21, Value22, Value23, Value24,
Value25, Value26, Value27, Value28, Value29, Value30,
Value31, Value32, Value33
proc transformObjectconfigPacked(arg: NimNode): NimNode =
let debug = arg.kind == nnkPragmaExpr
@ -296,6 +313,10 @@ testinstance:
b: int8
c: int8
PaddingOfSetEnum33 = object
cause: int8
theSet: set[MyEnum33]
Bazing {.objectconfig.} = object of RootObj
a: int64
# TODO test on 32 bit system
@ -328,6 +349,7 @@ testinstance:
var g : RecursiveStuff
var ro : RootObj
var go : GenericObject[int64]
var po : PaddingOfSetEnum33
var
e1: Enum1
@ -346,16 +368,16 @@ testinstance:
else:
doAssert sizeof(SimpleAlignment) > 10
testSizeAlignOf(t,a,b,c,d,e,f,g,ro,go, e1, e2, e4, e8, eoa, eob)
testSizeAlignOf(t,a,b,c,d,e,f,g,ro,go,po, e1, e2, e4, e8, eoa, eob)
when not defined(cpp):
type
WithBitsize {.objectconfig.} = object
bitfieldA {.bitsize: 16.}: uint32
bitfieldB {.bitsize: 16.}: uint32
var wbs: WithBitsize
testSize(wbs)
type
WithBitsize {.objectconfig.} = object
bitfieldA {.bitsize: 16.}: uint32
bitfieldB {.bitsize: 16.}: uint32
var wbs: WithBitsize
testSize(wbs)
testOffsetOf(TrivialType, x)
testOffsetOf(TrivialType, y)
@ -383,11 +405,13 @@ testinstance:
testOffsetOf(Foobar, c)
when not defined(cpp):
testOffsetOf(Bazing, a)
testOffsetOf(InheritanceA, a)
testOffsetOf(InheritanceB, b)
testOffsetOf(InheritanceC, c)
testOffsetOf(PaddingOfSetEnum33, cause)
testOffsetOf(PaddingOfSetEnum33, theSet)
testOffsetOf(Bazing, a)
testOffsetOf(InheritanceA, a)
testOffsetOf(InheritanceB, b)
testOffsetOf(InheritanceC, c)
testOffsetOf(EnumObjectA, a)
testOffsetOf(EnumObjectA, b)
@ -619,9 +643,6 @@ doAssert offsetof(MyPackedCaseObject, val3) == 13
doAssert offsetof(MyPackedCaseObject, val4) == 9
doAssert offsetof(MyPackedCaseObject, val5) == 13
reject:
const off4 = offsetof(MyPackedCaseObject, val1)
reject:
const off5 = offsetof(MyPackedCaseObject, val2)

View file

@ -17,7 +17,6 @@ block tobject2:
z: int # added a field
proc getPoint( p: var TPoint2d) =
{.breakpoint.}
writeLine(stdout, p.x)
var p: TPoint3d

View file

@ -1,5 +1,5 @@
discard """
errormsg: "invalid type: 'openarray[int]' for result"
errormsg: "invalid type: 'openArray[int]' for result"
line: 6
"""

View file

@ -1,6 +1,7 @@
discard """
output: '''[1, 2, 3, 4]
3
['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C']
OK
'''
"""
@ -66,4 +67,18 @@ var
doAssert y1 == ([1, 2], 3)
doAssert y2 == [1, 2, 3, 4]
template newOpenArray(x: var string, size: int): openArray[char] =
var z = 1
toOpenArray(x, z, size)
template doSomethingAndCreate(x: var string): openArray[char] =
let size = 12
newOpenArray(x, size)
proc sinkk(x: openArray[char]) =
echo x
var xArrayDeref = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
sinkk doSomethingAndCreate(xArrayDeref)
echo "OK"

View file

@ -9,9 +9,9 @@ proc term(k: float): float = 4 * math.pow(-1, k) / (2*k + 1)
proc piU(n: int): float =
var ch = newSeq[FlowVar[float]](n+1)
for k in 0..n:
for k in 0..ch.high:
ch[k] = spawn term(float(k))
for k in 0..n:
for k in 0..ch.high:
result += ^ch[k]
proc piS(n: int): float =

View file

@ -1,11 +1,12 @@
discard """
output: '''ob @[]
ob3 @[]
ob2 @[]
3
output: '''ob2 @[]
ob @[]
ob3 @[]
ob2 @[]'''
3
ob2 @[]
ob @[]
ob3 @[]
'''
cmd: "nim c -r --threads:on $file"
"""

View file

@ -1,8 +1,11 @@
discard """
cmd: "nim check $file"
errmsg: ""
nimout: '''tillegalreturntype.nim(8, 11) Error: return type 'typed' is only valid for macros and templates
tillegalreturntype.nim(11, 11) Error: return type 'untyped' is only valid for macros and templates'''
nimout: '''
tillegalreturntype.nim(11, 11) Error: return type 'typed' is only valid for macros and templates
tillegalreturntype.nim(14, 11) Error: return type 'untyped' is only valid for macros and templates
tillegalreturntype.nim(17, 41) Error: return type 'auto' cannot be used in forward declarations
'''
"""
proc x(): typed =
@ -10,3 +13,9 @@ proc x(): typed =
proc y(): untyped =
discard
proc test_proc[T, U](arg1: T, arg2: U): auto
proc test_proc[T, U](arg1: T, arg2: U): auto =
echo "Proc has been called"
return arg1 / arg2

View file

@ -118,3 +118,21 @@ block:
x3 = R32(4)
doAssert $x1 & $x2 & $x3 == "444"
block:
var x1: range[0'f..1'f] = 1
const x2: range[0'f..1'f] = 1
var x3: range[0'u8..1'u8] = 1
const x4: range[0'u8..1'u8] = 1
var x5: range[0'f32..1'f32] = 1'f64
const x6: range[0'f32..1'f32] = 1'f64
reject:
var x09: range[0'i8..1'i8] = 1.int
reject:
var x10: range[0'i64..1'i64] = 1'u64
const x11: range[0'f..1'f] = 2'f
reject:
const x12: range[0'f..1'f] = 2

View file

@ -8,6 +8,7 @@ output: '''
16
b is 2 times a
17
['\x00', '\x00', '\x00', '\x00']
'''
"""
@ -154,3 +155,14 @@ block:
const uk = MicroKernel(a: 5.5, b: 1)
tFunc[uk]()
# bug #7258
type
StringValue*[LEN: static[Natural]] = array[LEN+Natural(2),char]
StringValue16* = StringValue[2]
var
s: StringValue16
echo s

View file

@ -517,6 +517,42 @@ when true:
doAssert v.name == "smith"
doAssert MyRef(w).name == "smith"
# bug #12015
# The definition of the `%` proc needs to be here, since the `% c` calls below
# can only find our custom `%` proc for `Pix` if defined in global scope.
type
Pix = tuple[x, y: uint8, ch: uint16]
proc `%`(p: Pix): JsonNode =
result = %* { "x" : % p.x,
"y" : % p.y,
"ch" : % p.ch }
block:
type
Cluster = object
works: tuple[x, y: uint8, ch: uint16] # working
fails: Pix # previously broken
let data = (x: 123'u8, y: 53'u8, ch: 1231'u16)
let c = Cluster(works: data, fails: data)
let cFromJson = (% c).to(Cluster)
doAssert c == cFromJson
block:
# bug related to #12015
type
PixInt = tuple[x, y, ch: int]
SomePix = Pix | PixInt
Cluster[T: SomePix] = seq[T]
ClusterObject[T: SomePix] = object
data: Cluster[T]
RecoEvent[T: SomePix] = object
cluster: seq[ClusterObject[T]]
let data = @[(x: 123'u8, y: 53'u8, ch: 1231'u16)]
var c = RecoEvent[Pix](cluster: @[ClusterObject[Pix](data: data)])
let cFromJson = (% c).to(RecoEvent[Pix])
doAssert c == cFromJson
# TODO: when the issue with the limeted vm registers is solved, the
# exact same test as above should be evaluated at compile time as
# well, to ensure that the vm functionality won't diverge from the

View file

@ -159,3 +159,18 @@ block: # `$`*[T: tuple|object](x: T)
x2:float
doAssert $Foo(x:2) == "(x: 2, x2: 0.0)"
doAssert $() == "()"
# this is a call indirection to prevent `toInt` to be resolved at compile time.
proc testToInt(arg: float64, a: int, b: BiggestInt) =
doAssert toInt(arg) == a
doAssert toBiggestInt(arg) == b
testToInt(0.45, 0, 0) # should round towards 0
testToInt(-0.45, 0, 0) # should round towards 0
testToInt(0.5, 1, 1) # should round away from 0
testToInt(-0.5, -1, -1) # should round away from 0
testToInt(13.37, 13, 13) # should round towards 0
testToInt(-13.37, -13, -13) # should round towards 0
testToInt(7.8, 8, 8) # should round away from 0
testToInt(-7.8, -8, -8) # should round away from 0

View file

@ -6,6 +6,7 @@ output: '''
a
hi
Hello, World!
(e: 42)
'''
"""
@ -220,3 +221,17 @@ block t5235:
outer:
test("Hello, World!")
# bug #11941
type X = object
e: int
proc works(T: type X, v: auto): T = T(e: v)
template fails(T: type X, v: auto): T = T(e: v)
var
w = X.works(42)
x = X.fails(42)
echo x

View file

@ -9,6 +9,7 @@ bar7
10
4true
132
20
'''
"""
@ -192,7 +193,7 @@ block ttempl:
block ttempl4:
template `:=`(name, val: untyped): typed =
template `:=`(name, val: untyped) =
var name = val
ha := 1 * 4
@ -211,7 +212,7 @@ block ttempl5:
discard
# Call parse_to_close
template get_next_ident: typed =
template get_next_ident =
discard "{something}".parse_to_close(0, open = '{', close = '}')
get_next_ident()
@ -231,3 +232,16 @@ block ttempl5:
block templreturntype:
template `=~` (a: int, b: int): bool = false
var foo = 2 =~ 3
# bug #7117
template parse9(body: untyped): untyped =
template val9(arg: string): int {.inject.} =
var b: bool
if b: 10
else: 20
body
parse9:
echo val9("1")

View file

@ -0,0 +1,44 @@
discard """
output: '''0
0.0'''
"""
# bug #11494
import macros
macro staticForEach(arr: untyped, body: untyped): untyped =
result = newNimNode(nnkStmtList)
arr.expectKind(nnkBracket)
for n in arr:
let b = copyNimTree(body)
result.add quote do:
block:
type it {.inject.} = `n`
`b`
template forEveryMatchingEntity*() =
staticForEach([int, string, float]):
var a: it
echo a
forEveryMatchingEntity()
# bug #11483
proc main =
template first(body) =
template second: var int =
var o: int
var i = addr(o)
i[]
body
first:
second = 5
second = 6
main()

View file

@ -8,6 +8,7 @@ output: '''
1
2
3
wth
'''
"""
# bug #1915
@ -130,3 +131,17 @@ template test() =
doAssert(foo.len == 3)
test()
# regression found in PMunch's parser generator
proc namedcall(arg: string) =
discard
macro m(): untyped =
result = quote do:
(proc (arg: string) =
namedcall(arg = arg)
echo arg)
let meh = m()
meh("wth")

View file

@ -0,0 +1,13 @@
discard """
errormsg: "redefinition of 'a`gensym"
line: 9
"""
# bug #10180
proc f() =
template t() =
var a = 1
var a = 2
echo a
t()
f()

View file

@ -1,5 +1,5 @@
discard """
cmd: "testament/tester --directory:testament --colors:off --backendLogging:off --nim:../compiler/nim category shouldfail"
cmd: "testament/testament --directory:testament --colors:off --backendLogging:off --nim:../compiler/nim category shouldfail"
action: compile
nimout: '''
FAIL: tests/shouldfail/tccodecheck.nim C

View file

@ -0,0 +1,3 @@
{.used.}
proc nothing* = echo "nothing to see here"

View file

@ -0,0 +1,22 @@
discard """
cmd: "nim e $file"
output: '''
foobar
nothing
hallo
"""
# this test ensures that the mode is resetted correctly to repr
import macros
macro foobar(): void =
result = newCall(bindSym"echo", newLit("nothing"))
echo "foobar"
let x = 123
foobar()
exec "echo hallo"

View file

@ -10,7 +10,7 @@ tunused_imports.nim(25, 8) Warning: imported and not used: 'strutils' [UnusedImp
{.warning: "BEGIN".}
import net
import net, dontmentionme
echo AF_UNIX

View file

@ -0,0 +1,13 @@
discard """
errormsg: "cannot evaluate at compile time: BUILTIN_NAMES"
line: 11
"""
import sets
let BUILTIN_NAMES = toSet(["int8", "int16", "int32", "int64"])
macro test*(): bool =
echo "int64" notin BUILTIN_NAMES
echo test()