ttypeselectors.nim 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. discard """
  2. output: "8\n8\n4"
  3. """
  4. import
  5. macros, typetraits
  6. template selectType(x: int): type =
  7. when x < 10:
  8. int
  9. else:
  10. string
  11. template simpleTypeTempl: type =
  12. string
  13. macro typeFromMacro: type = bindSym"string"
  14. # The tests below check that the result variable of the
  15. # selected type matches the literal types in the code:
  16. proc t1*(x: int): simpleTypeTempl() =
  17. result = "test"
  18. proc t2*(x: int): selectType(100) =
  19. result = "test"
  20. proc t3*(x: int): selectType(1) =
  21. result = 10
  22. proc t4*(x: int): typeFromMacro() =
  23. result = "test"
  24. var x*: selectType(50) = "test"
  25. proc t5*(x: selectType(5)) =
  26. var y = x + 10
  27. echo y
  28. var y*: type(t2(100)) = "test"
  29. proc t6*(x: type(t3(0))): type(t1(0)) =
  30. result = $x
  31. proc t7*(x: int): type($x) =
  32. result = "test"
  33. # This is a more complicated example involving a type
  34. # selection through a macro:
  35. # https://github.com/nim-lang/Nim/issues/7230
  36. macro getBase*(bits: static[int]): untyped =
  37. if bits >= 128:
  38. result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint64"))
  39. else:
  40. result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint32"))
  41. type
  42. BaseUint* = SomeUnsignedInt or MpUintBase
  43. MpUintBase*[T] = object
  44. lo*, hi*: T
  45. ## This gets type mismatch
  46. MpUint*[bits: static[int]] = getBase(bits)
  47. var m1: MpUint[128]
  48. var m2: MpUint[64]
  49. var m3: getBase(32)
  50. static:
  51. # assert m1.type.name == "MpUintBase[uint64]"
  52. assert m1.lo.type.name == "uint64"
  53. assert m2.lo.type.name == "uint32"
  54. assert m3.type.name == "MpUintBase[system.uint32]"
  55. # https://github.com/nim-lang/Nim/issues/7379
  56. import macros, typetraits
  57. macro works(): untyped =
  58. result = getType(int64)
  59. macro fails(bits: static[int]): untyped =
  60. if bits > 64:
  61. result = getType(int64)
  62. else:
  63. result = getType(int32)
  64. type
  65. Foo*[bits: static[int]] = works()
  66. Bar*[bits: static[int]] = fails(bits)
  67. var a: Foo[16]
  68. var b: Bar[256]
  69. var c: Bar[32]
  70. echo sizeof(a)
  71. echo sizeof(b)
  72. echo sizeof(c)
  73. # This is the same example but using a proc instead of a macro
  74. # Instead of type mismatch for macro, proc just failed with internal error: getTypeDescAux(tyNone)
  75. # https://github.com/nim-lang/Nim/issues/7231
  76. proc getBase2*(bits: static[int]): typedesc =
  77. if bits == 128:
  78. result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint64"))
  79. else:
  80. result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint32"))
  81. type
  82. MpUint2*[bits: static[int]] = getbase2(bits)