mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-16 16:14:20 +00:00
fix incorrect lenTuple implementation (#13423)
This commit is contained in:
@@ -187,6 +187,10 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
|
||||
var operand = operand.skipTypes({tyGenericInst})
|
||||
let cond = operand.kind == tyTuple and operand.n != nil
|
||||
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":
|
||||
var arg = operand.skipTypes({tyGenericInst})
|
||||
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.
|
||||
## compile time error otherwise
|
||||
|
||||
import std/macros
|
||||
|
||||
macro lenTuple*(t: tuple): int {.since: (1, 1).} =
|
||||
## Return number of elements of `t`
|
||||
newLit t.len
|
||||
|
||||
macro lenTuple*(t: typedesc[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
|
||||
|
||||
since (1, 1):
|
||||
template lenTuple*(t: tuple): int =
|
||||
## Return number of elements of `t`
|
||||
lenTuple(type(t))
|
||||
|
||||
since (1, 1):
|
||||
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 ...`
|
||||
type(default(T)[i])
|
||||
|
||||
import std/macros
|
||||
|
||||
macro genericParams*(T: typedesc): untyped {.since: (1, 1).} =
|
||||
## return tuple of generic params for generic `T`
|
||||
runnableExamples:
|
||||
|
||||
@@ -92,7 +92,43 @@ block distinctBase:
|
||||
doAssert($distinctBase(typeof(b2)) == "string")
|
||||
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:
|
||||
|
||||
type Foo[T1, T2]=object
|
||||
doAssert genericParams(Foo[float, string]) is (float, string)
|
||||
type Foo1 = Foo[float, int]
|
||||
@@ -103,10 +139,6 @@ block genericParams:
|
||||
doAssert genericParams(Foo2).get(1) is Foo1
|
||||
doAssert (int,).get(0) is int
|
||||
doAssert (int, float).get(1) is float
|
||||
static: doAssert (int, float).lenTuple == 2
|
||||
static: doAssert (1, ).lenTuple == 1
|
||||
static: doAssert ().lenTuple == 0
|
||||
|
||||
|
||||
##############################################
|
||||
# bug 13095
|
||||
|
||||
Reference in New Issue
Block a user