* late instantiation for the generic procs' default param values * automatic mixin behaviour in concepts Other fixes: * don't render the automatically inserted default params in calls * better rendering of tyFromExpr
This commit is contained in:
parent
ea36e0ebbe
commit
5bcf8bcb59
15 changed files with 321 additions and 65 deletions
124
tests/generics/tlateboundgenericparams.nim
Normal file
124
tests/generics/tlateboundgenericparams.nim
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
import typetraits
|
||||
|
||||
type
|
||||
Foo = object
|
||||
|
||||
proc defaultFoo: Foo = discard
|
||||
proc defaultInt: int = 1
|
||||
proc defaultTInt(T: type): int = 2
|
||||
proc defaultTFoo[T](x: typedesc[T]): Foo = discard
|
||||
proc defaultTOldSchool[T](x: typedesc[T]): T = discard
|
||||
proc defaultTModern(T: type): T = discard
|
||||
|
||||
proc specializedDefault(T: type int): int = 10
|
||||
proc specializedDefault(T: type string): string = "default"
|
||||
|
||||
converter intFromFoo(x: Foo): int = 3
|
||||
|
||||
proc consumeInt(x: int) =
|
||||
discard
|
||||
|
||||
const activeTests = {1..100}
|
||||
|
||||
when true:
|
||||
template test(n, body) =
|
||||
when n in activeTests:
|
||||
block:
|
||||
body
|
||||
|
||||
template reject(x) =
|
||||
static: assert(not compiles(x))
|
||||
|
||||
test 1:
|
||||
proc t[T](val: T = defaultInt()) =
|
||||
consumeInt val
|
||||
|
||||
t[int]()
|
||||
reject t[string]()
|
||||
|
||||
test 2:
|
||||
proc t1[T](val: T = defaultFoo()) =
|
||||
static:
|
||||
assert type(val).name == "int"
|
||||
assert T.name == "int"
|
||||
|
||||
consumeInt val
|
||||
|
||||
# here, the converter should kick in, but notice
|
||||
# how `val` is still typed `int` inside the proc.
|
||||
t1[int]()
|
||||
|
||||
proc t2[T](val: T = defaultFoo()) =
|
||||
discard
|
||||
|
||||
reject t2[string]()
|
||||
|
||||
test 3:
|
||||
proc tInt[T](val = defaultInt()): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert tInt[int]() == "int"
|
||||
doAssert tInt[string]() == "int"
|
||||
|
||||
proc tInt2[T](val = defaultTInt(T)): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert tInt2[int]() == "int"
|
||||
doAssert tInt2[string]() == "int"
|
||||
|
||||
proc tDefTModern[T](val = defaultTModern(T)): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert tDefTModern[int]() == "int"
|
||||
doAssert tDefTModern[string]() == "string"
|
||||
doAssert tDefTModern[Foo]() == "Foo"
|
||||
|
||||
proc tDefTOld[T](val = defaultTOldSchool(T)): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert tDefTOld[int]() == "int"
|
||||
doAssert tDefTOld[string]() == "string"
|
||||
doAssert tDefTOld[Foo]() == "Foo"
|
||||
|
||||
test 4:
|
||||
proc t[T](val: T = defaultTFoo(T)): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert t[int]() == "int"
|
||||
doAssert t[Foo]() == "Foo"
|
||||
reject t[string]()
|
||||
|
||||
test 5:
|
||||
proc t1[T](a: T = specializedDefault(T)): T =
|
||||
return a
|
||||
|
||||
doAssert t1[int]() == 10
|
||||
doAssert t1[string]() == "default"
|
||||
|
||||
proc t2[T](a: T, b = specializedDefault(T)): auto =
|
||||
return $a & $b
|
||||
|
||||
doAssert t2(5) == "510"
|
||||
doAssert t2("string ") == "string default"
|
||||
|
||||
proc t3[T](a: T, b = specializedDefault(type(a))): auto =
|
||||
return $a & $b
|
||||
|
||||
doAssert t3(100) == "10010"
|
||||
doAssert t3("another ") == "another default"
|
||||
|
||||
test 6:
|
||||
# https://github.com/nim-lang/Nim/issues/5595
|
||||
type
|
||||
Point[T] = object
|
||||
x, y: T
|
||||
|
||||
proc getOrigin[T](): Point[T] = Point[T](x: 0, y: 0)
|
||||
|
||||
proc rotate[T](point: Point[T], radians: float,
|
||||
origin = getOrigin[T]()): Point[T] =
|
||||
discard
|
||||
|
||||
var p = getOrigin[float]()
|
||||
var rotated = p.rotate(2.1)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue