fix incorrect lenTuple implementation (#13423)
This commit is contained in:
parent
d1f9f11245
commit
273a93581f
3 changed files with 48 additions and 11 deletions
|
|
@ -187,6 +187,10 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
|
||||||
var operand = operand.skipTypes({tyGenericInst})
|
var operand = operand.skipTypes({tyGenericInst})
|
||||||
let cond = operand.kind == tyTuple and operand.n != nil
|
let cond = operand.kind == tyTuple and operand.n != nil
|
||||||
result = newIntNodeT(toInt128(ord(cond)), traitCall, c.graph)
|
result = newIntNodeT(toInt128(ord(cond)), traitCall, c.graph)
|
||||||
|
of "lenTuple":
|
||||||
|
var operand = operand.skipTypes({tyGenericInst})
|
||||||
|
assert operand.kind == tyTuple, $operand.kind
|
||||||
|
result = newIntNodeT(toInt128(operand.len), traitCall, c.graph)
|
||||||
of "distinctBase":
|
of "distinctBase":
|
||||||
var arg = operand.skipTypes({tyGenericInst})
|
var arg = operand.skipTypes({tyGenericInst})
|
||||||
if arg.kind == tyDistinct:
|
if arg.kind == tyDistinct:
|
||||||
|
|
|
||||||
|
|
@ -71,15 +71,14 @@ proc distinctBase*(T: typedesc): typedesc {.magic: "TypeTrait".}
|
||||||
## Returns base type for distinct types, works only for distinct types.
|
## Returns base type for distinct types, works only for distinct types.
|
||||||
## compile time error otherwise
|
## compile time error otherwise
|
||||||
|
|
||||||
import std/macros
|
|
||||||
|
|
||||||
macro lenTuple*(t: tuple): int {.since: (1, 1).} =
|
proc lenTuple*(T: typedesc[tuple]): int {.magic: "TypeTrait", since: (1, 1).}
|
||||||
## Return number of elements of `t`
|
|
||||||
newLit t.len
|
|
||||||
|
|
||||||
macro lenTuple*(t: typedesc[tuple]): int {.since: (1, 1).} =
|
|
||||||
## Return number of elements of `T`
|
## Return number of elements of `T`
|
||||||
newLit t.len
|
|
||||||
|
since (1, 1):
|
||||||
|
template lenTuple*(t: tuple): int =
|
||||||
|
## Return number of elements of `t`
|
||||||
|
lenTuple(type(t))
|
||||||
|
|
||||||
since (1, 1):
|
since (1, 1):
|
||||||
template get*(T: typedesc[tuple], i: static int): untyped =
|
template get*(T: typedesc[tuple], i: static int): untyped =
|
||||||
|
|
@ -87,6 +86,8 @@ since (1, 1):
|
||||||
# Note: `[]` currently gives: `Error: no generic parameters allowed for ...`
|
# Note: `[]` currently gives: `Error: no generic parameters allowed for ...`
|
||||||
type(default(T)[i])
|
type(default(T)[i])
|
||||||
|
|
||||||
|
import std/macros
|
||||||
|
|
||||||
macro genericParams*(T: typedesc): untyped {.since: (1, 1).} =
|
macro genericParams*(T: typedesc): untyped {.since: (1, 1).} =
|
||||||
## return tuple of generic params for generic `T`
|
## return tuple of generic params for generic `T`
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,43 @@ block distinctBase:
|
||||||
doAssert($distinctBase(typeof(b2)) == "string")
|
doAssert($distinctBase(typeof(b2)) == "string")
|
||||||
doAssert($distinctBase(typeof(c2)) == "int")
|
doAssert($distinctBase(typeof(c2)) == "int")
|
||||||
|
|
||||||
|
block: # lenTuple
|
||||||
|
doAssert not compiles(lenTuple(int))
|
||||||
|
|
||||||
|
type
|
||||||
|
MyTupleType = (int,float,string)
|
||||||
|
|
||||||
|
static: doAssert MyTupleType.lenTuple == 3
|
||||||
|
|
||||||
|
type
|
||||||
|
MyGenericTuple[T] = (T,int,float)
|
||||||
|
MyGenericAlias = MyGenericTuple[string]
|
||||||
|
static: doAssert MyGenericAlias.lenTuple == 3
|
||||||
|
|
||||||
|
type
|
||||||
|
MyGenericTuple2[T,U] = (T,U,string)
|
||||||
|
MyGenericTuple2Alias[T] = MyGenericTuple2[T,int]
|
||||||
|
|
||||||
|
MyGenericTuple2Alias2 = MyGenericTuple2Alias[float]
|
||||||
|
static: doAssert MyGenericTuple2Alias2.lenTuple == 3
|
||||||
|
|
||||||
|
static: doAssert (int, float).lenTuple == 2
|
||||||
|
static: doAssert (1, ).lenTuple == 1
|
||||||
|
static: doAssert ().lenTuple == 0
|
||||||
|
|
||||||
|
let x = (1,2,)
|
||||||
|
doAssert x.lenTuple == 2
|
||||||
|
doAssert ().lenTuple == 0
|
||||||
|
doAssert (1,).lenTuple == 1
|
||||||
|
doAssert (int,).lenTuple == 1
|
||||||
|
doAssert type(x).lenTuple == 2
|
||||||
|
doAssert type(x).default.lenTuple == 2
|
||||||
|
type T1 = (int,float)
|
||||||
|
type T2 = T1
|
||||||
|
doAssert T2.lenTuple == 2
|
||||||
|
|
||||||
block genericParams:
|
block genericParams:
|
||||||
|
|
||||||
type Foo[T1, T2]=object
|
type Foo[T1, T2]=object
|
||||||
doAssert genericParams(Foo[float, string]) is (float, string)
|
doAssert genericParams(Foo[float, string]) is (float, string)
|
||||||
type Foo1 = Foo[float, int]
|
type Foo1 = Foo[float, int]
|
||||||
|
|
@ -103,10 +139,6 @@ block genericParams:
|
||||||
doAssert genericParams(Foo2).get(1) is Foo1
|
doAssert genericParams(Foo2).get(1) is Foo1
|
||||||
doAssert (int,).get(0) is int
|
doAssert (int,).get(0) is int
|
||||||
doAssert (int, float).get(1) is float
|
doAssert (int, float).get(1) is float
|
||||||
static: doAssert (int, float).lenTuple == 2
|
|
||||||
static: doAssert (1, ).lenTuple == 1
|
|
||||||
static: doAssert ().lenTuple == 0
|
|
||||||
|
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
# bug 13095
|
# bug 13095
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue