Skip to content

Commit

Permalink
test case haul for old generic/template/macro issues
Browse files Browse the repository at this point in the history
closes nim-lang#12582, closes nim-lang#19552, closes nim-lang#2465, closes nim-lang#4596, closes nim-lang#15246,
closes nim-lang#12683, closes nim-lang#7889, closes nim-lang#4547, closes nim-lang#12415, closes nim-lang#2002,
closes nim-lang#1771, closes nim-lang#5121

The test for nim-lang#5648 is also moved into its own test
from `types/tissues_types` due to not being joinable.
  • Loading branch information
metagn committed Aug 27, 2023
1 parent a108a45 commit d001b70
Show file tree
Hide file tree
Showing 9 changed files with 248 additions and 34 deletions.
11 changes: 11 additions & 0 deletions tests/generics/treentranttypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,14 @@ echo @(b.arr[0].arr), @(b.arr[1].arr)
let y = b
echo @(y.arr[0].arr), @(y.arr[1].arr)

import macros

block: # issue #5121
type
A = object
AConst[X] = A

macro dumpType(t: typedesc): untyped =
result = newTree(nnkTupleConstr, newLit $t.getType[1].typeKind, newLit t.getType[1].treeRepr)

doAssert dumpType(A) == ("ntyObject", "Sym \"A\"")
62 changes: 62 additions & 0 deletions tests/generics/tuninstantiatedgenericcalls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,65 @@ block:
doAssert x.data.len == 5
var y: Leb128Buf[uint16]
doAssert y.data.len == 3

import macros

block: # issue #12415
macro isSomePointerImpl(t: typedesc): bool =
var impl = t.getTypeInst[1].getTypeImpl
if impl.kind == nnkDistinctTy:
impl = impl[0].getTypeImpl
if impl.kind in {nnkPtrTy,nnkRefTy}:
result = newLit(true)
elif impl.kind == nnkSym and impl.eqIdent("pointer"):
result = newLit(true)
else:
result = newLit(false)

proc isSomePointer[T](t: typedesc[T]): bool {.compileTime.} =
isSomePointerImpl(t)

type
Option[T] = object
## An optional type that stores its value and state separately in a boolean.
when isSomePointer(typedesc(T)):
val: T
else:
val: T
has: bool
var x: Option[ref int]
doAssert not compiles(x.has)
var y: Option[int]
doAssert compiles(y.has)

block: # issue #2002
proc isNillable(T: typedesc): bool =
when compiles((let v: T = nil)):
return true
else:
return false

type
Foo[T] = object
when isNillable(T):
nillable: float
else:
notnillable: int

var val1: Foo[ref int]
doAssert compiles(val1.nillable)
doAssert not compiles(val1.notnillable)
var val2: Foo[int]
doAssert not compiles(val2.nillable)
doAssert compiles(val2.notnillable)

block: # issue #1771
type
Foo[X, T] = object
bar: array[X.low..X.high, T]

proc test[X, T](f: Foo[X, T]): T =
f.bar[X.low]

var a: Foo[range[0..2], float]
doAssert test(a) == 0.0
31 changes: 31 additions & 0 deletions tests/macros/tmacros_various.nim
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,37 @@ xbenchmark:
discard inputtest
fastSHA("hey")

block: # issue #4547
macro lazy(stmtList : typed) : untyped =
let decl = stmtList[0]
decl.expectKind nnkLetSection
let name = decl[0][0].strVal
let call = decl[0][2].copy
call.expectKind nnkCall
let ident = newIdentNode("get" & name)
result = quote do:
var value : type(`call`)
proc `ident`() : type(`call`) =
if value.isNil:
value = `call`
value
type MyObject = object
a,b: int
# this part, the macro call and it's result (written in the comment below) is important
lazy:
let y = new(MyObject)
#[
var value: type(new(MyObject))
proc gety(): type(new(MyObject)) =
if value.isNil:
value = new(MyObject)
value
]#
doAssert gety().a == 0 # works and should work
doAssert gety().b == 0 # works and should work
doAssert not declared(y)
doAssert not compiles(y.a) # identifier y should not exist anymore
doAssert not compiles(y.b) # identifier y should not exist anymore

block: # bug #13511
type
Expand Down
32 changes: 32 additions & 0 deletions tests/template/mdotcall.nim
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,35 @@ template publicTemplateObjSyntax*(o: var ObjA, arg: Natural, doStuff: untyped) =
o.foo2()
doStuff
o.bar2(arg)

# issue #15246
import os

template sourceBaseName*(): string =
bind splitFile
instantiationInfo().filename.splitFile().name

# issue #12683

import unicode
template toRune(s: string): Rune = s.runeAt(0)
proc heh*[T](x: Slice[T], chars: string) = discard chars.toRune

# issue #7889

from streams import newStringStream, readData, writeData

template bindmeTemplate*(): untyped =
var tst = "sometext"
var ss = newStringStream("anothertext")
ss.writeData(tst[0].addr, 2)
discard ss.readData(tst[0].addr, 2) # <= comment this out to make compilation successful

from macros import quote, newIdentNode

macro bindmeQuote*(): untyped =
quote do:
var tst = "sometext"
var ss = newStringStream("anothertext")
ss.writeData(tst[0].addr, 2)
discard ss.readData(tst[0].addr, 2) # <= comment this out to make compilation successful
12 changes: 12 additions & 0 deletions tests/template/tdotcall.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,15 @@ block: # issue #11733
var evaluated = false
a.publicTemplateObjSyntax(42): evaluated = true
doAssert evaluated

block: # issue #15246
doAssert sourceBaseName() == "tdotcall"

block: # issue #12683
heh(0..40, "|")

block: # issue #7889
if false:
bindmeQuote()
if false:
bindmeTemplate()
36 changes: 36 additions & 0 deletions tests/template/template_various.nim
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,23 @@ block gensym3:
echo a ! b ! c ! d ! e
echo x,y,z

block: # issue #2465
template t() =
template declX(str: string) {.gensym.} =
var x {.inject.} : string = str

t()
doAssert not declared(declX)
doAssert not compiles(declX("a string"))

template t2() =
template foo() {.gensym.} =
echo 42

t2()
doAssert not declared(foo)
doAssert not compiles(foo())


block identifier_construction_with_overridden_symbol:
# could use add, but wanna make sure it's an override no matter what
Expand All @@ -368,3 +385,22 @@ block identifier_construction_with_overridden_symbol:
`examplefn n`()

exampletempl(1)

import typetraits

block: # issue #4596
type
T0 = object
T1 = object

template printFuncsT() =
proc getV[A](a: typedesc[A]): string =
var s {. global .} = name(A)
return s

printFuncsT()

doAssert getV(T1) == "T1"
doAssert getV(T0) == "T0"
doAssert getV(T0) == "T0"
doAssert getV(T1) == "T1"
25 changes: 17 additions & 8 deletions tests/template/tobjectdeclfield.nim
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
var x = 0
block: # issue #16005
var x = 0

block:
type Foo = object
x: float # ok

template main() =
block:
type Foo = object
x: float # Error: cannot use symbol of kind 'var' as a 'field'
x: float # ok

template main() =
block:
type Foo = object
x: float # Error: cannot use symbol of kind 'var' as a 'field'

main()

block: # issue #19552
template test =
type
test2 = ref object
reset: int

main()
test()
32 changes: 32 additions & 0 deletions tests/types/t5648.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
discard """
output: '''
ptr Foo
'''
joinable: false
"""
# not joinable because it causes out of memory with --gc:boehm

# issue #5648

import typetraits

type Foo = object
bar: int

proc main() =
var f = create(Foo)
f.bar = 3
echo f.type.name

discard realloc(f, 0)

var g = Foo()
g.bar = 3

var
mainPtr = cast[pointer](main)
mainFromPtr = cast[typeof(main)](mainPtr)

doAssert main == mainFromPtr

main()
41 changes: 15 additions & 26 deletions tests/types/tissues_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@ discard """
true
true
true
ptr Foo
(member: "hello world")
(member: 123.456)
(member: "hello world", x: ...)
(member: 123.456, x: ...)
0
false
'''
joinable: false
"""
# not joinable because it causes out of memory with --gc:boehm
import typetraits

block t1252:
echo float32 isnot float64
Expand All @@ -29,28 +25,6 @@ block t5640:

var v = vec2([0.0'f32, 0.0'f32])

block t5648:
type Foo = object
bar: int

proc main() =
var f = create(Foo)
f.bar = 3
echo f.type.name

discard realloc(f, 0)

var g = Foo()
g.bar = 3

var
mainPtr = cast[pointer](main)
mainFromPtr = cast[typeof(main)](mainPtr)

doAssert main == mainFromPtr

main()

block t7581:
discard int -1

Expand Down Expand Up @@ -107,3 +81,18 @@ block:

var f1: Foo
echo f1.bar

import macros

block: # issue #12582
macro foo(T: type): type =
nnkBracketExpr.newTree(bindSym "array", newLit 1, T)
var
_: foo(int) # fine
type
Foo = object
x: foo(int) # fine
Bar = ref object
x: foo(int) # error
let b = Bar()
let b2 = Bar(x: [123])

0 comments on commit d001b70

Please sign in to comment.