tborrow.nim 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. discard """
  2. output: '''4887 true
  3. 0.5'''
  4. """
  5. # test the new borrow feature that works with generics:
  6. proc `++`*[T: int | float](a, b: T): T =
  7. result = a + b
  8. type
  9. DI = distinct int
  10. DF = distinct float
  11. DS = distinct string
  12. proc `++`(x, y: DI): DI {.borrow.}
  13. proc `++`(x, y: DF): DF {.borrow.}
  14. proc `$`(x: DI): string {.borrow.}
  15. proc `$`(x: DF): string {.borrow.}
  16. echo 4544.DI ++ 343.DI, " ", (4.5.DF ++ 0.5.DF).float == 5.0
  17. # issue #14440
  18. type Radians = distinct float64
  19. func `-=`(a: var Radians, b: Radians) {.borrow.}
  20. var a = Radians(1.5)
  21. let b = Radians(1.0)
  22. a -= b
  23. echo a.float64
  24. block: #14449
  25. type
  26. Foo[T] = object
  27. foo: T
  28. Bar[T] {.borrow:`.`.} = distinct Foo[T]
  29. SomeThing {.borrow:`.`.} = distinct Foo[float]
  30. OtherThing {.borrow:`.`.} = distinct SomeThing
  31. var
  32. a: Bar[int]
  33. b: SomeThing
  34. c: OtherThing
  35. a.foo = 300
  36. b.foo = 400
  37. c.foo = 42
  38. assert a.foo == 300
  39. assert b.foo == 400d
  40. assert c.foo == 42d
  41. block: # Borrow from muliple aliasses #16666
  42. type
  43. AImpl = object
  44. i: int
  45. A = AImpl
  46. B {.borrow: `.`.} = distinct A
  47. C = B
  48. D {.borrow: `.`.} = distinct C
  49. E {.borrow: `.`.} = distinct D
  50. let
  51. b = default(B)
  52. d = default(D)
  53. e = default(E)
  54. assert b.i == 0
  55. assert d.i == 0
  56. assert e.i == 0
  57. block: # Borrow from generic alias
  58. type
  59. AImpl[T] = object
  60. i: T
  61. B[T] = AImpl[T]
  62. C {.borrow: `.`.} = distinct B[int]
  63. D = B[float]
  64. E {.borrow: `.`.} = distinct D
  65. let
  66. c = default(C)
  67. e = default(E)
  68. assert c.i == int(0)
  69. assert e.i == 0d
  70. block: # issue #22069
  71. type
  72. Vehicle[C: static[int]] = object
  73. color: array[C, int]
  74. Car[C: static[int]] {.borrow: `.`.} = distinct Vehicle[C]
  75. MuscleCar = Car[128]
  76. var x: MuscleCar
  77. doAssert x.color is array[128, int]
  78. block: # issue #22646
  79. type
  80. Vec[N : static[int], T: SomeNumber] = object
  81. arr: array[N, T]
  82. Vec3[T: SomeNumber] = Vec[3, T]
  83. proc `[]=`[N,T](v: var Vec[N,T]; ix:int; c:T): void {.inline.} = v.arr[ix] = c
  84. proc `[]`[N,T](v: Vec[N,T]; ix: int): T {.inline.} = v.arr[ix]
  85. proc dot[N,T](u,v: Vec[N,T]): T {. inline .} = discard
  86. proc length[N,T](v: Vec[N,T]): T = discard
  87. proc cross[T](v1,v2:Vec[3,T]): Vec[3,T] = discard
  88. proc normalizeWorks[T](v: Vec[3,T]): Vec[3,T] = discard ## <- Explicit size makes it work!
  89. proc foo[N,T](u, v: Vec[N,T]): Vec[N,T] = discard ## <- broken
  90. proc normalize[N,T](v: Vec[N,T]): Vec[N,T] = discard ## <- broken
  91. type Color = distinct Vec3[float]
  92. template borrowOps(typ: typedesc): untyped =
  93. proc `[]=`(v: var typ; ix: int; c: float): void {.borrow.}
  94. proc `[]`(v: typ; ix: int): float {.borrow.}
  95. proc dot(v, u: typ): float {.borrow.}
  96. proc cross(v, u: typ): typ {.borrow.}
  97. proc length(v: typ): float {.borrow.}
  98. proc normalizeWorks(v: typ): typ {.borrow.} ## Up to here everything works
  99. proc foo(u, v: typ): typ {.borrow.} ## Broken
  100. proc normalize(v: typ): typ {.borrow.} ## Broken
  101. borrowOps(Color)
  102. var x: Vec[3, float]
  103. let y = Color(x)
  104. doAssert Vec3[float](y) == x