summary refs log tree commit diff stats
path: root/tests/distinct
diff options
context:
space:
mode:
Diffstat (limited to 'tests/distinct')
-rw-r--r--tests/distinct/t7165.nim15
-rw-r--r--tests/distinct/tborrow.nim132
-rw-r--r--tests/distinct/tcomplexaddressableconv.nim21
-rw-r--r--tests/distinct/tdistinct.nim119
-rw-r--r--tests/distinct/tdistinct_issues.nim14
-rw-r--r--tests/distinct/tinvalidborrow.nim42
-rw-r--r--tests/distinct/tnil.nim18
-rw-r--r--tests/distinct/typeclassborrow.nim56
8 files changed, 404 insertions, 13 deletions
diff --git a/tests/distinct/t7165.nim b/tests/distinct/t7165.nim
new file mode 100644
index 000000000..b16c29c0e
--- /dev/null
+++ b/tests/distinct/t7165.nim
@@ -0,0 +1,15 @@
+
+type
+  Table[K, V] = object
+    key: K
+    val: V
+
+  MyTable = distinct Table[string, int]
+  MyTableRef = ref MyTable
+
+proc newTable[K, V](): ref Table[K, V] = discard
+
+proc newMyTable: MyTableRef =
+  MyTableRef(newTable[string, int]()) # <--- error here
+
+discard newMyTable()
diff --git a/tests/distinct/tborrow.nim b/tests/distinct/tborrow.nim
new file mode 100644
index 000000000..e34248de5
--- /dev/null
+++ b/tests/distinct/tborrow.nim
@@ -0,0 +1,132 @@
+discard """
+  output: '''4887 true
+0.5'''
+"""
+
+# test the new borrow feature that works with generics:
+
+proc `++`*[T: int | float](a, b: T): T =
+  result = a + b
+
+type
+  DI = distinct int
+  DF = distinct float
+  DS = distinct string
+
+proc `++`(x, y: DI): DI {.borrow.}
+proc `++`(x, y: DF): DF {.borrow.}
+
+proc `$`(x: DI): string {.borrow.}
+proc `$`(x: DF): string {.borrow.}
+
+echo  4544.DI ++ 343.DI, " ", (4.5.DF ++ 0.5.DF).float == 5.0
+
+# issue #14440
+
+type Radians = distinct float64
+
+func `-=`(a: var Radians, b: Radians) {.borrow.}
+
+var a = Radians(1.5)
+let b = Radians(1.0)
+
+a -= b
+
+echo a.float64
+
+block: #14449
+  type 
+    Foo[T] = object
+      foo: T
+
+    Bar[T] {.borrow:`.`.} = distinct Foo[T]
+    SomeThing {.borrow:`.`.} = distinct Foo[float]
+    OtherThing {.borrow:`.`.} = distinct SomeThing
+
+  var
+    a: Bar[int]
+    b: SomeThing
+    c: OtherThing
+  a.foo = 300
+  b.foo = 400
+  c.foo = 42
+  assert a.foo == 300
+  assert b.foo == 400d
+  assert c.foo == 42d
+
+block: # Borrow from muliple aliasses #16666
+  type
+    AImpl = object
+      i: int
+    
+    A = AImpl
+  
+    B {.borrow: `.`.} = distinct A
+    C = B
+    D {.borrow: `.`.} = distinct C
+    E {.borrow: `.`.} = distinct D
+  
+  let
+    b = default(B)
+    d = default(D)
+    e = default(E)
+  
+  assert b.i == 0
+  assert d.i == 0
+  assert e.i == 0
+
+block: # Borrow from generic alias
+  type
+    AImpl[T] = object
+      i: T
+    B[T] = AImpl[T]
+    C {.borrow: `.`.} = distinct B[int]
+    D = B[float]
+    E {.borrow: `.`.} = distinct D
+
+  let
+    c = default(C)
+    e = default(E)
+  assert c.i == int(0)
+  assert e.i == 0d
+
+block: # issue #22069
+  type
+    Vehicle[C: static[int]] = object
+      color: array[C, int]
+    Car[C: static[int]] {.borrow: `.`.} = distinct Vehicle[C]
+    MuscleCar = Car[128]
+  var x: MuscleCar
+  doAssert x.color is array[128, int]
+
+block: # issue #22646
+  type
+    Vec[N : static[int], T: SomeNumber] = object
+      arr: array[N, T]
+    Vec3[T: SomeNumber] = Vec[3, T]
+
+  proc `[]=`[N,T](v: var Vec[N,T]; ix:int; c:T): void {.inline.} = v.arr[ix] = c
+  proc `[]`[N,T](v: Vec[N,T]; ix: int): T {.inline.} = v.arr[ix]
+
+  proc dot[N,T](u,v: Vec[N,T]): T {. inline .} = discard
+  proc length[N,T](v: Vec[N,T]): T = discard
+  proc cross[T](v1,v2:Vec[3,T]): Vec[3,T] = discard
+  proc normalizeWorks[T](v: Vec[3,T]): Vec[3,T] = discard ## <- Explicit size makes it work!
+  proc foo[N,T](u, v: Vec[N,T]): Vec[N,T] = discard ## <- broken
+  proc normalize[N,T](v: Vec[N,T]): Vec[N,T] = discard ## <- broken
+
+  type Color = distinct Vec3[float]
+
+  template borrowOps(typ: typedesc): untyped =
+    proc `[]=`(v: var typ; ix: int; c: float): void {.borrow.}
+    proc `[]`(v: typ; ix: int): float {.borrow.}
+    proc dot(v, u: typ): float {.borrow.}
+    proc cross(v, u: typ): typ {.borrow.}
+    proc length(v: typ): float {.borrow.}
+    proc normalizeWorks(v: typ): typ {.borrow.} ## Up to here everything works
+    proc foo(u, v: typ): typ {.borrow.} ## Broken
+    proc normalize(v: typ): typ {.borrow.} ## Broken
+  borrowOps(Color)
+  var x: Vec[3, float]
+  let y = Color(x)
+  doAssert Vec3[float](y) == x
diff --git a/tests/distinct/tcomplexaddressableconv.nim b/tests/distinct/tcomplexaddressableconv.nim
new file mode 100644
index 000000000..00e96bfeb
--- /dev/null
+++ b/tests/distinct/tcomplexaddressableconv.nim
@@ -0,0 +1,21 @@
+# issue #22523
+
+from std/typetraits import distinctBase
+
+type
+  V[p: static int] = distinct int
+  D[p: static int] = distinct int
+  T = V[1]
+
+proc f(y: var T) = discard
+
+var a: D[0]
+
+static:
+  doAssert distinctBase(T) is distinctBase(D[0])
+  doAssert distinctBase(T) is int
+  doAssert distinctBase(D[0]) is int
+  doAssert T(a) is T
+
+f(cast[ptr T](addr a)[])
+f(T(a))
diff --git a/tests/distinct/tdistinct.nim b/tests/distinct/tdistinct.nim
index 2c0196745..b6ba7aa99 100644
--- a/tests/distinct/tdistinct.nim
+++ b/tests/distinct/tdistinct.nim
@@ -1,4 +1,5 @@
 discard """
+  targets: "c js"
   output: '''
 tdistinct
 25
@@ -7,6 +8,7 @@ false
 false
 false
 Foo
+foo
 '''
 """
 
@@ -106,3 +108,120 @@ type FooD = distinct int
 proc `<=`(a, b: FooD): bool {.borrow.}
 
 for f in [FooD(0): "Foo"]: echo f
+
+block tRequiresInit:
+  template accept(x) =
+    static: doAssert compiles(x)
+
+  template reject(x) =
+    static: doAssert not compiles(x)
+
+  type
+    Foo = object
+      x: string
+
+    DistinctFoo {.requiresInit, borrow: `.`.} = distinct Foo
+    DistinctString {.requiresInit.} = distinct string
+
+  reject:
+    var foo: DistinctFoo
+    foo.x = "test"
+    doAssert foo.x == "test"
+
+  accept:
+    let foo = DistinctFoo(Foo(x: "test"))
+    doAssert foo.x == "test"
+
+  reject:
+    var s: DistinctString
+    s = "test"
+    doAssert string(s) == "test"
+
+  accept:
+    let s = DistinctString("test")
+    doAssert string(s) == "test"
+
+block: #17322
+  type
+    A[T] = distinct string
+
+  proc foo(a: var A) =
+    a.string.add "foo"
+
+  type
+    B = distinct A[int]
+
+  var b: B
+  foo(A[int](b))
+  echo A[int](b).string
+  b.string.add "bar"
+  assert b.string == "foobar"
+
+type Foo = distinct string
+
+proc main() = # proc instead of template because of MCS/UFCS.
+  # xxx put everything here to test under RT + VM
+  block: # bug #12282
+    block:
+      proc test() =
+        var s: Foo
+        s.string.add('c')
+        doAssert s.string == "c" # was failing
+      test()
+
+    block:
+      proc add(a: var Foo, b: char) {.borrow.}
+      proc test() =
+        var s: Foo
+        s.add('c')
+        doAssert s.string == "c" # was ok
+      test()
+
+    block:
+      proc add(a: var Foo, b: char) {.borrow.}
+      proc test() =
+        var s: string
+        s.Foo.add('c')
+        doAssert s.string == "c" # was failing
+      test()
+    block: #18061
+      type
+        A = distinct (0..100)
+        B = A(0) .. A(10)
+      proc test(b: B) = discard
+      let
+        a = A(10)
+        b = B(a)
+      test(b)
+
+      proc test(a: A) = discard
+      discard cast[B](A(1))
+      var c: B
+
+
+  block: # bug #9423
+    block:
+      type Foo = seq[int]
+      type Foo2 = distinct Foo
+      template fn() =
+        var a = Foo2(@[1])
+        a.Foo.add 2
+        doAssert a.Foo == @[1, 2]
+      fn()
+
+    block:
+      type Stack[T] = distinct seq[T]
+      proc newStack[T](): Stack[T] =
+        Stack[T](newSeq[T]())
+      proc push[T](stack: var Stack[T], elem: T) =
+        seq[T](stack).add(elem)
+      proc len[T](stack: Stack[T]): int =
+        seq[T](stack).len
+      proc fn() = 
+        var stack = newStack[int]()
+        stack.push(5)
+        doAssert stack.len == 1
+      fn()
+
+static: main()
+main()
diff --git a/tests/distinct/tdistinct_issues.nim b/tests/distinct/tdistinct_issues.nim
index ce71344d0..747cf0b8d 100644
--- a/tests/distinct/tdistinct_issues.nim
+++ b/tests/distinct/tdistinct_issues.nim
@@ -65,3 +65,17 @@ block t9322:
   proc mystr(s: string) =
     echo s
   mystr($Fix("apr"))
+
+
+block: # bug #13517
+  type MyUint64 = distinct uint64
+
+  proc `==`(a: MyUint64, b: uint64): bool = uint64(a) == b
+
+  block:
+    doAssert MyUint64.high is MyUint64
+    doAssert MyUint64.high == 18446744073709551615'u64
+
+  static:
+    doAssert MyUint64.high is MyUint64
+    doAssert MyUint64.high == 18446744073709551615'u64
diff --git a/tests/distinct/tinvalidborrow.nim b/tests/distinct/tinvalidborrow.nim
new file mode 100644
index 000000000..d4b19fa8d
--- /dev/null
+++ b/tests/distinct/tinvalidborrow.nim
@@ -0,0 +1,42 @@
+discard """
+  cmd: "nim check --hints:off --warnings:off $file"
+  action: "reject"
+  nimout:'''
+tinvalidborrow.nim(25, 3) Error: only a 'distinct' type can borrow `.`
+tinvalidborrow.nim(26, 3) Error: only a 'distinct' type can borrow `.`
+tinvalidborrow.nim(27, 1) Error: borrow proc without distinct type parameter is meaningless
+tinvalidborrow.nim(36, 1) Error: borrow with generic parameter is not supported
+tinvalidborrow.nim(41, 1) Error: borrow from proc return type mismatch: 'T'
+tinvalidborrow.nim(42, 1) Error: borrow from '[]=' is not supported
+'''
+"""
+
+
+
+
+
+# bug #516
+
+type
+  TAtom = culong
+  Test {.borrow:`.`.} = distinct int
+  Foo[T] = object
+    a: int
+  Bar[T] {.borrow:`.`.} = Foo[T]
+  OtherFoo {.borrow:`.`.} = Foo[int]
+proc `==`*(a, b: TAtom): bool {.borrow.}
+
+var
+  d, e: TAtom
+
+discard( $(d == e) )
+
+# issue #4121
+type HeapQueue[T] = distinct seq[T]
+proc len*[T](h: HeapQueue[T]): int {.borrow.}
+
+# issue #3564
+type vec4[T] = distinct array[4, float32]
+
+proc `[]`(v: vec4, i: int): float32 {.borrow.}
+proc `[]=`(v: vec4, i: int, va: float32) {.borrow.}
diff --git a/tests/distinct/tnil.nim b/tests/distinct/tnil.nim
index 5bdb97f37..b54c07432 100644
--- a/tests/distinct/tnil.nim
+++ b/tests/distinct/tnil.nim
@@ -1,29 +1,21 @@
-discard """
-output: '''
-1
-0
-0
-'''
-"""
 {.experimental: "notnil".}
 type
   MyPointer = distinct pointer
   MyString = distinct string
   MyInt = distinct int
 
-proc foo(a: MyPointer) =
+proc foo(a: MyPointer): int =
   # workaround a Windows 'repr' difference:
-  echo cast[int](a)
+  cast[int](a)
 
-foo(cast[MyPointer](1))
-foo(cast[MyPointer](nil))
-foo(nil)
+doAssert foo(cast[MyPointer](1)) == 1
+doAssert foo(cast[MyPointer](nil)) == 0
+doAssert foo(MyPointer(nil)) == 0
 
 var p: MyPointer
 p = cast[MyPointer](1)
 p = cast[MyPointer](nil)
 p = nil.MyPointer
-p = nil
 
 var i: MyInt
 i = 1.MyInt
diff --git a/tests/distinct/typeclassborrow.nim b/tests/distinct/typeclassborrow.nim
new file mode 100644
index 000000000..5e0c63953
--- /dev/null
+++ b/tests/distinct/typeclassborrow.nim
@@ -0,0 +1,56 @@
+import std/tables
+
+type
+  Foo = distinct seq[int]
+  Bar[N: static[int]] = distinct seq[int]
+  Baz = distinct Bar[10]
+
+proc newSeq(s: var Foo, n: Natural) {.borrow.}
+proc newSeq(s: var Bar, n: Natural) {.borrow.}
+proc newSeq(s: var Baz, n: Natural) {.borrow.}
+
+
+proc `$`(s: Foo): string {.borrow.}
+proc `$`(s: Bar): string {.borrow.}
+proc `$`(s: Baz): string {.borrow.}
+
+proc doThing(b: Bar) = discard
+proc doThing(b: Baz) {.borrow.}
+
+var
+  foo: Foo
+  bar: Bar[10]
+  baz: Baz
+
+newSeq(foo, 100)
+newSeq(bar, bar.N)
+newSeq(baz, 10)
+
+bar.doThing()
+baz.doThing()
+
+assert $seq[int](foo) == $foo
+assert $seq[int](bar) == $bar
+assert $seq[int](baz) == $baz
+
+type
+  Fine* = distinct string
+
+proc `==`*(x, y: Fine): bool {.borrow.} =
+  ## Here is the documentation
+  runnableExamples:
+    var x = Fine("1234")
+    var y = Fine("1234")
+    doAssert x == y
+  doAssert false
+
+
+var x = Fine("1234")
+var y = Fine("1234")
+doAssert x == y
+
+block: # bug #22902
+  type
+    DistinctTable = distinct Table[int, int]
+
+  proc `[]`(t: DistinctTable; key: int): lent int {.borrow.}