mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-25 18:11:59 +00:00
Merge branch 'devel' into expand-amb-identifier-output
This commit is contained in:
@@ -2,6 +2,7 @@ discard """
|
||||
output: '''(1, 1)
|
||||
(2, 2)
|
||||
(3, 3)
|
||||
@[1, 2, 3, 4]
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -15,3 +16,12 @@ proc foo(args: varargs[int]) =
|
||||
discard
|
||||
|
||||
foo(1,2,3)
|
||||
|
||||
# 10999
|
||||
|
||||
proc varargsToSeq(vals: varargs[int32]): seq[int32] =
|
||||
result = newSeqOfCap[int32](vals.len)
|
||||
for v in vals:
|
||||
result.add v
|
||||
|
||||
echo varargsToSeq(1, 2, 3, 4)
|
||||
|
||||
@@ -7,8 +7,8 @@ mygeneric1 constructed
|
||||
mygeneric1 destroyed
|
||||
----
|
||||
mygeneric2 constructed
|
||||
myobj destroyed
|
||||
mygeneric2 destroyed
|
||||
myobj destroyed
|
||||
----
|
||||
mygeneric3 constructed
|
||||
mygeneric1 destroyed
|
||||
@@ -20,10 +20,10 @@ mygeneric2 destroyed
|
||||
----
|
||||
----
|
||||
myobj destroyed
|
||||
myobj destroyed
|
||||
myobj destroyed
|
||||
myobj destroyed
|
||||
mygeneric1 destroyed
|
||||
myobj destroyed
|
||||
myobj destroyed
|
||||
myobj destroyed
|
||||
---
|
||||
myobj destroyed
|
||||
myobj destroyed
|
||||
|
||||
@@ -4,8 +4,8 @@ destroy
|
||||
destroy
|
||||
5
|
||||
123
|
||||
destroy Foo: 5
|
||||
destroy Foo: 123'''
|
||||
destroy Foo: 123
|
||||
destroy Foo: 5'''
|
||||
joinable: false
|
||||
"""
|
||||
|
||||
|
||||
43
tests/destructor/tdont_return_unowned_from_owned.nim
Normal file
43
tests/destructor/tdont_return_unowned_from_owned.nim
Normal file
@@ -0,0 +1,43 @@
|
||||
discard """
|
||||
cmd: "nim check --newruntime --hints:off $file"
|
||||
nimout: '''tdont_return_unowned_from_owned.nim(24, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type
|
||||
tdont_return_unowned_from_owned.nim(27, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type
|
||||
tdont_return_unowned_from_owned.nim(30, 6) Error: type mismatch: got <Obj>
|
||||
but expected one of:
|
||||
proc new[T](a: var ref T; finalizer: proc (x: ref T) {.nimcall.})
|
||||
2 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them
|
||||
|
||||
expression: new(result)
|
||||
tdont_return_unowned_from_owned.nim(30, 6) Error: illformed AST:
|
||||
tdont_return_unowned_from_owned.nim(38, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref
|
||||
tdont_return_unowned_from_owned.nim(39, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref
|
||||
tdont_return_unowned_from_owned.nim(43, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(RootRef)' as the return type
|
||||
'''
|
||||
errormsg: "cannot return an owned pointer as an unowned pointer; use 'owned(RootRef)' as the return type"
|
||||
line: 43
|
||||
"""
|
||||
# bug #11073
|
||||
type
|
||||
Obj = ref object
|
||||
|
||||
proc newObjA(): Obj =
|
||||
result = new Obj
|
||||
|
||||
proc newObjB(): Obj =
|
||||
result = Obj()
|
||||
|
||||
proc newObjC(): Obj =
|
||||
new(result)
|
||||
|
||||
let a = newObjA()
|
||||
let b = newObjB()
|
||||
let c = newObjC()
|
||||
|
||||
proc testA(result: var (RootRef, RootRef)) =
|
||||
let r: owned RootRef = RootRef()
|
||||
result[0] = r
|
||||
result[1] = RootRef()
|
||||
|
||||
proc testB(): RootRef =
|
||||
let r: owned RootRef = RootRef()
|
||||
result = r
|
||||
@@ -4,7 +4,9 @@ discard """
|
||||
ho
|
||||
ha
|
||||
@["arg", "asdfklasdfkl", "asdkfj", "dfasj", "klfjl"]
|
||||
22 22'''
|
||||
@[1, 2, 3]
|
||||
@["red", "yellow", "orange", "rtrt1", "pink"]
|
||||
30 30'''
|
||||
"""
|
||||
|
||||
import allocators
|
||||
@@ -132,6 +134,41 @@ proc other =
|
||||
|
||||
other()
|
||||
|
||||
# bug #11050
|
||||
|
||||
type
|
||||
Obj* = object
|
||||
f*: seq[int]
|
||||
|
||||
method main(o: Obj) {.base.} =
|
||||
for newb in o.f:
|
||||
discard
|
||||
|
||||
# test that o.f was not moved!
|
||||
proc testforNoMove =
|
||||
var o = Obj(f: @[1, 2, 3])
|
||||
main(o)
|
||||
echo o.f
|
||||
|
||||
testforNoMove()
|
||||
|
||||
# bug #11065
|
||||
type
|
||||
Warm = seq[string]
|
||||
|
||||
proc testWarm =
|
||||
var w: Warm
|
||||
w = @["red", "yellow", "orange"]
|
||||
|
||||
var x = "rt"
|
||||
var y = "rt1"
|
||||
w.add(x & y)
|
||||
|
||||
w.add("pink")
|
||||
echo w
|
||||
|
||||
testWarm()
|
||||
|
||||
#echo s
|
||||
let (a, d) = allocCounters()
|
||||
discard cprintf("%ld %ld\n", a, d)
|
||||
|
||||
@@ -2,30 +2,46 @@ discard """
|
||||
output: '''works'''
|
||||
"""
|
||||
|
||||
type
|
||||
MyVal = object
|
||||
f: ptr float
|
||||
# bug #11095
|
||||
|
||||
proc `=destroy`(x: var MyVal) =
|
||||
type
|
||||
MyVal[T] = object
|
||||
f: ptr T
|
||||
|
||||
proc `=destroy`[T](x: var MyVal[T]) =
|
||||
if x.f != nil:
|
||||
dealloc(x.f)
|
||||
|
||||
proc `=sink`(x1: var MyVal, x2: Myval) =
|
||||
proc `=sink`[T](x1: var MyVal[T], x2: MyVal[T]) =
|
||||
if x1.f != x2.f:
|
||||
`=destroy`(x1)
|
||||
x1.f = x2.f
|
||||
|
||||
proc `=`(x1: var MyVal, x2: Myval) {.error.}
|
||||
proc `=`[T](x1: var MyVal[T], x2: MyVal[T]) {.error.}
|
||||
|
||||
proc newVal(x: float): MyVal =
|
||||
result.f = create(float)
|
||||
proc newVal[T](x: sink T): MyVal[T] =
|
||||
result.f = create(T)
|
||||
result.f[] = x
|
||||
|
||||
proc sinkMe(x: sink MyVal) =
|
||||
proc set[T](x: var MyVal[T], val: T) =
|
||||
x.f[] = val
|
||||
|
||||
proc sinkMe[T](x: sink MyVal[T]) =
|
||||
discard
|
||||
|
||||
var flag = false
|
||||
|
||||
proc main =
|
||||
var y = (newVal(3.0), newVal(4.0))
|
||||
var y = case flag
|
||||
of true:
|
||||
var x1 = newVal[float](1.0)
|
||||
var x2 = newVal[float](2.0)
|
||||
(newVal(x1), newVal(x2))
|
||||
|
||||
of false:
|
||||
var x1 = newVal[float](1.0)
|
||||
var x2 = newVal[float](2.0)
|
||||
(newVal(x1), newVal(x2))
|
||||
|
||||
sinkMe y[0]
|
||||
sinkMe y[1]
|
||||
|
||||
92
tests/destructor/towned_binary_tree.nim
Normal file
92
tests/destructor/towned_binary_tree.nim
Normal file
@@ -0,0 +1,92 @@
|
||||
discard """
|
||||
cmd: '''nim c --newruntime $file'''
|
||||
output: '''331665
|
||||
allocs 0'''
|
||||
"""
|
||||
|
||||
# bug #11053
|
||||
|
||||
import random
|
||||
|
||||
type Node = ref object
|
||||
x, y: int32
|
||||
left, right: owned Node
|
||||
|
||||
proc newNode(x: int32): owned Node =
|
||||
result = Node(x: x, y: rand(high int32).int32)
|
||||
|
||||
proc merge(lower, greater: owned Node): owned Node =
|
||||
if lower.isNil:
|
||||
result = greater
|
||||
elif greater.isNil:
|
||||
result = lower
|
||||
elif lower.y < greater.y:
|
||||
lower.right = merge(lower.right, greater)
|
||||
result = lower
|
||||
else:
|
||||
greater.left = merge(lower, greater.left)
|
||||
result = greater
|
||||
|
||||
proc splitBinary(orig: owned Node, value: int32): (owned Node, owned Node) =
|
||||
if orig.isNil:
|
||||
result = (nil, nil)
|
||||
elif orig.x < value:
|
||||
let splitPair = splitBinary(orig.right, value)
|
||||
orig.right = splitPair[0]
|
||||
result = (orig, splitPair[1])
|
||||
else:
|
||||
let splitPair = splitBinary(orig.left, value)
|
||||
orig.left = splitPair[1]
|
||||
result = (splitPair[0], orig)
|
||||
|
||||
proc merge3(lower, equal, greater: owned Node): owned Node =
|
||||
merge(merge(lower, equal), greater)
|
||||
|
||||
proc split(orig: owned Node, value: int32): tuple[lower, equal, greater: owned Node] =
|
||||
let
|
||||
(lower, equalGreater) = splitBinary(orig, value)
|
||||
(equal, greater) = splitBinary(equalGreater, value + 1)
|
||||
result = (lower, equal, greater)
|
||||
|
||||
type Tree = object
|
||||
root: owned Node
|
||||
|
||||
proc hasValue(self: var Tree, x: int32): bool =
|
||||
let splited = split(move self.root, x)
|
||||
result = not splited.equal.isNil
|
||||
self.root = merge3(splited.lower, splited.equal, splited.greater)
|
||||
|
||||
proc insert(self: var Tree, x: int32) =
|
||||
var splited = split(move self.root, x)
|
||||
if splited.equal.isNil:
|
||||
splited.equal = newNode(x)
|
||||
self.root = merge3(splited.lower, splited.equal, splited.greater)
|
||||
|
||||
proc erase(self: var Tree, x: int32) =
|
||||
let splited = split(move self.root, x)
|
||||
self.root = merge(splited.lower, splited.greater)
|
||||
|
||||
proc main() =
|
||||
var
|
||||
tree = Tree()
|
||||
cur = 5'i32
|
||||
res = 0
|
||||
|
||||
for i in 1 ..< 1000000:
|
||||
let a = i mod 3
|
||||
cur = (cur * 57 + 43) mod 10007
|
||||
case a:
|
||||
of 0:
|
||||
tree.insert(cur)
|
||||
of 1:
|
||||
tree.erase(cur)
|
||||
of 2:
|
||||
if tree.hasValue(cur):
|
||||
res += 1
|
||||
else:
|
||||
discard
|
||||
echo res
|
||||
|
||||
when isMainModule:
|
||||
main()
|
||||
echo "allocs ", allocs
|
||||
78
tests/destructor/twidgets.nim
Normal file
78
tests/destructor/twidgets.nim
Normal file
@@ -0,0 +1,78 @@
|
||||
discard """
|
||||
cmd: '''nim c --newruntime $file'''
|
||||
output: '''button
|
||||
clicked!
|
||||
1 1 alloc/dealloc pairs: 0'''
|
||||
"""
|
||||
|
||||
import core / allocators
|
||||
import system / ansi_c
|
||||
|
||||
type
|
||||
Widget* = ref object of RootObj
|
||||
drawImpl: owned(proc (self: Widget))
|
||||
|
||||
Button* = ref object of Widget
|
||||
caption: string
|
||||
onclick: owned(proc())
|
||||
|
||||
Window* = ref object of Widget
|
||||
elements: seq[owned Widget]
|
||||
|
||||
|
||||
proc newButton(caption: string; onclick: owned(proc())): owned Button =
|
||||
proc draw(self: Widget) =
|
||||
let b = Button(self)
|
||||
echo b.caption
|
||||
|
||||
#result = Button(drawImpl: draw, caption: caption, onclick: onclick)
|
||||
new(result)
|
||||
result.drawImpl = draw
|
||||
result.caption = caption
|
||||
result.onclick = onclick
|
||||
|
||||
iterator unitems*[T](a: seq[owned T]): T {.inline.} =
|
||||
## Iterates over each item of `a`.
|
||||
var i = 0
|
||||
let L = len(a)
|
||||
while i < L:
|
||||
yield a[i]
|
||||
inc(i)
|
||||
assert(len(a) == L, "seq modified while iterating over it")
|
||||
|
||||
proc newWindow(): owned Window =
|
||||
proc windraw(self: Widget) =
|
||||
let w = Window(self)
|
||||
for i in 0..<len(w.elements):
|
||||
let e = Widget(w.elements[i])
|
||||
let d = (proc(self: Widget))e.drawImpl
|
||||
if not d.isNil: d(e)
|
||||
|
||||
result = Window(drawImpl: windraw, elements: @[])
|
||||
|
||||
proc draw(w: Widget) =
|
||||
let d = (proc(self: Widget))w.drawImpl
|
||||
if not d.isNil: d(w)
|
||||
|
||||
proc add*(w: Window; elem: owned Widget) =
|
||||
w.elements.add elem
|
||||
|
||||
proc main =
|
||||
var w = newWindow()
|
||||
|
||||
var b = newButton("button", nil)
|
||||
let u: Button = b
|
||||
b.onclick = proc () =
|
||||
b.caption = "clicked!"
|
||||
w.add b
|
||||
|
||||
w.draw()
|
||||
# simulate button click:
|
||||
u.onclick()
|
||||
|
||||
w.draw()
|
||||
|
||||
main()
|
||||
|
||||
let (a, d) = allocCounters()
|
||||
discard cprintf("%ld %ld alloc/dealloc pairs: %ld\n", a, d, allocs)
|
||||
68
tests/destructor/twidgets_unown.nim
Normal file
68
tests/destructor/twidgets_unown.nim
Normal file
@@ -0,0 +1,68 @@
|
||||
discard """
|
||||
cmd: '''nim c --newruntime $file'''
|
||||
output: '''button
|
||||
clicked!
|
||||
3 3 alloc/dealloc pairs: 0'''
|
||||
"""
|
||||
|
||||
import core / allocators
|
||||
import system / ansi_c
|
||||
|
||||
type
|
||||
Widget* = ref object of RootObj
|
||||
drawImpl: owned(proc (self: Widget))
|
||||
|
||||
Button* = ref object of Widget
|
||||
caption: string
|
||||
onclick: owned(proc())
|
||||
|
||||
Window* = ref object of Widget
|
||||
elements: seq[owned Widget]
|
||||
|
||||
|
||||
proc newButton(caption: string; onclick: owned(proc())): owned Button =
|
||||
proc draw(self: Widget) =
|
||||
let b = Button(self)
|
||||
echo b.caption
|
||||
|
||||
#result = Button(drawImpl: draw, caption: caption, onclick: onclick)
|
||||
new(result)
|
||||
result.drawImpl = draw
|
||||
result.caption = caption
|
||||
result.onclick = onclick
|
||||
|
||||
proc newWindow(): owned Window =
|
||||
proc windraw(self: Widget) =
|
||||
let w = Window(self)
|
||||
for e in unown(w.elements):
|
||||
let d = unown e.drawImpl
|
||||
if not d.isNil: d(e)
|
||||
|
||||
result = Window(drawImpl: windraw, elements: @[])
|
||||
|
||||
proc draw(w: Widget) =
|
||||
let d = unown w.drawImpl
|
||||
if not d.isNil: d(w)
|
||||
|
||||
proc add*(w: Window; elem: owned Widget) =
|
||||
w.elements.add elem
|
||||
|
||||
proc main =
|
||||
var w = newWindow()
|
||||
|
||||
var b = newButton("button", nil)
|
||||
let u = unown b
|
||||
b.onclick = proc () =
|
||||
b.caption = "clicked!"
|
||||
w.add b
|
||||
|
||||
w.draw()
|
||||
# simulate button click:
|
||||
u.onclick()
|
||||
|
||||
w.draw()
|
||||
|
||||
main()
|
||||
|
||||
let (a, d) = allocCounters()
|
||||
discard cprintf("%ld %ld alloc/dealloc pairs: %ld\n", a, d, allocs)
|
||||
@@ -3,6 +3,8 @@ output: '''
|
||||
tdiscardable
|
||||
1
|
||||
1
|
||||
something defered
|
||||
something defered
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -45,3 +47,21 @@ proc foo: (proc: int) =
|
||||
return bar
|
||||
|
||||
discard foo()
|
||||
|
||||
# bug #10842
|
||||
|
||||
proc myDiscardable(): int {.discardable.} =
|
||||
discard
|
||||
|
||||
proc main1() =
|
||||
defer:
|
||||
echo "something defered"
|
||||
discard myDiscardable()
|
||||
|
||||
proc main2() =
|
||||
defer:
|
||||
echo "something defered"
|
||||
myDiscardable()
|
||||
|
||||
main1()
|
||||
main2()
|
||||
|
||||
51
tests/macros/tnewproc.nim
Normal file
51
tests/macros/tnewproc.nim
Normal file
@@ -0,0 +1,51 @@
|
||||
import macros
|
||||
|
||||
macro test(a: untyped): untyped =
|
||||
# proc hello*(x: int = 3, y: float32): int {.inline.} = discard
|
||||
let
|
||||
nameNode = nnkPostfix.newTree(
|
||||
newIdentNode("*"),
|
||||
newIdentNode("hello")
|
||||
)
|
||||
params = @[
|
||||
newIdentNode("int"),
|
||||
nnkIdentDefs.newTree(
|
||||
newIdentNode("x"),
|
||||
newIdentNode("int"),
|
||||
newLit(3)
|
||||
),
|
||||
nnkIdentDefs.newTree(
|
||||
newIdentNode("y"),
|
||||
newIdentNode("float32"),
|
||||
newEmptyNode()
|
||||
)
|
||||
]
|
||||
paramsNode = nnkFormalParams.newTree(params)
|
||||
pragmasNode = nnkPragma.newTree(
|
||||
newIdentNode("inline")
|
||||
)
|
||||
bodyNode = nnkStmtList.newTree(
|
||||
nnkDiscardStmt.newTree(
|
||||
newEmptyNode()
|
||||
)
|
||||
)
|
||||
|
||||
var
|
||||
expected = nnkProcDef.newTree(
|
||||
nameNode,
|
||||
newEmptyNode(),
|
||||
newEmptyNode(),
|
||||
paramsNode,
|
||||
pragmasNode,
|
||||
newEmptyNode(),
|
||||
bodyNode
|
||||
)
|
||||
|
||||
doAssert expected == newProc(name=nameNode, params=params,
|
||||
body = bodyNode, pragmas=pragmasNode)
|
||||
expected.pragma = newEmptyNode()
|
||||
doAssert expected == newProc(name=nameNode, params=params,
|
||||
body = bodyNode)
|
||||
|
||||
test:
|
||||
42
|
||||
@@ -0,0 +1 @@
|
||||
proc flat*() = echo "flat"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
discard """
|
||||
errormsg: "module names need to be unique per Nimble package"
|
||||
file: "tnotuniquename/mnotuniquename.nim"
|
||||
output: '''nested
|
||||
flat'''
|
||||
"""
|
||||
|
||||
import mnotuniquename
|
||||
import tnotuniquename/mnotuniquename as nun
|
||||
import tnotuniquename_dir/mnotuniquename as nun
|
||||
|
||||
nested()
|
||||
flat()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
discard """
|
||||
errormsg: "module names need to be unique per Nimble package"
|
||||
file: "tnotuniquename/mnotuniquename.nim"
|
||||
disabled: "true"
|
||||
"""
|
||||
|
||||
import mnotuniquename
|
||||
|
||||
2
tests/modules/tnotuniquename_dir/mnotuniquename.nim
Normal file
2
tests/modules/tnotuniquename_dir/mnotuniquename.nim
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
proc nested*() = echo "nested"
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
errormsg: "illegal recursion in type 'RefTreeInt'"
|
||||
errormsg: "illegal recursion in type 'RefTree'"
|
||||
"""
|
||||
|
||||
type
|
||||
|
||||
9
tests/types/tillegaltuplerecursiongeneric2.nim
Normal file
9
tests/types/tillegaltuplerecursiongeneric2.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
discard """
|
||||
errormsg: "illegal recursion in type 'TPearl'"
|
||||
"""
|
||||
|
||||
type
|
||||
TPearl[T] = tuple
|
||||
next: TPearl[T]
|
||||
|
||||
var x: TPearl[int]
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
errormsg: "invalid recursion in type 'Executor'"
|
||||
errormsg: "illegal recursion in type 'Executor'"
|
||||
line: 8
|
||||
"""
|
||||
# bug reported by PR #5637
|
||||
|
||||
Reference in New Issue
Block a user