diff options
Diffstat (limited to 'tests/arc')
39 files changed, 1536 insertions, 80 deletions
diff --git a/tests/arc/t17812.nim b/tests/arc/t17812.nim index bcd5f3a93..dd8ac89b0 100644 --- a/tests/arc/t17812.nim +++ b/tests/arc/t17812.nim @@ -27,3 +27,15 @@ block: # bug #17812 proc `$`(o: MyObj): string = o.repr doAssert ($MyObj()).len > 0 + +# bug #22175 + +type Xxx = object + value: string + +proc complete(xxx: ref Xxx, v: sink string) = + xxx.value = move(v) + +let yyy = (ref Xxx)() + +yyy.complete("test") diff --git a/tests/arc/t18645.nim b/tests/arc/t18645.nim new file mode 100644 index 000000000..c5fddd4bb --- /dev/null +++ b/tests/arc/t18645.nim @@ -0,0 +1,18 @@ +discard """ + matrix: "--gc:arc; --gc:refc" + output: ''' +1 +2 +3 +''' +""" + +proc bitTypeIdUnion() = + var bitId {.global.} = block: + 0 + inc bitId + echo bitId + +bitTypeIdUnion() +bitTypeIdUnion() +bitTypeIdUnion() diff --git a/tests/arc/t18977.nim b/tests/arc/t18977.nim new file mode 100644 index 000000000..c775551a4 --- /dev/null +++ b/tests/arc/t18977.nim @@ -0,0 +1,26 @@ +discard """ + matrix: "--mm:arc" +""" + +type + E = enum + a, b, c, d + X = object + v: int + O = object + case kind: E + of a: + a: int + of {b, c}: + b: float + else: + d: X + +proc `=destroy`(x: var X) = + echo "x destroyed" + +var o = O(kind: d, d: X(v: 12345)) +doAssert o.d.v == 12345 + +doAssertRaises(FieldDefect): + o.kind = a diff --git a/tests/arc/t19231.nim b/tests/arc/t19231.nim new file mode 100644 index 000000000..40fcf277c --- /dev/null +++ b/tests/arc/t19231.nim @@ -0,0 +1,18 @@ +discard """ + matrix: "--mm:orc" + targets: "c cpp" +""" + +type + Game* = ref object + +proc free*(game: Game) = + var mixNumOpened:cint = 0 + for i in 0..<mixNumOpened: + mixNumOpened -= 1 + +proc newGame*(): Game = + new result, free + +var + game*: Game diff --git a/tests/arc/t19364.nim b/tests/arc/t19364.nim new file mode 100644 index 000000000..f520f3291 --- /dev/null +++ b/tests/arc/t19364.nim @@ -0,0 +1,30 @@ +discard """ + cmd: '''nim c --gc:arc --expandArc:fooLeaks $file''' + nimout: ''' +--expandArc: fooLeaks + +var + tmpTuple_cursor + a_cursor + b_cursor + c_cursor +tmpTuple_cursor = refTuple +a_cursor = tmpTuple_cursor[0] +b_cursor = tmpTuple_cursor[1] +c_cursor = tmpTuple_cursor[2] +-- end of expandArc ------------------------ +''' +""" + +func fooLeaks(refTuple: tuple[a, + b, + c: seq[float]]): float = + let (a, b, c) = refTuple + +let refset = (a: newSeq[float](25_000_000), + b: newSeq[float](25_000_000), + c: newSeq[float](25_000_000)) + +var res = newSeq[float](1_000_000) +for i in 0 .. res.high: + res[i] = fooLeaks(refset) diff --git a/tests/arc/t19862.nim b/tests/arc/t19862.nim index f7146ec26..6d3f57692 100644 --- a/tests/arc/t19862.nim +++ b/tests/arc/t19862.nim @@ -2,6 +2,8 @@ discard """ matrix: "--gc:refc; --gc:arc" """ +import std/widestrs + # bug #19862 type NewString = object diff --git a/tests/arc/t20456.nim b/tests/arc/t20456.nim new file mode 100644 index 000000000..ace79255a --- /dev/null +++ b/tests/arc/t20456.nim @@ -0,0 +1,7 @@ +discard """ + cmd: "nim check $file" + action: "compile" +""" + +when not defined(gcOrc): + {.error: "orc".} diff --git a/tests/arc/t20588.nim b/tests/arc/t20588.nim new file mode 100644 index 000000000..008bd1dcd --- /dev/null +++ b/tests/arc/t20588.nim @@ -0,0 +1,25 @@ +discard """ + cmd: "nim check --warnings:off --hints:off $file" + errormsg: "" + nimout: ''' +t20588.nim(20, 12) Error: illegal type conversion to 'auto' +t20588.nim(21, 14) Error: illegal type conversion to 'typed' +t20588.nim(22, 16) Error: illegal type conversion to 'untyped' +t20588.nim(24, 7) Error: illegal type conversion to 'any' +''' +""" + + + + + + + + + +discard 0.0.auto +discard typed("abc") +discard untyped(4) +var a = newSeq[bool](1000) +if any(a): + echo "ok?" \ No newline at end of file diff --git a/tests/arc/t21184.nim b/tests/arc/t21184.nim new file mode 100644 index 000000000..91d0c42c7 --- /dev/null +++ b/tests/arc/t21184.nim @@ -0,0 +1,77 @@ +discard """ + matrix: "--mm:orc" +""" + +import std/[with] + +type + Node* {.acyclic.} = ref object of RootObj + name: string + data: pointer + children: seq[Node] + TextNode = ref object of Node + text: string + +proc fakeEcho(s: string) = + if s.len < 0: + echo s + +proc newNode[T: Node](parent: Node): T = + new result + result.data = alloc0(250) + parent.children.add(result) + +proc newRootNode(): Node = + new result + result.data = alloc0(250) + +method printNode(node: Node) {.base.} = + fakeEcho node.name + +method printNode(node: TextNode) = + procCall printNode(Node(node)) + fakeEcho node.text + +proc printChildren(node: Node) = + for child in node.children: + child.printNode() + printChildren(child) + +proc free(node: Node) = + for child in node.children: + free(child) + dealloc(node.data) + +template node(parent: Node, body: untyped): untyped = + var node = newNode[Node](parent) + with node: + body + +proc textNode(parent: Node, text: string) = + var node = newNode[TextNode](parent) + node.text = text + +template withRootNode(body: untyped): untyped = + var root = newRootNode() + root.name = "root" + with root: + body + root.printNode() + printChildren(root) + root.free() + +proc doTest() = + withRootNode: + node: + name = "child1" + node: + name = "child2" + node: + name = "child3" + textNode "Hello, world!" + + +# bug #21171 +if isMainModule: + for i in 0..100000: + doTest() diff --git a/tests/arc/t22218.nim b/tests/arc/t22218.nim new file mode 100644 index 000000000..7837ed1d0 --- /dev/null +++ b/tests/arc/t22218.nim @@ -0,0 +1,25 @@ +discard """ + cmd: "nim c --mm:arc $file" + errormsg: "'=copy' is not available for type <Obj>; requires a copy because it's not the last read of 'chan[]'; routine: test" +""" + +# bug #22218 +type Obj[T] = object + v: T + +proc `=copy`[T]( + dest: var Obj[T], + source: Obj[T] + ) {.error: "A channel cannot be copied".} + +from system/ansi_c import c_calloc + +proc test() = + var v: bool = true + var chan = cast[ptr Obj[int]](c_calloc(1, csize_t sizeof(Obj[int]))) + var copy = chan[] + + echo chan.v + echo v + +test() \ No newline at end of file diff --git a/tests/arc/t22237.nim b/tests/arc/t22237.nim new file mode 100644 index 000000000..c6dbf768a --- /dev/null +++ b/tests/arc/t22237.nim @@ -0,0 +1,55 @@ +discard """ + matrix: "--mm:arc; --mm:orc" +""" + +import std/macros +import std/streams + +# bug #22237 + +proc iterlines_closure2(f: File | Stream): iterator (): string = + result = iterator(): string = + for line in f.lines: + if line.len == 0: + break + yield line + +proc test() = + let f = newStringStream(""" + 1 + 2 + + 3 + 4 + + 5 + 6 + 7 + + 8 +""") + while not f.atEnd(): + let iterator_inst = iterlines_closure2(f) + for item in iterator_inst(): # Fails with "SIGSEGV: Illegal storage access. (Attempt to read from nil?)" + discard + +test() + +# bug #21160 +import sequtils + +iterator allMoves(fls: seq[int]): seq[int] = + yield fls + +proc neighbors(flrs: seq[int]): iterator: seq[int] = + return iterator(): seq[int] = + for flrs2 in allMoves(flrs): + yield flrs2 + for flrs3 in allMoves(flrs2): + yield flrs3 + +let f = @[1] +for _ in neighbors(f): + discard +for _ in neighbors(f): + discard diff --git a/tests/arc/t22478.nim b/tests/arc/t22478.nim new file mode 100644 index 000000000..5373fa161 --- /dev/null +++ b/tests/arc/t22478.nim @@ -0,0 +1,46 @@ +discard """ + matrix: "-d:nimNoLentIterators --mm:arc" + output: '''PUSH DATA: {"test.message":{"test":{"nested":"v1"}}}''' + joinable: false +""" + +# bug #22748 +import std/[json, typetraits, times] + +# publish + +proc publish*[T](payload: T) = + discard + +type MetricsPoint* = JsonNode + +proc push*(stat: string, data: JsonNode, usec: int64 = 0) = + let payload = newJObject() + + # this results in a infinite recursion unless we deepCopy() + payload[stat] = data #.deepCopy + + echo "PUSH DATA: ", payload + + publish[MetricsPoint](payload) + +var scopes {.threadvar.}: seq[JsonNode] + +type WithTimeCallback*[T] = proc(data: var JsonNode): T + +proc pushScoped*[T](metric: string, blk: WithTimeCallback[T]): T {.gcsafe.} = + scopes.add newJObject() + defer: discard scopes.pop() + + let stc = (cpuTime() * 1000_000).int64 + result = blk(scopes[^1]) + let dfc = (cpuTime() * 1000_000).int64 - stc + + push(metric, scopes[^1], dfc) + +# demo code + +discard pushScoped[int]("test.message") do (data: var JsonNode) -> int: + data["test"] = %*{ + "nested": "v1" + } \ No newline at end of file diff --git a/tests/arc/t22787.nim b/tests/arc/t22787.nim new file mode 100644 index 000000000..5840a984b --- /dev/null +++ b/tests/arc/t22787.nim @@ -0,0 +1,37 @@ +discard """ + joinable: false +""" + +import std/assertions + +proc foo = + var s:seq[string] + var res = "" + + for i in 0..3: + s.add ("test" & $i) + s.add ("test" & $i) + + var lastname:string + + for i in s: + var name = i[0..4] + + if name != lastname: + res.add "NEW:" & name & "\n" + else: + res.add name & ">" & lastname & "\n" + + lastname = name + + doAssert res == """ +NEW:test0 +test0>test0 +NEW:test1 +test1>test1 +NEW:test2 +test2>test2 +NEW:test3 +test3>test3 +""" +foo() \ No newline at end of file diff --git a/tests/arc/t23247.nim b/tests/arc/t23247.nim new file mode 100644 index 000000000..0fadc50cd --- /dev/null +++ b/tests/arc/t23247.nim @@ -0,0 +1,52 @@ +discard """ + matrix: ";-d:useMalloc" +""" + +# bug #23247 +import std/hashes + +func baseAddr[T](x: openArray[T]): ptr T = + # Return the address of the zero:th element of x or `nil` if x is empty + if x.len == 0: nil else: cast[ptr T](x) + +func makeUncheckedArray[T](p: ptr T): ptr UncheckedArray[T] = + cast[ptr UncheckedArray[T]](p) + +type + LabelKey = object + data: seq[string] + refs: ptr UncheckedArray[string] + refslen: int + + Gauge = ref object + metrics: seq[seq[seq[string]]] + +template values(key: LabelKey): openArray[string] = + if key.refslen > 0: + key.refs.toOpenArray(0, key.refslen - 1) + else: + key.data + +proc hash(key: LabelKey): Hash = + hash(key.values) + +proc view(T: type LabelKey, values: openArray[string]): T = + # TODO some day, we might get view types - until then.. + LabelKey(refs: baseAddr(values).makeUncheckedArray(), refslen: values.len()) + +template withValue2(k: untyped) = + discard hash(k) + +proc setGauge( + collector: Gauge, + labelValues: openArray[string], +) = + let v = LabelKey.view(labelValues) + withValue2(v) + collector.metrics.add @[@labelValues, @labelValues] + discard @labelValues + +var nim_gc_mem_bytes = Gauge() +let threadID = $getThreadId() +setGauge(nim_gc_mem_bytes, @[threadID]) +setGauge(nim_gc_mem_bytes, @[threadID]) \ No newline at end of file diff --git a/tests/arc/taliased_reassign.nim b/tests/arc/taliased_reassign.nim new file mode 100644 index 000000000..5563fae8c --- /dev/null +++ b/tests/arc/taliased_reassign.nim @@ -0,0 +1,41 @@ +discard """ + matrix: "--mm:orc" +""" + +# bug #20993 + +type + Dual[int] = object # must be generic (even if fully specified) + p: int +proc D(p: int): Dual[int] = Dual[int](p: p) +proc `+`(x: Dual[int], y: Dual[int]): Dual[int] = D(x.p + y.p) + +type + Tensor[T] = object + buf: seq[T] +proc newTensor*[T](s: int): Tensor[T] = Tensor[T](buf: newSeq[T](s)) +proc `[]`*[T](t: Tensor[T], idx: int): T = t.buf[idx] +proc `[]=`*[T](t: var Tensor[T], idx: int, val: T) = t.buf[idx] = val + +proc `+.`[T](t1, t2: Tensor[T]): Tensor[T] = + let n = t1.buf.len + result = newTensor[T](n) + for i in 0 ..< n: + result[i] = t1[i] + t2[i] + +proc toTensor*[T](a: sink seq[T]): Tensor[T] = + ## This breaks it: Using `T` instead makes it work + type U = typeof(a[0]) + var t: Tensor[U] # Tensor[T] works + t.buf = a + result = t + +proc loss() = + var B = toTensor(@[D(123)]) + let a = toTensor(@[D(-10)]) + B = B +. a + doAssert B[0].p == 113, "I want to be 113, but I am " & $B[0].p + +loss() + + diff --git a/tests/arc/tarc_macro.nim b/tests/arc/tarc_macro.nim new file mode 100644 index 000000000..33ade1da4 --- /dev/null +++ b/tests/arc/tarc_macro.nim @@ -0,0 +1,57 @@ +import macros + +var destroyCalled = false +macro bar() = + let s = newTree(nnkAccQuoted, ident"=destroy") + # let s = ident"`=destroy`" # this would not work + result = quote do: + type Foo = object + # proc `=destroy`(a: var Foo) = destroyCalled = true # this would not work + proc `s`(a: var Foo) = destroyCalled = true + block: + let a = Foo() +bar() +doAssert destroyCalled + +# custom `op` +var destroyCalled2 = false +macro bar(ident) = + var x = 1.5 + result = quote("@") do: + type Foo = object + let `@ident` = 0 # custom op interpolated symbols need quoted (``) + proc `=destroy`(a: var Foo) = + doAssert @x == 1.5 + doAssert compiles(@x == 1.5) + let b1 = @[1,2] + let b2 = @@[1,2] + doAssert $b1 == "[1, 2]" + doAssert $b2 == "@[1, 2]" + destroyCalled2 = true + block: + let a = Foo() +bar(someident) +doAssert destroyCalled2 + +proc `&%`(x: int): int = 1 +proc `&%`(x, y: int): int = 2 + +macro bar2() = + var x = 3 + result = quote("&%") do: + var y = &%x # quoting operator + doAssert &%&%y == 1 # unary operator => need to escape + doAssert y &% y == 2 # binary operator => no need to escape + doAssert y == 3 +bar2() + +block: + macro foo(a: openArray[string] = []): string = + echo a # Segfault doesn't happen if this is removed + newLit "" + + proc bar(a: static[openArray[string]] = []) = + const tmp = foo(a) + + # bug #22909 + doAssert not compiles(bar()) diff --git a/tests/arc/tarc_orc.nim b/tests/arc/tarc_orc.nim index c6a7845b0..f2c7de2fc 100644 --- a/tests/arc/tarc_orc.nim +++ b/tests/arc/tarc_orc.nim @@ -33,3 +33,154 @@ proc bug20303() = doAssert res == "are" bug20303() + +proc main() = # todo bug with templates + block: # bug #11267 + var a: seq[char] = block: @[] + doAssert a == @[] + # 2 + proc b: seq[string] = + discard + @[] + doAssert b() == @[] +static: main() +main() + + +type Obj = tuple + value: int + arr: seq[int] + +proc bug(): seq[Obj] = + result.add (value: 0, arr: @[]) + result[^1].value = 1 + result[^1].arr.add 1 + +# bug #19990 +let s = bug() +doAssert s[0] == (value: 1, arr: @[1]) + +block: # bug #21974 + type Test[T] = ref object + values : seq[T] + counter: int + + proc newTest[T](): Test[T] = + result = new(Test[T]) + result.values = newSeq[T](16) + result.counter = 0 + + proc push[T](self: Test[T], value: T) = + self.counter += 1 + if self.counter >= self.values.len: + self.values.setLen(self.values.len * 2) + self.values[self.counter - 1] = value + + proc pop[T](self: Test[T]): T = + result = self.values[0] + self.values[0] = self.values[self.counter - 1] # <--- This line + self.counter -= 1 + + + type X = tuple + priority: int + value : string + + var a = newTest[X]() + a.push((1, "One")) + doAssert a.pop.value == "One" + +# bug #21987 + +type + EmbeddedImage* = distinct Image + Image = object + len: int + +proc imageCopy*(image: Image): Image {.nodestroy.} + +proc `=destroy`*(x: var Image) = + discard +proc `=sink`*(dest: var Image; source: Image) = + `=destroy`(dest) + wasMoved(dest) + +proc `=dup`*(source: Image): Image {.nodestroy.} = + result = imageCopy(source) + +proc `=copy`*(dest: var Image; source: Image) = + dest = imageCopy(source) # calls =sink implicitly + +proc `=destroy`*(x: var EmbeddedImage) = discard + +proc `=dup`*(source: EmbeddedImage): EmbeddedImage {.nodestroy.} = source + +proc `=copy`*(dest: var EmbeddedImage; source: EmbeddedImage) {.nodestroy.} = + dest = source + +proc imageCopy*(image: Image): Image = + result = image + +proc main2 = + block: + var a = Image(len: 2).EmbeddedImage + var b = Image(len: 1).EmbeddedImage + b = a + doAssert Image(a).len == 2 + doAssert Image(b).len == 2 + + block: + var a = Image(len: 2) + var b = Image(len: 1) + b = a + doAssert a.len == 2 + doAssert b.len == 0 + +main2() + +block: + type + TestObj = object of RootObj + name: string + + TestSubObj = object of TestObj + objname: string + + proc `=destroy`(x: TestObj) = + `=destroy`(x.name) + + proc `=destroy`(x: TestSubObj) = + `=destroy`(x.objname) + `=destroy`(TestObj(x)) + + proc testCase() = + let t1 {.used.} = TestSubObj(objname: "tso1", name: "to1") + + proc main() = + testCase() + + main() + +block: # bug #23858 + type Object = object + a: int + b: ref int + var x = 0 + proc fn(): auto {.cdecl.} = + inc x + return Object() + discard fn() + doAssert x == 1 + +block: # bug #24147 + type + O = object of RootObj + val: string + OO = object of O + + proc `=copy`(dest: var O, src: O) = + dest.val = src.val + + let oo = OO(val: "hello world") + var ooCopy : OO + `=copy`(ooCopy, oo) diff --git a/tests/arc/tarcmisc.nim b/tests/arc/tarcmisc.nim index 45d1514cd..b4476ef4f 100644 --- a/tests/arc/tarcmisc.nim +++ b/tests/arc/tarcmisc.nim @@ -1,5 +1,7 @@ discard """ output: ''' +Destructor for TestTestObj +=destroy called 123xyzabc destroyed: false destroyed: false @@ -26,18 +28,90 @@ new line after - @['a'] finalizer aaaaa hello -ok true copying 123 42 -closed +@["", "d", ""] +ok destroying variable: 20 destroying variable: 10 +closed ''' - cmd: "nim c --gc:arc --deepcopy:on -d:nimAllocPagesViaMalloc $file" + cmd: "nim c --mm:arc --deepcopy:on -d:nimAllocPagesViaMalloc $file" """ +block: # bug #23627 + type + TestObj = object of RootObj + + Test2 = object of RootObj + foo: TestObj + + TestTestObj = object of RootObj + shit: TestObj + + proc `=destroy`(x: TestTestObj) = + echo "Destructor for TestTestObj" + let test = Test2(foo: TestObj()) + + proc testCaseT() = + let tt1 {.used.} = TestTestObj(shit: TestObj()) + + + proc main() = + testCaseT() + + main() + + +# bug #9401 + +type + MyObj = object + len: int + data: ptr UncheckedArray[float] + +proc `=destroy`*(m: MyObj) = + + echo "=destroy called" + + if m.data != nil: + deallocShared(m.data) + +type + MyObjDistinct = distinct MyObj + +proc `=copy`*(m: var MyObj, m2: MyObj) = + if m.data == m2.data: return + if m.data != nil: + `=destroy`(m) + m.len = m2.len + if m.len > 0: + m.data = cast[ptr UncheckedArray[float]](allocShared(sizeof(float) * m.len)) + copyMem(m.data, m2.data, sizeof(float) * m.len) + + +proc `=sink`*(m: var MyObj, m2: MyObj) = + if m.data != m2.data: + if m.data != nil: + `=destroy`(m) + m.len = m2.len + m.data = m2.data + +proc newMyObj(len: int): MyObj = + result.len = len + result.data = cast[ptr UncheckedArray[float]](allocShared(sizeof(float) * len)) + +proc newMyObjDistinct(len: int): MyObjDistinct = + MyObjDistinct(newMyObj(len)) + +proc fooDistinct = + doAssert newMyObjDistinct(2).MyObj.len == 2 + +fooDistinct() + + proc takeSink(x: sink string): bool = true proc b(x: sink string): string = @@ -55,7 +129,7 @@ bbb("123") type Variable = ref object value: int -proc `=destroy`(self: var typeof(Variable()[])) = +proc `=destroy`(self: typeof(Variable()[])) = echo "destroying variable: ",self.value proc newVariable(value: int): Variable = @@ -75,7 +149,7 @@ proc test(count: int) = test(3) proc test2(count: int) = - #block: #XXX: Fails with block currently + block: #XXX: Fails with block currently var v {.global.} = newVariable(20) var count = count - 1 @@ -109,7 +183,7 @@ type B = ref object of A x: int -proc `=destroy`(x: var AObj) = +proc `=destroy`(x: AObj) = close(x.io) echo "closed" @@ -497,3 +571,266 @@ proc fooz(sec: var InputSectionBase) = var sec = create(InputSection) sec[] = InputSection(relocations: newSeq[int]()) fooz sec[] + +block: + type + Data = ref object + id: int + proc main = + var x = Data(id: 99) + var y = x + x[] = Data(id: 778)[] + doAssert y.id == 778 + doAssert x[].id == 778 + main() + +block: # bug #19857 + type + ValueKind = enum VNull, VFloat, VObject # need 3 elements. Cannot remove VNull or VObject + + Value = object + case kind: ValueKind + of VFloat: fnum: float + of VObject: tab: Table[int, int] # OrderedTable[T, U] also makes it fail. + # "simpler" types also work though + else: discard # VNull can be like this, but VObject must be filled + + # required. Pure proc works + FormulaNode = proc(c: OrderedTable[string, int]): Value + + proc toF(v: Value): float = + doAssert v.kind == VFloat + case v.kind + of VFloat: result = v.fnum + else: discard + + + proc foo() = + let fuck = initOrderedTable[string, int]() + proc cb(fuck: OrderedTable[string, int]): Value = + # works: + #result = Value(kind: VFloat, fnum: fuck["field_that_does_not_exist"].float) + # broken: + discard "actuall runs!" + let t = fuck["field_that_does_not_exist"] + echo "never runs, but we crash after! ", t + + doAssertRaises(KeyError): + let fn = FormulaNode(cb) + let v = fn(fuck) + #echo v + let res = v.toF() + + foo() + +import std/options + +# bug #21592 +type Event* = object + code*: string + +type App* = ref object of RootObj + id*: string + +method process*(self: App): Option[Event] {.base.} = + raise Exception.new_exception("not impl") + +# bug #21617 +type Test2 = ref object of RootObj + +method bug(t: Test2): seq[float] {.base.} = discard + +block: # bug #22664 + type + ElementKind = enum String, Number + Element = object + case kind: ElementKind + of String: + str: string + of Number: + num: float + Calc = ref object + stack: seq[Element] + + var calc = new Calc + + calc.stack.add Element(kind: Number, num: 200.0) + doAssert $calc.stack == "@[(kind: Number, num: 200.0)]" + let calc2 = calc + calc2.stack = calc.stack # This nulls out the object in the stack + doAssert $calc.stack == "@[(kind: Number, num: 200.0)]" + doAssert $calc2.stack == "@[(kind: Number, num: 200.0)]" + +block: # bug #19250 + type + Bar[T] = object + err: proc(): string + + Foo[T] = object + run: proc(): Bar[T] + + proc bar[T](err: proc(): string): Bar[T] = + assert not err.isNil + Bar[T](err: err) + + proc foo(): Foo[char] = + result.run = proc(): Bar[char] = + # works + # result = Bar[char](err: proc(): string = "x") + # not work + result = bar[char](proc(): string = "x") + + proc bug[T](fs: Foo[T]): Foo[T] = + result.run = proc(): Bar[T] = + let res = fs.run() + + # works + # var errors = @[res.err] + + # not work + var errors: seq[proc(): string] + errors.add res.err + + return bar[T] do () -> string: + for err in errors: + result.add res.err() + + doAssert bug(foo()).run().err() == "x" + +block: # bug #22259 + type + ProcWrapper = tuple + p: proc() {.closure.} + + + proc f(wrapper: ProcWrapper) = + let s = @[wrapper.p] + let a = [wrapper.p] + + proc main = + # let wrapper: ProcWrapper = ProcWrapper(p: proc {.closure.} = echo 10) + let wrapper: ProcWrapper = (p: proc {.closure.} = echo 10) + f(wrapper) + + main() + +block: + block: # bug #22923 + block: + let + a: int = 100 + b: int32 = 200'i32 + + let + x = arrayWith(a, 8) # compiles + y = arrayWith(b, 8) # internal error + z = arrayWith(14, 8) # integer literal also results in a crash + + doAssert x == [100, 100, 100, 100, 100, 100, 100, 100] + doAssert $y == "[200, 200, 200, 200, 200, 200, 200, 200]" + doAssert z == [14, 14, 14, 14, 14, 14, 14, 14] + + block: + let a: string = "nim" + doAssert arrayWith(a, 3) == ["nim", "nim", "nim"] + + let b: char = 'c' + doAssert arrayWith(b, 3) == ['c', 'c', 'c'] + + let c: uint = 300'u + doAssert $arrayWith(c, 3) == "[300, 300, 300]" + +block: # bug #23505 + type + K = object + C = object + value: ptr K + + proc init(T: type C): C = + let tmp = new K + C(value: addr tmp[]) + + discard init(C) + +block: # bug #23524 + type MyType = object + a: int + + proc `=destroy`(typ: MyType) = discard + + var t1 = MyType(a: 100) + var t2 = t1 # Should be a copy? + + proc main() = + t2 = t1 + doAssert t1.a == 100 + doAssert t2.a == 100 + + main() + +block: # bug #23907 + type + Thingy = object + value: int + + ExecProc[C] = proc(value: sink C): int {.nimcall.} + + proc `=copy`(a: var Thingy, b: Thingy) {.error.} + + var thingyDestroyCount = 0 + + proc `=destroy`(thingy: Thingy) = + assert(thingyDestroyCount <= 0) + thingyDestroyCount += 1 + + proc store(value: sink Thingy): int = + result = value.value + + let callback: ExecProc[Thingy] = store + + doAssert callback(Thingy(value: 123)) == 123 + +import std/strutils + +block: # bug #23974 + func g(e: seq[string]): lent seq[string] = result = e + proc k(f: string): seq[string] = f.split("/") + proc n() = + const r = "/d/" + let t = + if true: + k(r).g() + else: + k("/" & r).g() + echo t + + n() + +block: # bug #23973 + func g(e: seq[string]): lent seq[string] = result = e + proc k(f: string): seq[string] = f.split("/") + proc n() = + const r = "/test/empty" # or "/test/empty/1" + let a = k(r).g() + let t = + if true: + k(r).g() + else: + k("/" & r).g() # or raiseAssert "" + doAssert t == a + + n() + +block: # bug #24141 + func reverse(s: var openArray[char]) = + s[0] = 'f' + + func rev(s: var string) = + s.reverse + + proc main = + var abc = "abc" + abc.rev + doAssert abc == "fbc" + + main() diff --git a/tests/arc/tasyncleak.nim b/tests/arc/tasyncleak.nim index eb0c45213..8e3a7b3e7 100644 --- a/tests/arc/tasyncleak.nim +++ b/tests/arc/tasyncleak.nim @@ -1,5 +1,5 @@ discard """ - outputsub: "(allocCount: 4302, deallocCount: 4300)" + outputsub: "(allocCount: 4050, deallocCount: 4048)" cmd: "nim c --gc:orc -d:nimAllocStats $file" """ diff --git a/tests/arc/tcaseobj.nim b/tests/arc/tcaseobj.nim index d52833e4d..3499f5c1e 100644 --- a/tests/arc/tcaseobj.nim +++ b/tests/arc/tcaseobj.nim @@ -60,7 +60,7 @@ proc `=destroy`(o: var TMyObj) = o.p = nil echo "myobj destroyed" -proc `=`(dst: var TMyObj, src: TMyObj) = +proc `=copy`(dst: var TMyObj, src: TMyObj) = `=destroy`(dst) dst.p = alloc(src.len) dst.len = src.len @@ -170,18 +170,24 @@ proc test_myobject = x.x1 = "x1" x.x2 = "x2" x.y1 = "ljhkjhkjh" - x.kind1 = true + {.cast(uncheckedAssign).}: + x.kind1 = true x.y2 = @["1", "2"] - x.kind2 = true + {.cast(uncheckedAssign).}: + x.kind2 = true x.z1 = "yes" - x.kind2 = false + {.cast(uncheckedAssign).}: + x.kind2 = false x.z2 = @["1", "2"] - x.kind2 = true + {.cast(uncheckedAssign).}: + x.kind2 = true x.z1 = "yes" x.kind2 = true # should be no effect doAssert(x.z1 == "yes") - x.kind2 = false - x.kind1 = x.kind2 # support self assignment with effect + {.cast(uncheckedAssign).}: + x.kind2 = false + {.cast(uncheckedAssign).}: + x.kind1 = x.kind2 # support self assignment with effect try: x.kind1 = x.flag # flag is not accesible @@ -207,8 +213,9 @@ type error*: string proc init(): RocksDBResult[string] = - result.ok = true - result.value = "ok" + {.cast(uncheckedAssign).}: + result.ok = true + result.value = "ok" echo init() @@ -222,7 +229,8 @@ type MyObj = object of true: x1: string var a = MyObj(kind: false, x0: 1234) -a.kind = true +{.cast(uncheckedAssign).}: + a.kind = true doAssert(a.x1 == "") block: @@ -269,3 +277,90 @@ proc bug20305 = echo x.pChildren bug20305() + +# bug #21023 +block: + block: + type + MGErrorKind = enum + mgeUnexpected, mgeNotFound + + type Foo = object + kind: MGErrorKind + ex: Exception + + type Boo = object + a: seq[int] + + type + Result2 = object + case o: bool + of false: + e: Foo + of true: + v: Boo + + proc startSessionSync(): Result2 = + return Result2(o: true) + + proc mainSync = + let ff = startSessionSync() + doAssert ff.o == true + + mainSync() + + block: + type + MGErrorKind = enum + mgeUnexpected, mgeNotFound + + type Foo = object + kind: MGErrorKind + ex: Exception + + type Boo = object + a: seq[int] + + type + Result2 = object + case o: bool + of false: + e: Foo + of true: + v: Boo + s: int + + proc startSessionSync(): Result2 = + return Result2(o: true, s: 12) + + proc mainSync = + let ff = startSessionSync() + doAssert ff.s == 12 + + mainSync() + +import std/sequtils + +# bug #23690 +type + SomeObj* = object of RootObj + + Item* = object + case kind*: 0..1 + of 0: + a*: int + b*: SomeObj + of 1: + c*: string + + ItemExt* = object + a*: Item + b*: string + +proc do1(x: int): seq[(string, Item)] = + result = @[("zero", Item(kind: 1, c: "first"))] + +proc do2(x: int, e: ItemExt): seq[(string, ItemExt)] = + do1(x).map(proc(v: (string, Item)): auto = (v[0], ItemExt(a: v[1], b: e.b))) + +doAssert $do2(0, ItemExt(a: Item(kind: 1, c: "second"), b: "third")) == """@[("zero", (a: (kind: 1, c: "first"), b: "third"))]""" diff --git a/tests/arc/tcaseobjcopy.nim b/tests/arc/tcaseobjcopy.nim index ed07b404e..fb26a4973 100644 --- a/tests/arc/tcaseobjcopy.nim +++ b/tests/arc/tcaseobjcopy.nim @@ -169,18 +169,23 @@ proc test_myobject = x.x1 = "x1" x.x2 = "x2" x.y1 = "ljhkjhkjh" - x.kind1 = true + {.cast(uncheckedAssign).}: + x.kind1 = true x.y2 = @["1", "2"] - x.kind2 = true + {.cast(uncheckedAssign).}: + x.kind2 = true x.z1 = "yes" - x.kind2 = false + {.cast(uncheckedAssign).}: + x.kind2 = false x.z2 = @["1", "2"] - x.kind2 = true + {.cast(uncheckedAssign).}: + x.kind2 = true x.z1 = "yes" x.kind2 = true # should be no effect doAssert(x.z1 == "yes") - x.kind2 = false - x.kind1 = x.kind2 # support self assignment with effect + {.cast(uncheckedAssign).}: + x.kind2 = false + x.kind1 = x.kind2 # support self assignment with effect try: x.kind1 = x.flag # flag is not accesible @@ -206,7 +211,8 @@ type error*: string proc init(): RocksDBResult[string] = - result.ok = true + {.cast(uncheckedAssign).}: + result.ok = true result.value = "ok" echo init() @@ -221,7 +227,8 @@ type MyObj = object of true: x1: string var a = MyObj(kind: false, x0: 1234) -a.kind = true +{.cast(uncheckedAssign).}: + a.kind = true doAssert(a.x1 == "") block: diff --git a/tests/arc/tcomputedgoto.nim b/tests/arc/tcomputedgoto.nim index 541a748c6..07487684a 100644 --- a/tests/arc/tcomputedgoto.nim +++ b/tests/arc/tcomputedgoto.nim @@ -1,16 +1,19 @@ discard """ - cmd: '''nim c --gc:arc $file''' - output: '''2 -2''' + cmd: '''nim c --mm:arc $file''' + output: ''' +2 +2 +destroyed +''' """ type ObjWithDestructor = object a: int -proc `=destroy`(self: var ObjWithDestructor) = +proc `=destroy`(self: ObjWithDestructor) = echo "destroyed" -proc `=`(self: var ObjWithDestructor, other: ObjWithDestructor) = +proc `=copy`(self: var ObjWithDestructor, other: ObjWithDestructor) = echo "copied" proc test(a: range[0..1], arg: ObjWithDestructor) = @@ -38,4 +41,4 @@ proc test(a: range[0..1], arg: ObjWithDestructor) = if iteration == 2: break -test(1, ObjWithDestructor()) \ No newline at end of file +test(1, ObjWithDestructor()) diff --git a/tests/arc/tcomputedgotocopy.nim b/tests/arc/tcomputedgotocopy.nim index 8337123ba..07487684a 100644 --- a/tests/arc/tcomputedgotocopy.nim +++ b/tests/arc/tcomputedgotocopy.nim @@ -1,13 +1,16 @@ discard """ - cmd: '''nim c --gc:arc $file''' - output: '''2 -2''' + cmd: '''nim c --mm:arc $file''' + output: ''' +2 +2 +destroyed +''' """ type ObjWithDestructor = object a: int -proc `=destroy`(self: var ObjWithDestructor) = +proc `=destroy`(self: ObjWithDestructor) = echo "destroyed" proc `=copy`(self: var ObjWithDestructor, other: ObjWithDestructor) = diff --git a/tests/arc/tcontrolflow.nim b/tests/arc/tcontrolflow.nim index 80cc2b187..dbc115903 100644 --- a/tests/arc/tcontrolflow.nim +++ b/tests/arc/tcontrolflow.nim @@ -76,7 +76,7 @@ var c = Control(x: 7) run(c) -proc sysFatal(exceptn: typedesc, message: string) {.inline, noreturn.} = +proc sysFatal(exceptn: typedesc, message: string) {.inline.} = var buf = newStringOfCap(200) add(buf, "##") add(buf, message) diff --git a/tests/arc/tdup.nim b/tests/arc/tdup.nim new file mode 100644 index 000000000..61f262a68 --- /dev/null +++ b/tests/arc/tdup.nim @@ -0,0 +1,71 @@ +discard """ + cmd: "nim c --mm:arc --expandArc:foo --hints:off $file" + nimout: ''' +--expandArc: foo + +var + x + :tmpD + s + :tmpD_1 +x = Ref(id: 8) +inc: + :tmpD = `=dup`(x) + :tmpD +inc: + let blitTmp = x + blitTmp +var id_1 = 777 +s = RefCustom(id_2: addr(id_1)) +inc_1 : + :tmpD_1 = `=dup_1`(s) + :tmpD_1 +inc_1 : + let blitTmp_1 = s + blitTmp_1 +-- end of expandArc ------------------------ +''' +""" + +type + Ref = ref object + id: int + + RefCustom = object + id: ptr int + +proc `=dup`(x: RefCustom): RefCustom = + result.id = x.id + +proc inc(x: sink Ref) = + inc x.id + +proc inc(x: sink RefCustom) = + inc x.id[] + + +proc foo = + var x = Ref(id: 8) + inc(x) + inc(x) + var id = 777 + var s = RefCustom(id: addr id) + inc s + inc s + +foo() + +proc foo2 = + var x = Ref(id: 8) + inc(x) + doAssert x.id == 9 + inc(x) + doAssert x.id == 10 + var id = 777 + var s = RefCustom(id: addr id) + inc s + doAssert s.id[] == 778 + inc s + doAssert s.id[] == 779 + +foo2() diff --git a/tests/arc/texplicit_sink.nim b/tests/arc/texplicit_sink.nim new file mode 100644 index 000000000..4b021ed62 --- /dev/null +++ b/tests/arc/texplicit_sink.nim @@ -0,0 +1,29 @@ +discard """ + output: '''de''' + cmd: '''nim c --mm:arc --expandArc:main $file''' + nimout: '''--expandArc: main + +var + a + b_cursor +try: + a = f "abc" + b_cursor = "de" + `=sink`(a, b_cursor) + echo [a] +finally: + `=destroy`(a) +-- end of expandArc ------------------------''' +""" + +# bug #20572 + +proc f(s: string): string = s + +proc main = + var a = f "abc" + var b = "de" + `=sink`(a, b) + echo a + +main() diff --git a/tests/arc/thard_alignment.nim b/tests/arc/thard_alignment.nim index baa964c77..30cfddb05 100644 --- a/tests/arc/thard_alignment.nim +++ b/tests/arc/thard_alignment.nim @@ -1,9 +1,11 @@ discard """ disabled: "arm64" -cmd: "nim c --gc:arc $file" +cmd: "nim c --mm:arc -u:nimPreviewNonVarDestructor $file" output: "y" """ +# TODO: fixme: investigate why it failed with non-var destructors + {.passC: "-march=native".} proc isAlignedCheck(p: pointer, alignment: int) = diff --git a/tests/arc/titeration_doesnt_copy.nim b/tests/arc/titeration_doesnt_copy.nim new file mode 100644 index 000000000..e510a6eff --- /dev/null +++ b/tests/arc/titeration_doesnt_copy.nim @@ -0,0 +1,67 @@ +discard """ + output: "true" +""" + +type + Idx = object + i: int + Node = object + n: int + next: seq[Idx] + FooBar = object + s: seq[Node] + +proc `=copy`(dest: var Idx; source: Idx) {.error.} +proc `=copy`(dest: var Node; source: Node) {.error.} +proc `=copy`(dest: var FooBar; source: FooBar) {.error.} + +proc doSomething(ss: var seq[int], s: FooBar) = + for i in 0 .. s.s.len-1: + for elm in items s.s[i].next: + ss.add s.s[elm.i].n + +when isMainModule: + const foo = FooBar(s: @[Node(n: 1, next: @[Idx(i: 0)])]) + var ss: seq[int] + doSomething(ss, foo) + echo ss == @[1] + +from sequtils import mapIt +from strutils import join + +proc toBinSeq*(b: uint8): seq[uint8] = + ## Return binary sequence from each bits of uint8. + runnableExamples: + from sequtils import repeat + doAssert 0'u8.toBinSeq == 0'u8.repeat(8) + doAssert 0b1010_1010.toBinSeq == @[1'u8, 0, 1, 0, 1, 0, 1, 0] + result = @[] + var c = b + for i in 1..8: + result.add (uint8(c and 0b1000_0000) shr 7) + c = c shl 1 + +proc toBinString*(data: openArray[uint8], col: int): string = + ## Return binary string from each bits of uint8. + runnableExamples: + doAssert @[0b0000_1111'u8, 0b1010_1010].toBinString(8) == "0000111110101010" + doAssert @[0b1000_0000'u8, 0b0000_0000].toBinString(1) == "10" + result = "" + for b in items data.mapIt(it.toBinSeq.mapIt(it.`$`[0].char)): + for i, c in b: + if i < col: + result.add c + +doAssert @[0b0000_1111'u8, 0b1010_1010].toBinString(8) == "0000111110101010" +doAssert @[0b1000_0000'u8, 0b0000_0000].toBinString(1) == "10" + +block: # bug #23982 + iterator `..`(a, b: ptr int16): ptr int16 = discard + var a: seq[int16] #; let p = a[0].addr + var b: seq[ptr int16] + + try: + for x in a[0].addr .. b[1]: # `p .. b[1]` works + discard + except IndexDefect: + discard diff --git a/tests/arc/tmalloc.nim b/tests/arc/tmalloc.nim new file mode 100644 index 000000000..1d72646c8 --- /dev/null +++ b/tests/arc/tmalloc.nim @@ -0,0 +1,16 @@ +discard """ + matrix: "--mm:arc -d:useMalloc; --mm:arc" +""" + +block: # bug #22058 + template foo(): auto = + {.noSideEffect.}: + newSeq[byte](1) + + type V = object + v: seq[byte] + + proc bar(): V = + V(v: foo()) + + doAssert bar().v == @[byte(0)] diff --git a/tests/arc/tmove_regression.nim b/tests/arc/tmove_regression.nim new file mode 100644 index 000000000..7d9a867c3 --- /dev/null +++ b/tests/arc/tmove_regression.nim @@ -0,0 +1,22 @@ +discard """ + output: '''/1/2 +/1 +/ +''' +"""" + +# bug #22001 + +import std / [os, strutils] + +proc finOp2(path, name: string): (string, File) = # Find & open FIRST `name` + var current = path + while true: + if current.isRootDir: break # <- current=="" => current.isRootDir + current = current.parentDir + let dir = current + echo dir.replace('\\', '/') # Commenting out try/except below hides bug + try: result[0] = dir/name; result[1] = open(result[0]); return + except CatchableError: discard + +discard finOp2("/1/2/3", "4") # All same if this->inside a proc diff --git a/tests/arc/tmovebug.nim b/tests/arc/tmovebug.nim index 002bd6796..8ad7c955c 100644 --- a/tests/arc/tmovebug.nim +++ b/tests/arc/tmovebug.nim @@ -93,6 +93,7 @@ destroy destroy destroy sink +sink destroy copy (f: 1) @@ -767,8 +768,7 @@ proc initC(): C = C(o: initO()) proc pair(): tuple[a: C, b: C] = - result.a = initC() # <- when firstWrite tries to find this node to start its analysis it fails, because injectdestructors uses copyTree/shallowCopy - result.b = initC() + result = (a: initC(), b: initC())# <- when firstWrite tries to find this node to start its analysis it fails, because injectdestructors uses copyTree/shallowCopy discard pair() @@ -818,3 +818,24 @@ proc atomicClosureOp = atomicClosureOp() + +template assertEq(a, b: untyped): untyped = + block: + let + aval = a + bval = b + + if aval != bval: + quit "bug!" + +proc convoluted = + let _ = (; + var val1: string; + if true: val1 = "22" + true + ) + + assertEq val1, "22" + assertEq val1, "22" + +convoluted() diff --git a/tests/arc/topenarray.nim b/tests/arc/topenarray.nim index 03ec7adf2..ba91666ba 100644 --- a/tests/arc/topenarray.nim +++ b/tests/arc/topenarray.nim @@ -6,6 +6,8 @@ Nim ''' matrix: "--gc:arc -d:useMalloc; --gc:arc" """ +{.experimental: "views".} + block: # bug 18627 proc setPosition(params: openArray[string]) = for i in params.toOpenArray(0, params.len - 1): @@ -22,3 +24,63 @@ block: # bug 18627 for i in params.toOpenArray(0, params.len - 1): echo i uciLoop2() + +when defined(nimPreviewSlimSystem): + import std/assertions + +block: # bug #20954 + block: + doAssertRaises(IndexDefect): + var v: array[10, int] + + echo len(toOpenArray(v, 20, 30)) + + block: + doAssertRaises(IndexDefect): + var v: seq[int] + + echo len(toOpenArray(v, 20, 30)) + +# bug #20422 + +proc f(a: var string) = + var v = a.toOpenArray(1, 3) + v[0] = 'a' + +var a = "Hello" +f(a) +doAssert a == "Hallo" + +# bug #22132 +block: + func foo[T](arr: openArray[T], idx: int = arr.low): string = + doAssert idx == 0 + return $arr + + let bug = ["0", "c", "a"] + + let str = foo(bug) + + const expected = """["0", "c", "a"]""" + doAssert str == expected + + const noBugConst = ["0", "c", "a"] + doAssert foo(noBugConst) == expected + let noBugSeq = @["0", "c", "a"] + doAssert foo(noBugSeq) == expected + +block: # bug #20865 + var p: pointer + var x: array[0, int] + # echo toOpenArray(x, 0, 1)[0] # Raises IndexDefect + doAssertRaises(IndexDefect): + echo toOpenArray(cast[ptr array[0, int]](p)[], 0, 1)[0] # Does not raise IndexDefect + +block: # bug #20987 + var v: array[1, byte] + + var p = cast[ptr array[0, byte]](addr v) + + doAssertRaises(IndexDefect): + echo toOpenArray(p[], 1, 2) + diff --git a/tests/arc/topt_no_cursor.nim b/tests/arc/topt_no_cursor.nim index 0de7f41b9..0a4984a69 100644 --- a/tests/arc/topt_no_cursor.nim +++ b/tests/arc/topt_no_cursor.nim @@ -1,23 +1,20 @@ discard """ - output: '''(package: "", ext: "meo") -doing shady stuff... -3 -6 -(@[1], @[2]) -192.168.0.1 -192.168.0.1 -192.168.0.1 -192.168.0.1''' - cmd: '''nim c --gc:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off --assertions:off --expandArc:extractConfig --expandArc:mergeShadowScope --expandArc:check $file''' - nimout: '''--expandArc: newTarget + nimoutFull: true + cmd: '''nim c -r --warnings:off --hints:off --mm:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off --assertions:off --expandArc:extractConfig --expandArc:mergeShadowScope --expandArc:check $file''' + nimout: ''' +--expandArc: newTarget +var + splat + :tmp + :tmp_1 splat = splitDrive do: let blitTmp = path blitTmp :tmp = splat.drive -wasMoved(splat.drive) +`=wasMoved`(splat.drive) :tmp_1 = splat.path_1 -wasMoved(splat.path_1) +`=wasMoved`(splat.path_1) result = ( let blitTmp_1 = :tmp blitTmp_1, @@ -42,14 +39,14 @@ var lresult lvalue lnext - _ + tmpTupleAsgn lresult = @[123] -_ = ( +tmpTupleAsgn = ( let blitTmp = lresult blitTmp, ";") -lvalue = _[0] -lnext = _[1] -result.value = move lvalue +lvalue = tmpTupleAsgn[0] +lnext = tmpTupleAsgn[1] +`=sink`(result.value, move lvalue) `=destroy`(lnext) `=destroy_1`(lvalue) -- end of expandArc ------------------------ @@ -64,11 +61,9 @@ var try: it_cursor = x a = ( - wasMoved(:tmpD) - `=copy`(:tmpD, it_cursor.key) + :tmpD = `=dup`(it_cursor.key) :tmpD, - wasMoved(:tmpD_1) - `=copy`(:tmpD_1, it_cursor.val) + :tmpD_1 = `=dup`(it_cursor.val) :tmpD_1) echo [ :tmpD_2 = `$$`(a) @@ -96,11 +91,14 @@ try: `=copy`(lan_ip, splitted[1]) echo [lan_ip] echo [splitted[1]] + {.push, overflowChecks: false.} inc(i, 1) + {.pop.} finally: `=destroy`(splitted) finally: `=destroy_1`(lan_ip) +-- end of expandArc ------------------------ --expandArc: mergeShadowScope var shadowScope @@ -115,10 +113,11 @@ block :tmp: var :tmpD sym = shadowScope.symbols[i] addInterfaceDecl(c): - wasMoved(:tmpD) - `=copy_1`(:tmpD, sym) + :tmpD = `=dup`(sym) :tmpD + {.push, overflowChecks: false.} inc(i, 1) + {.pop.} `=destroy`(shadowScope) -- end of expandArc ------------------------ --expandArc: check @@ -128,19 +127,16 @@ this.isValid = fileExists(this.value) if dirExists(this.value): var :tmpD par = (dir: - wasMoved(:tmpD) - `=copy`(:tmpD, this.value) + :tmpD = `=dup`(this.value) :tmpD, front: "") else: var :tmpD_1 :tmpD_2 :tmpD_3 par = (dir_1: parentDir(this.value), front_1: - wasMoved(:tmpD_1) - `=copy`(:tmpD_1, + :tmpD_1 = `=dup`( :tmpD_3 = splitDrive do: - wasMoved(:tmpD_2) - `=copy`(:tmpD_2, this.value) + :tmpD_2 = `=dup`(this.value) :tmpD_2 :tmpD_3.path) :tmpD_1) @@ -150,7 +146,21 @@ if dirExists(par.dir): else: `=sink`(this.matchDirs, []) `=destroy`(par) --- end of expandArc ------------------------''' +-- end of expandArc ------------------------ +--expandArc: check + +check(this) +-- end of expandArc ------------------------ +(package: "", ext: "meo") +doing shady stuff... +3 +6 +(@[1], @[2]) +192.168.0.1 +192.168.0.1 +192.168.0.1 +192.168.0.1 +''' """ import os, std/private/ntpath diff --git a/tests/arc/topt_refcursors.nim b/tests/arc/topt_refcursors.nim index c13d81bad..8c638a4a1 100644 --- a/tests/arc/topt_refcursors.nim +++ b/tests/arc/topt_refcursors.nim @@ -1,7 +1,8 @@ discard """ output: '''''' cmd: '''nim c --gc:arc --expandArc:traverse --hint:Performance:off $file''' - nimout: '''--expandArc: traverse + nimout: ''' +--expandArc: traverse var it_cursor @@ -22,12 +23,13 @@ try: `=copy`(ri_1, jt.ri) echo [jt.s] `=sink`(jt, ri_1) - wasMoved(ri_1) + `=wasMoved`(ri_1) finally: `=destroy`(ri_1) finally: `=destroy`(jt) --- end of expandArc ------------------------''' +-- end of expandArc ------------------------ +''' """ type diff --git a/tests/arc/topt_wasmoved_destroy_pairs.nim b/tests/arc/topt_wasmoved_destroy_pairs.nim index 2f971f112..c96340a30 100644 --- a/tests/arc/topt_wasmoved_destroy_pairs.nim +++ b/tests/arc/topt_wasmoved_destroy_pairs.nim @@ -1,7 +1,8 @@ discard """ output: '''''' cmd: '''nim c --gc:arc --expandArc:main --expandArc:tfor --hint:Performance:off $file''' - nimout: '''--expandArc: main + nimout: ''' +--expandArc: main var a @@ -29,6 +30,7 @@ try: x = f() block :tmp: var i_cursor + mixin inc var i_1 = 0 block :tmp_1: while i_1 < 4: @@ -37,25 +39,25 @@ try: if i_cursor == 2: return add(a): - wasMoved(:tmpD) - `=copy`(:tmpD, x) + :tmpD = `=dup`(x) :tmpD inc i_1, 1 if cond: add(a): let blitTmp = x - wasMoved(x) + `=wasMoved`(x) blitTmp else: add(b): let blitTmp_1 = x - wasMoved(x) + `=wasMoved`(x) blitTmp_1 finally: `=destroy`(x) `=destroy_1`(b) `=destroy_1`(a) --- end of expandArc ------------------------''' +-- end of expandArc ------------------------ +''' """ proc f(): seq[int] = diff --git a/tests/arc/trepr.nim b/tests/arc/trepr.nim index 50d433208..abf28330a 100644 --- a/tests/arc/trepr.nim +++ b/tests/arc/trepr.nim @@ -9,6 +9,7 @@ nil 2 Obj(member: ref @["hello"]) ref (member: ref @["hello"]) +ObjUa(v: 0, a: [...]) ''' """ @@ -87,3 +88,10 @@ macro extract(): untyped = test(parseExpr("discard")) extract() + +type + ObjUa = ref object + v: int + a: UncheckedArray[char] + +echo ObjUa().repr diff --git a/tests/arc/tstringliteral.nim b/tests/arc/tstringliteral.nim new file mode 100644 index 000000000..c5fac22d8 --- /dev/null +++ b/tests/arc/tstringliteral.nim @@ -0,0 +1,17 @@ +discard """ + matrix: "--mm:arc; --mm:orc" +""" + +block: # issue #24080 + var a = (s: "a") + var b = "a" + a.s.setLen 0 + b = a.s + doAssert b == "" + +block: # issue #24080, longer string + var a = (s: "abc") + var b = "abc" + a.s.setLen 2 + b = a.s + doAssert b == "ab" diff --git a/tests/arc/tweave.nim b/tests/arc/tweave.nim index 220d65f97..1c60ac403 100644 --- a/tests/arc/tweave.nim +++ b/tests/arc/tweave.nim @@ -8,6 +8,9 @@ discard """ import std/atomics +when defined(nimPreviewSlimSystem): + import std/[assertions, typedthreads] + const MemBlockSize = 256 type diff --git a/tests/arc/twrong_sinkinference.nim b/tests/arc/twrong_sinkinference.nim index 59930a9fa..ecf09d28a 100644 --- a/tests/arc/twrong_sinkinference.nim +++ b/tests/arc/twrong_sinkinference.nim @@ -1,6 +1,6 @@ discard """ cmd: "nim c --gc:arc $file" - errormsg: "type mismatch: got <proc (a: string, b: sink string){.noSideEffect, gcsafe, locks: 0.}>" + errormsg: "type mismatch: got <proc (a: string, b: sink string){.noSideEffect, gcsafe.}>" line: 18 """ |