mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 17:34:43 +00:00
fixes #24121 Proc arguments can have typeclass type like `Foo | Bar` that `sigmatch` handles specially before matching them to the param type, because they wouldn't match otherwise. Not exactly sure why this existed but matching any typeclass or unresolved type in generic contexts now fails the match so typing the call is delayed until instantiation. Also it turns out default values with `tyFromExpr` type depending on other parameters was never tested, this also needs a patch to make the `tyFromExpr` type `tfNonConstExpr` so it doesn't try to evaluate the other parameter at compile time.
99 lines
3.2 KiB
Nim
99 lines
3.2 KiB
Nim
block: # issue #16700
|
|
type MyObject[T] = object
|
|
x: T
|
|
proc initMyObject[T](value = T.default): MyObject[T] =
|
|
MyObject[T](x: value)
|
|
var obj = initMyObject[int]()
|
|
|
|
block: # issue #20916
|
|
type
|
|
SomeX = object
|
|
v: int
|
|
var val = 0
|
|
proc f(_: type int, x: SomeX, v = x.v) =
|
|
doAssert v == 42
|
|
val = v
|
|
proc a(): proc() =
|
|
let v = SomeX(v: 42)
|
|
var tmp = proc() =
|
|
int.f(v)
|
|
tmp
|
|
a()()
|
|
doAssert val == 42
|
|
|
|
import std/typetraits
|
|
|
|
block: # issue #24099, original example
|
|
type
|
|
ColorRGBU = distinct array[3, uint8] ## RGB range 0..255
|
|
ColorRGBAU = distinct array[4, uint8] ## RGB range 0..255
|
|
ColorRGBUAny = ColorRGBU | ColorRGBAU
|
|
template componentType(t: typedesc[ColorRGBUAny]): typedesc =
|
|
## Returns component type of a given color type.
|
|
arrayType distinctBase t
|
|
func `~=`[T: ColorRGBUAny](a, b: T, e = componentType(T)(1.0e-11)): bool =
|
|
## Compares colors with given accuracy.
|
|
abs(a[0] - b[0]) < e and abs(a[1] - b[1]) < e and abs(a[2] - b[2]) < e
|
|
|
|
block: # issue #24099, modified to actually work
|
|
type
|
|
ColorRGBU = distinct array[3, uint8] ## RGB range 0..255
|
|
ColorRGBAU = distinct array[4, uint8] ## RGB range 0..255
|
|
ColorRGBUAny = ColorRGBU | ColorRGBAU
|
|
template arrayType[I, T](t: typedesc[array[I, T]]): typedesc =
|
|
T
|
|
template `[]`(a: ColorRGBUAny, i: untyped): untyped = distinctBase(a)[i]
|
|
proc abs(a: uint8): uint8 = a
|
|
template componentType(t: typedesc[ColorRGBUAny]): typedesc =
|
|
## Returns component type of a given color type.
|
|
arrayType distinctBase t
|
|
func `~=`[T: ColorRGBUAny](a, b: T, e = componentType(T)(1.0e-11)): bool =
|
|
## Compares colors with given accuracy.
|
|
abs(a[0] - b[0]) <= e and abs(a[1] - b[1]) <= e and abs(a[2] - b[2]) <= e
|
|
doAssert ColorRGBU([1.uint8, 1, 1]) ~= ColorRGBU([1.uint8, 1, 1])
|
|
|
|
block: # issue #24099, modified to work but using float32
|
|
type
|
|
ColorRGBU = distinct array[3, float32] ## RGB range 0..255
|
|
ColorRGBAU = distinct array[4, float32] ## RGB range 0..255
|
|
ColorRGBUAny = ColorRGBU | ColorRGBAU
|
|
template arrayType[I, T](t: typedesc[array[I, T]]): typedesc =
|
|
T
|
|
template `[]`(a: ColorRGBUAny, i: untyped): untyped = distinctBase(a)[i]
|
|
template componentType(t: typedesc[ColorRGBUAny]): typedesc =
|
|
## Returns component type of a given color type.
|
|
arrayType distinctBase t
|
|
func `~=`[T: ColorRGBUAny](a, b: T, e = componentType(T)(1.0e-11)): bool =
|
|
## Compares colors with given accuracy.
|
|
abs(a[0] - b[0]) < e and abs(a[1] - b[1]) < e and abs(a[2] - b[2]) < e
|
|
doAssert ColorRGBU([1.float32, 1, 1]) ~= ColorRGBU([1.float32, 1, 1])
|
|
|
|
block: # issue #13270
|
|
type
|
|
A = object
|
|
B = object
|
|
proc f(a: A) = discard
|
|
proc g[T](value: T, cb: (proc(a: T)) = f) =
|
|
cb value
|
|
g A()
|
|
# This should fail because there is no f(a: B) overload available
|
|
doAssert not compiles(g B())
|
|
|
|
block: # issue #24121
|
|
type
|
|
Foo = distinct int
|
|
Bar = distinct int
|
|
FooBar = Foo | Bar
|
|
|
|
proc foo[T: distinct](x: T): string = "a"
|
|
proc foo(x: Foo): string = "b"
|
|
proc foo(x: Bar): string = "c"
|
|
|
|
proc bar(x: FooBar, y = foo(x)): string = y
|
|
doAssert bar(Foo(123)) == "b"
|
|
doAssert bar(Bar(123)) == "c"
|
|
|
|
proc baz[T: FooBar](x: T, y = foo(x)): string = y
|
|
doAssert baz(Foo(123)) == "b"
|
|
doAssert baz(Bar(123)) == "c"
|