1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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
|