summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorflywind <xzsflywind@gmail.com>2021-03-03 18:58:50 +0800
committerGitHub <noreply@github.com>2021-03-03 11:58:50 +0100
commit6391f6e861d4c1dc87a94861374973b809f0d09f (patch)
tree33e8cf8f03bdeea5126492efc8d9dd220ed34755
parent4982d1c66212de2762eb4ebff183eaa09b00b1f8 (diff)
downloadNim-6391f6e861d4c1dc87a94861374973b809f0d09f.tar.gz
fix #16384 and #17144 (#17126) [backport]
-rw-r--r--compiler/vm.nim3
-rw-r--r--tests/stdlib/tlists.nim441
2 files changed, 225 insertions, 219 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index ba14f2d51..429419cf8 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1019,7 +1019,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
         let nc = regs[rc].node
         if nb.kind != nc.kind: discard
         elif (nb == nc) or (nb.kind == nkNilLit): ret = true # intentional
-        elif sameConstant(nb, nc): ret = true
+        elif (nb.kind in {nkSym, nkTupleConstr, nkClosure} and nb.typ.kind == tyProc) and sameConstant(nb, nc):
+          ret = true
           # this also takes care of procvar's, represented as nkTupleConstr, e.g. (nil, nil)
         elif nb.kind == nkIntLit and nc.kind == nkIntLit and nb.intVal == nc.intVal: # TODO: nkPtrLit
           let tb = nb.getTyp
diff --git a/tests/stdlib/tlists.nim b/tests/stdlib/tlists.nim
index 2d3165c9c..54fa8b24f 100644
--- a/tests/stdlib/tlists.nim
+++ b/tests/stdlib/tlists.nim
@@ -2,232 +2,237 @@ discard """
   targets: "c js"
 """
 
-import lists, sequtils
+import std/[lists, sequtils]
 
 const
   data = [1, 2, 3, 4, 5, 6]
 
-block SinglyLinkedListTest1:
-  var L: SinglyLinkedList[int]
-  for d in items(data): L.prepend(d)
-  for d in items(data): L.add(d)
-  doAssert($L == "[6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6]")
-
-  doAssert(4 in L)
-
-block SinglyLinkedListTest2:
-  var L: SinglyLinkedList[string]
-  for d in items(data): L.prepend($d)
-  doAssert($L == """["6", "5", "4", "3", "2", "1"]""")
-
-  doAssert("4" in L)
-
-
-block DoublyLinkedListTest1:
-  var L: DoublyLinkedList[int]
-  for d in items(data): L.prepend(d)
-  for d in items(data): L.add(d)
-  L.remove(L.find(1))
-  doAssert($L == "[6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6]")
-
-  doAssert(4 in L)
-
-block SinglyLinkedRingTest1:
-  var L: SinglyLinkedRing[int]
-  L.prepend(4)
-  doAssert($L == "[4]")
-  L.prepend(4)
-
-  doAssert($L == "[4, 4]")
-  doAssert(4 in L)
-
-
-block DoublyLinkedRingTest1:
-  var L: DoublyLinkedRing[int]
-  L.prepend(4)
-  doAssert($L == "[4]")
-  L.prepend(4)
-
-  doAssert($L == "[4, 4]")
-  doAssert(4 in L)
-
-  L.add(3)
-  L.add(5)
-  doAssert($L == "[4, 4, 3, 5]")
-
-  L.remove(L.find(3))
-  L.remove(L.find(5))
-  L.remove(L.find(4))
-  L.remove(L.find(4))
-  doAssert($L == "[]")
-  doAssert(4 notin L)
-
-block tlistsToString:
-  block:
-    var l = initDoublyLinkedList[int]()
-    l.add(1)
-    l.add(2)
-    l.add(3)
-    doAssert $l == "[1, 2, 3]"
-  block:
-    var l = initDoublyLinkedList[string]()
-    l.add("1")
-    l.add("2")
-    l.add("3")
-    doAssert $l == """["1", "2", "3"]"""
-  block:
-    var l = initDoublyLinkedList[char]()
-    l.add('1')
-    l.add('2')
-    l.add('3')
-    doAssert $l == """['1', '2', '3']"""
-
-# Copied here until it is merged into sequtils
-template take(a: untyped, max: int): untyped =
-  type T = typeof(block: (for ai in a: ai))
-  var ret: seq[T]
-  var i = 0
-  if max > 0:
-    for ai in a:
-      ret.add ai
-      i.inc
-      if i >= max: break
-  ret
-
-template testCommon(initList, toList) =
-
-  block: # toSinglyLinkedList, toDoublyLinkedList
-    let l = seq[int].default
-    doAssert l.toList.toSeq == []
-    doAssert [1].toList.toSeq == [1]
-    doAssert [1, 2, 3].toList.toSeq == [1, 2, 3]
-
-  block copy:
-    doAssert array[0, int].default.toList.copy.toSeq == []
-    doAssert [1].toList.copy.toSeq == [1]
-    doAssert [1, 2].toList.copy.toSeq == [1, 2]
-    doAssert [1, 2, 3].toList.copy.toSeq == [1, 2, 3]
-    type Foo = ref object
-      x: int
-    var f0 = Foo(x: 0)
-    let f1 = Foo(x: 1)
-    var a = [f0].toList
-    var b = a.copy
-    b.add f1
-    doAssert a.toSeq == [f0]
-    doAssert b.toSeq == [f0, f1]
-    f0.x = 42
-    doAssert a.head.value.x == 42
-    doAssert b.head.value.x == 42
-
-  block: # add, addMoved
-    block:
-      var
-        l0 = initList[int]()
-        l1 = [1].toList
-        l2 = [2, 3].toList
-        l3 = [4, 5, 6].toList
-      l0.add l3
-      l1.add l3
-      l2.addMoved l3
-      doAssert l0.toSeq == [4, 5, 6]
-      doAssert l1.toSeq == [1, 4, 5, 6]
-      doAssert l2.toSeq == [2, 3, 4, 5, 6]
-      doAssert l3.toSeq == []
-      l2.add l3 # re-adding l3 that was destroyed is now a no-op
-      doAssert l2.toSeq == [2, 3, 4, 5, 6]
-      doAssert l3.toSeq == []
-    block:
-      var
-        l0 = initList[int]()
-        l1 = [1].toList
-        l2 = [2, 3].toList
-        l3 = [4, 5, 6].toList
-      l3.addMoved l0
-      l2.addMoved l1
-      doAssert l3.toSeq == [4, 5, 6]
-      doAssert l2.toSeq == [2, 3, 1]
-      l3.add l0
-      doAssert l3.toSeq == [4, 5, 6]
-    block:
-      var c = [0, 1].toList
-      c.addMoved c
-      doAssert c.take(6) == [0, 1, 0, 1, 0, 1]
 
-  block: # prepend, prependMoved
+template main =
+  block SinglyLinkedListTest1:
+    var L: SinglyLinkedList[int]
+    for d in items(data): L.prepend(d)
+    for d in items(data): L.add(d)
+    doAssert($L == "[6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6]")
+
+    doAssert(4 in L)
+
+  block SinglyLinkedListTest2:
+    var L: SinglyLinkedList[string]
+    for d in items(data): L.prepend($d)
+    doAssert($L == """["6", "5", "4", "3", "2", "1"]""")
+
+    doAssert("4" in L)
+
+
+  block DoublyLinkedListTest1:
+    var L: DoublyLinkedList[int]
+    for d in items(data): L.prepend(d)
+    for d in items(data): L.add(d)
+    L.remove(L.find(1))
+    doAssert($L == "[6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6]")
+
+    doAssert(4 in L)
+
+  block SinglyLinkedRingTest1:
+    var L: SinglyLinkedRing[int]
+    L.prepend(4)
+    doAssert($L == "[4]")
+    L.prepend(4)
+
+    doAssert($L == "[4, 4]")
+    doAssert(4 in L)
+
+
+  block DoublyLinkedRingTest1:
+    var L: DoublyLinkedRing[int]
+    L.prepend(4)
+    doAssert($L == "[4]")
+    L.prepend(4)
+
+    doAssert($L == "[4, 4]")
+    doAssert(4 in L)
+
+    L.add(3)
+    L.add(5)
+    doAssert($L == "[4, 4, 3, 5]")
+
+    L.remove(L.find(3))
+    L.remove(L.find(5))
+    L.remove(L.find(4))
+    L.remove(L.find(4))
+    doAssert($L == "[]")
+    doAssert(4 notin L)
+
+  block tlistsToString:
     block:
-      var
-        l0 = initList[int]()
-        l1 = [1].toList
-        l2 = [2, 3].toList
-        l3 = [4, 5, 6].toList
-      l0.prepend l3
-      l1.prepend l3
-      doAssert l3.toSeq == [4, 5, 6]
-      l2.prependMoved l3
-      doAssert l0.toSeq == [4, 5, 6]
-      doAssert l1.toSeq == [4, 5, 6, 1]
-      doAssert l2.toSeq == [4, 5, 6, 2, 3]
-      doAssert l3.toSeq == []
-      l2.prepend l3 # re-prepending l3 that was destroyed is now a no-op
-      doAssert l2.toSeq == [4, 5, 6, 2, 3]
-      doAssert l3.toSeq == []
+      var l = initDoublyLinkedList[int]()
+      l.add(1)
+      l.add(2)
+      l.add(3)
+      doAssert $l == "[1, 2, 3]"
     block:
-      var
-        l0 = initList[int]()
-        l1 = [1].toList
-        l2 = [2, 3].toList
-        l3 = [4, 5, 6].toList
-      l3.prependMoved l0
-      l2.prependMoved l1
-      doAssert l3.toSeq == [4, 5, 6]
-      doAssert l2.toSeq == [1, 2, 3]
-      l3.prepend l0
-      doAssert l3.toSeq == [4, 5, 6]
+      var l = initDoublyLinkedList[string]()
+      l.add("1")
+      l.add("2")
+      l.add("3")
+      doAssert $l == """["1", "2", "3"]"""
     block:
-      var c = [0, 1].toList
-      c.prependMoved c
-      doAssert c.take(6) == [0, 1, 0, 1, 0, 1]
-
-  block remove:
-    var l = [0, 1, 2, 3].toList
-    let
-      l0 = l.head
-      l1 = l0.next
-      l2 = l1.next
-      l3 = l2.next
-    l.remove l0
-    doAssert l.toSeq == [1, 2, 3]
-    l.remove l2
+      var l = initDoublyLinkedList[char]()
+      l.add('1')
+      l.add('2')
+      l.add('3')
+      doAssert $l == """['1', '2', '3']"""
+
+  # Copied here until it is merged into sequtils
+  template take(a: untyped, max: int): untyped =
+    type T = typeof(block: (for ai in a: ai))
+    var ret: seq[T]
+    var i = 0
+    if max > 0:
+      for ai in a:
+        ret.add ai
+        i.inc
+        if i >= max: break
+    ret
+
+  template testCommon(initList, toList) =
+
+    block: # toSinglyLinkedList, toDoublyLinkedList
+      let l = seq[int].default
+      doAssert l.toList.toSeq == []
+      doAssert [1].toList.toSeq == [1]
+      doAssert [1, 2, 3].toList.toSeq == [1, 2, 3]
+
+    block copy:
+      doAssert array[0, int].default.toList.copy.toSeq == []
+      doAssert [1].toList.copy.toSeq == [1]
+      doAssert [1, 2].toList.copy.toSeq == [1, 2]
+      doAssert [1, 2, 3].toList.copy.toSeq == [1, 2, 3]
+      type Foo = ref object
+        x: int
+      var f0 = Foo(x: 0)
+      let f1 = Foo(x: 1)
+      var a = [f0].toList
+      var b = a.copy
+      b.add f1
+      doAssert a.toSeq == [f0]
+      doAssert b.toSeq == [f0, f1]
+      f0.x = 42
+      doAssert a.head.value.x == 42
+      doAssert b.head.value.x == 42
+
+    block: # add, addMoved
+      block:
+        var
+          l0 = initList[int]()
+          l1 = [1].toList
+          l2 = [2, 3].toList
+          l3 = [4, 5, 6].toList
+        l0.add l3
+        l1.add l3
+        l2.addMoved l3
+        doAssert l0.toSeq == [4, 5, 6]
+        doAssert l1.toSeq == [1, 4, 5, 6]
+        doAssert l2.toSeq == [2, 3, 4, 5, 6]
+        doAssert l3.toSeq == []
+        l2.add l3 # re-adding l3 that was destroyed is now a no-op
+        doAssert l2.toSeq == [2, 3, 4, 5, 6]
+        doAssert l3.toSeq == []
+      block:
+        var
+          l0 = initList[int]()
+          l1 = [1].toList
+          l2 = [2, 3].toList
+          l3 = [4, 5, 6].toList
+        l3.addMoved l0
+        l2.addMoved l1
+        doAssert l3.toSeq == [4, 5, 6]
+        doAssert l2.toSeq == [2, 3, 1]
+        l3.add l0
+        doAssert l3.toSeq == [4, 5, 6]
+      block:
+        var c = [0, 1].toList
+        c.addMoved c
+        doAssert c.take(6) == [0, 1, 0, 1, 0, 1]
+
+    block: # prepend, prependMoved
+      block:
+        var
+          l0 = initList[int]()
+          l1 = [1].toList
+          l2 = [2, 3].toList
+          l3 = [4, 5, 6].toList
+        l0.prepend l3
+        l1.prepend l3
+        doAssert l3.toSeq == [4, 5, 6]
+        l2.prependMoved l3
+        doAssert l0.toSeq == [4, 5, 6]
+        doAssert l1.toSeq == [4, 5, 6, 1]
+        doAssert l2.toSeq == [4, 5, 6, 2, 3]
+        doAssert l3.toSeq == []
+        l2.prepend l3 # re-prepending l3 that was destroyed is now a no-op
+        doAssert l2.toSeq == [4, 5, 6, 2, 3]
+        doAssert l3.toSeq == []
+      block:
+        var
+          l0 = initList[int]()
+          l1 = [1].toList
+          l2 = [2, 3].toList
+          l3 = [4, 5, 6].toList
+        l3.prependMoved l0
+        l2.prependMoved l1
+        doAssert l3.toSeq == [4, 5, 6]
+        doAssert l2.toSeq == [1, 2, 3]
+        l3.prepend l0
+        doAssert l3.toSeq == [4, 5, 6]
+      block:
+        var c = [0, 1].toList
+        c.prependMoved c
+        doAssert c.take(6) == [0, 1, 0, 1, 0, 1]
+
+    block remove:
+      var l = [0, 1, 2, 3].toList
+      let
+        l0 = l.head
+        l1 = l0.next
+        l2 = l1.next
+        l3 = l2.next
+      l.remove l0
+      doAssert l.toSeq == [1, 2, 3]
+      l.remove l2
+      doAssert l.toSeq == [1, 3]
+      l.remove l2
+      doAssert l.toSeq == [1, 3]
+      l.remove l3
+      doAssert l.toSeq == [1]
+      l.remove l1
+      doAssert l.toSeq == []
+      # Cycle preservation
+      var a = [10, 11, 12].toList
+      a.addMoved a
+      doAssert a.take(6) == @[10, 11, 12, 10, 11, 12]
+      a.remove a.head.next
+      doAssert a.take(6) == @[10, 12, 10, 12, 10, 12]
+      a.remove a.head
+      doAssert a.take(6) == @[12, 12, 12, 12, 12, 12]
+
+  testCommon initSinglyLinkedList, toSinglyLinkedList
+  testCommon initDoublyLinkedList, toDoublyLinkedList
+
+  block remove: # return value check
+    var l = [0, 1, 2, 3].toSinglyLinkedList
+    let n = l.head.next.next
+    doAssert l.remove(n) == true
+    doAssert l.toSeq == [0, 1, 3]
+    doAssert l.remove(n) == false
+    doAssert l.toSeq == [0, 1, 3]
+    doAssert l.remove(l.head) == true
     doAssert l.toSeq == [1, 3]
-    l.remove l2
-    doAssert l.toSeq == [1, 3]
-    l.remove l3
+    doAssert l.remove(l.head.next) == true
     doAssert l.toSeq == [1]
-    l.remove l1
+    doAssert l.remove(l.head) == true
     doAssert l.toSeq == []
-    # Cycle preservation
-    var a = [10, 11, 12].toList
-    a.addMoved a
-    doAssert a.take(6) == @[10, 11, 12, 10, 11, 12]
-    a.remove a.head.next
-    doAssert a.take(6) == @[10, 12, 10, 12, 10, 12]
-    a.remove a.head
-    doAssert a.take(6) == @[12, 12, 12, 12, 12, 12]
-
-testCommon initSinglyLinkedList, toSinglyLinkedList
-testCommon initDoublyLinkedList, toDoublyLinkedList
-
-block remove: # return value check
-  var l = [0, 1, 2, 3].toSinglyLinkedList
-  let n = l.head.next.next
-  doAssert l.remove(n) == true
-  doAssert l.toSeq == [0, 1, 3]
-  doAssert l.remove(n) == false
-  doAssert l.toSeq == [0, 1, 3]
-  doAssert l.remove(l.head) == true
-  doAssert l.toSeq == [1, 3]
-  doAssert l.remove(l.head.next) == true
-  doAssert l.toSeq == [1]
-  doAssert l.remove(l.head) == true
-  doAssert l.toSeq == []
+
+static: main()
+main()