mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
test case haul for old generic/template/macro issues (#22564)
* test case haul for old generic/template/macro issues closes #12582, closes #19552, closes #2465, closes #4596, closes #15246, closes #12683, closes #7889, closes #4547, closes #12415, closes #2002, closes #1771, closes #5121 The test for #5648 is also moved into its own test from `types/tissues_types` due to not being joinable. * fix template gensym test
This commit is contained in:
@@ -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\"")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 fooGensym() {.gensym.} =
|
||||
echo 42
|
||||
|
||||
t2()
|
||||
doAssert not declared(fooGensym)
|
||||
doAssert not compiles(fooGensym())
|
||||
|
||||
|
||||
block identifier_construction_with_overridden_symbol:
|
||||
# could use add, but wanna make sure it's an override no matter what
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
main()
|
||||
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
|
||||
|
||||
test()
|
||||
|
||||
32
tests/types/t5648.nim
Normal file
32
tests/types/t5648.nim
Normal file
@@ -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()
|
||||
@@ -3,7 +3,6 @@ discard """
|
||||
true
|
||||
true
|
||||
true
|
||||
ptr Foo
|
||||
(member: "hello world")
|
||||
(member: 123.456)
|
||||
(member: "hello world", x: ...)
|
||||
@@ -11,10 +10,7 @@ ptr Foo
|
||||
0
|
||||
false
|
||||
'''
|
||||
joinable: false
|
||||
"""
|
||||
# not joinable because it causes out of memory with --gc:boehm
|
||||
import typetraits
|
||||
|
||||
block t1252:
|
||||
echo float32 isnot float64
|
||||
@@ -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
|
||||
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user