Static[T] fixes (#7333)
* fix the usage of unresolved static[T] parameters in proc signatures * fix tsametype and tmacrogenerics * Allow creating composite type classes with concepts and using them in type signatures * Allow integers to be used in ident concatenations * Support using imported C++ generic types in proc signatures * fixes #7230 * closes #7379 * re-enable some metatype tests
This commit is contained in:
parent
2e7a0e1cdd
commit
121b9e26fb
18 changed files with 265 additions and 26 deletions
19
tests/concepts/tseqofconcept.nim
Normal file
19
tests/concepts/tseqofconcept.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
discard """
|
||||
output: "1\n2\n3"
|
||||
"""
|
||||
|
||||
type
|
||||
MyConcept = concept x
|
||||
someProc(x)
|
||||
|
||||
SomeSeq = seq[MyConcept]
|
||||
|
||||
proc someProc(x:int) = echo x
|
||||
|
||||
proc work (s: SomeSeq) =
|
||||
for item in s:
|
||||
someProc item
|
||||
|
||||
var s = @[1, 2, 3]
|
||||
work s
|
||||
|
||||
|
|
@ -300,7 +300,7 @@ reject wantsVarPointer2(pcat)
|
|||
|
||||
# covariance may be allowed for certain extern types
|
||||
|
||||
{.emit: """
|
||||
{.emit: """/*TYPESECTION*/
|
||||
template <class T> struct FN { typedef void (*type)(T); };
|
||||
template <class T> struct ARR { typedef T DataType[2]; DataType data; };
|
||||
""".}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ discard """
|
|||
targets: "cpp"
|
||||
"""
|
||||
|
||||
{.emit: """
|
||||
{.emit: """/*TYPESECTION*/
|
||||
|
||||
template <class T>
|
||||
struct Vector {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ AST b
|
|||
20Test
|
||||
20
|
||||
'''
|
||||
disabled: true
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
|
@ -26,7 +25,7 @@ type
|
|||
|
||||
const data: Tconfig = (@["aa", "bb"], @[11, 22])
|
||||
|
||||
macro mymacro(data: static[TConfig]) =
|
||||
macro mymacro(data: static[TConfig]): untyped =
|
||||
echo "letters"
|
||||
for s in items(data.letters):
|
||||
echo s
|
||||
|
|
@ -44,10 +43,10 @@ const
|
|||
a : Ta = @[(11, 22), (33, 44)]
|
||||
b : Tb = (@[55,66], @[77, 88])
|
||||
|
||||
macro mA(data: static[Ta]) =
|
||||
macro mA(data: static[Ta]): untyped =
|
||||
echo "AST a \n", repr(data)
|
||||
|
||||
macro mB(data: static[Tb]) =
|
||||
macro mB(data: static[Tb]): untyped =
|
||||
echo "AST b \n", repr(data)
|
||||
echo data.e[0]
|
||||
|
||||
|
|
@ -57,13 +56,15 @@ mB(b)
|
|||
type
|
||||
Foo[N: static[int], Z: static[string]] = object
|
||||
|
||||
macro staticIntMacro(f: static[int]) = echo f
|
||||
macro staticIntMacro(f: static[int]): untyped =
|
||||
echo f
|
||||
|
||||
staticIntMacro 10
|
||||
|
||||
var
|
||||
x: Foo[20, "Test"]
|
||||
|
||||
macro genericMacro[N; Z: static[string]](f: Foo[N, Z], ll = 3, zz = 12) =
|
||||
macro genericMacro[N; Z: static[string]](f: Foo[N, Z], ll = 3, zz = 12): untyped =
|
||||
echo N, Z
|
||||
|
||||
genericMacro x
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
import macros
|
||||
discard """
|
||||
output: "8\n8\n4"
|
||||
"""
|
||||
|
||||
import
|
||||
macros, typetraits
|
||||
|
||||
template selectType(x: int): typeDesc =
|
||||
when x < 10:
|
||||
|
|
@ -11,6 +16,9 @@ template simpleTypeTempl: typeDesc =
|
|||
|
||||
macro typeFromMacro: typedesc = string
|
||||
|
||||
# The tests below check that the result variable of the
|
||||
# selected type matches the literal types in the code:
|
||||
|
||||
proc t1*(x: int): simpleTypeTempl() =
|
||||
result = "test"
|
||||
|
||||
|
|
@ -37,3 +45,57 @@ proc t6*(x: type(t3(0))): type(t1(0)) =
|
|||
proc t7*(x: int): type($x) =
|
||||
result = "test"
|
||||
|
||||
# This is a more compicated example involving a type
|
||||
# selection through a macro:
|
||||
# https://github.com/nim-lang/Nim/issues/7230
|
||||
|
||||
macro getBase*(bits: static[int]): untyped =
|
||||
if bits >= 128:
|
||||
result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint64"))
|
||||
else:
|
||||
result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint32"))
|
||||
|
||||
type
|
||||
BaseUint* = SomeUnsignedInt or MpUintBase
|
||||
|
||||
MpUintBase*[T] = object
|
||||
lo*, hi*: T
|
||||
|
||||
## This gets type mismatch
|
||||
MpUint*[bits: static[int]] = getBase(bits)
|
||||
|
||||
var m1: MpUint[128]
|
||||
var m2: MpUint[64]
|
||||
var m3: getBase(32)
|
||||
|
||||
static:
|
||||
# assert m1.type.name == "MpUintBase[uint64]"
|
||||
assert m1.lo.type.name == "uint64"
|
||||
assert m2.lo.type.name == "uint32"
|
||||
assert m3.type.name == "MpUintBase[system.uint32]"
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/7379
|
||||
|
||||
import macros, typetraits
|
||||
|
||||
macro works(): untyped =
|
||||
result = getType(int64)
|
||||
|
||||
macro fails(bits: static[int]): untyped =
|
||||
if bits > 64:
|
||||
result = getType(int64)
|
||||
else:
|
||||
result = getType(int32)
|
||||
|
||||
type
|
||||
Foo*[bits: static[int]] = works()
|
||||
Bar*[bits: static[int]] = fails(bits)
|
||||
|
||||
var a: Foo[16]
|
||||
var b: Bar[256]
|
||||
var c: Bar[32]
|
||||
|
||||
echo sizeof(a)
|
||||
echo sizeof(b)
|
||||
echo sizeof(c)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
discard """
|
||||
errormsg: "type mismatch: got <string> but expected 'ptr'"
|
||||
line: 20
|
||||
disabled: true
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
|
@ -12,7 +11,7 @@ type
|
|||
var x = Vec([1, 2, 3])
|
||||
|
||||
static:
|
||||
assert x.type.name == "Vec[static[int](3), int]"
|
||||
assert x.type.name == "Vec[3, system.int]"
|
||||
|
||||
var str1: string = "hello, world!"
|
||||
var ptr1: ptr = addr(str1)
|
||||
|
|
|
|||
32
tests/misc/tidentconcatenations.nim
Normal file
32
tests/misc/tidentconcatenations.nim
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
type
|
||||
Hash*[bits: static[int]] = object
|
||||
data*: array[bits div 8, uint8]
|
||||
|
||||
{.emit: """
|
||||
|
||||
void sha_256(void* input, int input_len, void* output, int output_len) {}
|
||||
void sha_512(void* input, int input_len, void* output, int output_len) {}
|
||||
|
||||
void keccak_256(void* input, int input_len, void* output, int output_len) {}
|
||||
void keccak_512(void* input, int input_len, void* output, int output_len) {}
|
||||
|
||||
""".}
|
||||
|
||||
template defineKeccak(bits: untyped) =
|
||||
proc `extKeccak bits`(output: pointer, outSize: csize, input: pointer, inputSize: csize) {.nodecl, importc: "keccak_" & astToStr(bits).}
|
||||
|
||||
template defineSha(bits: static[int]) =
|
||||
proc `extSha bits`(output: pointer, outSize: csize, input: pointer, inputSize: csize) {.nodecl, importc: "sha_" & astToStr(bits).}
|
||||
|
||||
template defineHashProcs(bits) =
|
||||
defineSha(bits)
|
||||
defineKeccak(bits)
|
||||
|
||||
defineHashProcs(256)
|
||||
defineHashProcs(512)
|
||||
|
||||
extSha256(nil, 0, nil, 0)
|
||||
extSha512(nil, 0, nil, 0)
|
||||
extKeccak256(nil, 0, nil, 0)
|
||||
extKeccak512(nil, 0, nil, 0)
|
||||
|
||||
44
tests/statictypes/tcryptodigest.nim
Normal file
44
tests/statictypes/tcryptodigest.nim
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
discard """
|
||||
output: "Digest[128]\nDigest[256]"
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
type
|
||||
Digest[bits: static[int]] = object
|
||||
data: array[bits div 8, byte]
|
||||
|
||||
ContextKind = enum
|
||||
A, B, C
|
||||
|
||||
HashingContext[bits: static[int], kind: static[ContextKind]] = object
|
||||
ctx: array[bits div 8, byte]
|
||||
|
||||
Hash128 = HashingContext[128, A]
|
||||
Hash256 = HashingContext[256, B]
|
||||
|
||||
HMAC[HashType] = object
|
||||
h: HashType
|
||||
|
||||
proc init(c: var HashingContext) = discard
|
||||
proc update(c: var HashingContext, data: ptr byte, dataLen: uint) = discard
|
||||
proc finish(c: var HashingContext): Digest[c.bits] = discard
|
||||
|
||||
proc digest(T: typedesc, data: ptr byte, dataLen: uint): Digest[T.bits] =
|
||||
mixin init, update, finish
|
||||
|
||||
var ctx: T
|
||||
ctx.init()
|
||||
ctx.update(data, dataLen)
|
||||
result = ctx.finish()
|
||||
|
||||
var h = Hash128.digest(nil, 0)
|
||||
echo h.type.name
|
||||
|
||||
proc finish(hmac: var HMAC): Digest[HMAC.HashType.bits] =
|
||||
discard
|
||||
|
||||
var hm: HMAC[Hash256]
|
||||
var d = hm.finish
|
||||
echo d.type.name
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
discard """
|
||||
targets: "cpp"
|
||||
output: "[0, 0, 10, 0]\n5\n1.2\n15\ntest"
|
||||
output: "[0, 0, 10, 0]\n5\n1.2\n15\ntest\n[0, 0, 20, 0]"
|
||||
"""
|
||||
|
||||
{.emit: """
|
||||
{.emit: """/*TYPESECTION*/
|
||||
|
||||
template <int N, class T>
|
||||
struct GenericIntType {
|
||||
|
|
@ -51,3 +51,9 @@ echo c.field
|
|||
echo d.field
|
||||
echo e.field
|
||||
|
||||
proc plus(a, b: GenInt4): GenInt4 =
|
||||
for i in 0 ..< result.data.len:
|
||||
result.data[i] = a.data[i] + b.data[i]
|
||||
|
||||
echo plus(a, a).data
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue