mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 09:24:36 +00:00
reverts #22642, reopens #22639, closes #22646, refs #22650, refs https://github.com/alaviss/union/issues/51, refs #22652 The fallout is too much from #22642, we can come back to it if we can account for all the affected code.
133 lines
3.0 KiB
Nim
133 lines
3.0 KiB
Nim
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
|