mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-11 22:08:54 +00:00
generic issues test cases (#24028)
closes #1969, closes #7547, closes #7737, closes #11838, closes #12283, closes #12714, closes #12720, closes #14053, closes #16118, closes #19670, closes #22645 I was going to wait on these but regression tests even for recent PRs are turning out to be important in wide reaching PRs like #24010. The other issues with the working label felt either finnicky (#7385, #9156, #12732, #15247), excessive to test (#12405, #12424, #17527), or I just don't know what fixed them/what the issue was (#16128: the PR link gives a server error by Github, #12457, #12487).
This commit is contained in:
86
tests/generics/tbracketinstantiation.nim
Normal file
86
tests/generics/tbracketinstantiation.nim
Normal file
@@ -0,0 +1,86 @@
|
||||
discard """
|
||||
nimout: '''
|
||||
type
|
||||
Bob = object
|
||||
type
|
||||
Another = object
|
||||
'''
|
||||
"""
|
||||
|
||||
block: # issue #22645
|
||||
type
|
||||
Opt[T] = object
|
||||
FutureBase = ref object of RootObj
|
||||
Future[T] = ref object of FutureBase ## Typed future.
|
||||
internalValue: T ## Stored value
|
||||
template err[T](E: type Opt[T]): E = E()
|
||||
proc works(): Future[Opt[int]] {.stackTrace: off, gcsafe, raises: [].} =
|
||||
var chronosInternalRetFuture: FutureBase
|
||||
template result(): untyped {.used.} =
|
||||
Future[Opt[int]](chronosInternalRetFuture).internalValue
|
||||
result = err(type(result))
|
||||
proc breaks(): Future[Opt[int]] {.stackTrace: off, gcsafe, raises: [].} =
|
||||
var chronosInternalRetFuture: FutureBase
|
||||
template result(): untyped {.used.} =
|
||||
cast[Future[Opt[int]]](chronosInternalRetFuture).internalValue
|
||||
result = err(type(result))
|
||||
|
||||
import macros
|
||||
|
||||
block: # issue #16118
|
||||
macro thing(name: static[string]) =
|
||||
result = newStmtList(
|
||||
nnkTypeSection.newTree(
|
||||
nnkTypeDef.newTree(
|
||||
ident(name),
|
||||
newEmptyNode(),
|
||||
nnkObjectTy.newTree(
|
||||
newEmptyNode(),
|
||||
newEmptyNode(),
|
||||
nnkRecList.newTree()))))
|
||||
template foo(name: string): untyped =
|
||||
thing(name)
|
||||
expandMacros:
|
||||
foo("Bob")
|
||||
block:
|
||||
expandMacros:
|
||||
foo("Another")
|
||||
|
||||
block: # issue #19670
|
||||
type
|
||||
Past[Z] = object
|
||||
OpenObject = object
|
||||
|
||||
macro rewriter(prc: untyped): untyped =
|
||||
prc.body.add(nnkCall.newTree(
|
||||
prc.params[0]
|
||||
))
|
||||
prc
|
||||
|
||||
macro macroAsync(name, restype: untyped): untyped =
|
||||
quote do:
|
||||
proc `name`(): Past[seq[`restype`]] {.rewriter.} = discard
|
||||
|
||||
macroAsync(testMacro, OpenObject)
|
||||
|
||||
import asyncdispatch
|
||||
|
||||
block: # issue #11838 long
|
||||
type
|
||||
R[P] = object
|
||||
updates: seq[P]
|
||||
D[T, P] = ref object
|
||||
ps: seq[P]
|
||||
t: T
|
||||
proc newD[T, P](ps: seq[P], t: T): D[T, P] =
|
||||
D[T, P](ps: ps, t: t)
|
||||
proc loop[T, P](d: D[T, P]) =
|
||||
var results = newSeq[Future[R[P]]](10)
|
||||
let d = newD[string, int](@[1], "")
|
||||
d.loop()
|
||||
|
||||
block: # issue #11838 minimal
|
||||
type R[T] = object
|
||||
proc loop[T]() =
|
||||
discard newSeq[R[R[T]]]()
|
||||
loop[int]()
|
||||
@@ -172,3 +172,15 @@ block: # issue #23865
|
||||
return $error
|
||||
"ok"
|
||||
doAssert g(int) == "f"
|
||||
|
||||
import sequtils
|
||||
|
||||
block: # issue #12283
|
||||
var b = 5
|
||||
type Foo[T] = object
|
||||
h, w: int
|
||||
proc bar[T](foos: seq[Foo[T]]): T =
|
||||
let w = foldl(foos, a + b.w, 0)
|
||||
w
|
||||
let foos = @[Foo[int](h: 3, w: 5), Foo[int](h: 4, w: 6)]
|
||||
doAssert bar(foos) == 11
|
||||
|
||||
@@ -294,6 +294,37 @@ block: # issue #22647
|
||||
var x: b[4]
|
||||
x.p()
|
||||
|
||||
block: # issue #1969
|
||||
type ZeroGenerator = object
|
||||
proc next(g: ZeroGenerator): int = 0
|
||||
# This compiles.
|
||||
type TripleOfInts = tuple
|
||||
a, b, c: typeof(new(ZeroGenerator)[].next)
|
||||
# This raises a compiler error before it's even instantiated.
|
||||
# The `new` proc can't be resolved because `Generator` is not defined.
|
||||
type TripleLike[Generator] = tuple
|
||||
a, b, c: typeof(new(Generator)[].next)
|
||||
|
||||
import std/atomics
|
||||
|
||||
block: # issue #12720
|
||||
const CacheLineSize = 128
|
||||
type
|
||||
Enqueueable = concept x, type T
|
||||
x is ptr
|
||||
x.next is Atomic[pointer]
|
||||
MyChannel[T: Enqueueable] = object
|
||||
pad: array[CacheLineSize - sizeof(default(T)[]), byte]
|
||||
dummy: typeof(default(T)[])
|
||||
|
||||
block: # issue #12714
|
||||
type
|
||||
Enqueueable = concept x, type T
|
||||
x is ptr
|
||||
x.next is Atomic[pointer]
|
||||
MyChannel[T: Enqueueable] = object
|
||||
dummy: type(default(T)[])
|
||||
|
||||
when false: # issue #22342, type section version of #22607
|
||||
type GenAlias[isInt: static bool] = (
|
||||
when isInt:
|
||||
|
||||
61
tests/macros/tgettypeinst7737.nim
Normal file
61
tests/macros/tgettypeinst7737.nim
Normal file
@@ -0,0 +1,61 @@
|
||||
discard """
|
||||
nimout: '''
|
||||
seq[int]
|
||||
CustomSeq[int]
|
||||
'''
|
||||
"""
|
||||
|
||||
import macros, typetraits, sequtils
|
||||
|
||||
block: # issue #7737 original
|
||||
type
|
||||
CustomSeq[T] = object
|
||||
data: seq[T]
|
||||
|
||||
proc getSubType(T: NimNode): NimNode =
|
||||
echo getTypeInst(T).repr
|
||||
result = getTypeInst(T)[1]
|
||||
|
||||
macro typed_helper(x: varargs[typed]): untyped =
|
||||
let foo = getSubType(x[0])
|
||||
result = quote do: discard
|
||||
|
||||
macro untyped_heavylifting(x: varargs[untyped]): untyped =
|
||||
var containers = nnkArgList.newTree()
|
||||
for arg in x:
|
||||
case arg.kind:
|
||||
of nnkInfix:
|
||||
if eqIdent(arg[0], "in"):
|
||||
containers.add arg[2]
|
||||
else:
|
||||
discard
|
||||
result = quote do:
|
||||
typed_helper(`containers`)
|
||||
var a, b, c: seq[int]
|
||||
untyped_heavylifting z in c, x in a, y in b:
|
||||
discard
|
||||
## The following gives me CustomSeq instead
|
||||
## of CustomSeq[int] in getTypeInst
|
||||
var u, v, w: CustomSeq[int]
|
||||
untyped_heavylifting z in u, x in v, y in w:
|
||||
discard
|
||||
|
||||
block: # issue #7737 comment
|
||||
type
|
||||
CustomSeq[T] = object
|
||||
data: seq[T]
|
||||
# when using just one argument, `foo` and `bar` should be exactly
|
||||
# identical.
|
||||
macro foo(arg: typed): string =
|
||||
result = newLit(arg.getTypeInst.repr)
|
||||
macro bar(args: varargs[typed]): untyped =
|
||||
result = newTree(nnkBracket)
|
||||
for arg in args:
|
||||
result.add newLit(arg.getTypeInst.repr)
|
||||
var
|
||||
a: seq[int]
|
||||
b: CustomSeq[int]
|
||||
doAssert foo(a) == "seq[int]"
|
||||
doAssert bar(a) == ["seq[int]"]
|
||||
doAssert foo(b) == "CustomSeq[int]"
|
||||
doAssert bar(b) == ["CustomSeq[int]"]
|
||||
@@ -192,6 +192,37 @@ block: # issue #4990 comment
|
||||
let bar = Bar(curIndex: 0)
|
||||
doAssert bar.next() == meB
|
||||
|
||||
block: # issue #14053
|
||||
template returnType(value: static[int]): typedesc =
|
||||
when value == 1:
|
||||
int
|
||||
else:
|
||||
float
|
||||
proc fun(value: static[int]): returnType(value) = discard
|
||||
doAssert fun(1) is int
|
||||
template returnType2(value: static[int]): typedesc =
|
||||
int
|
||||
proc fun2(value: static[int]): returnType2(value) = discard
|
||||
doAssert fun2(1) is int
|
||||
|
||||
block: # issue #7547
|
||||
macro foo(N: static[int]): untyped =
|
||||
result = getType(int)
|
||||
type
|
||||
Foo[N: static[int]] = foo(N)
|
||||
ContainsFoo[N: static[int]] = object
|
||||
Ffoo: Foo[N]
|
||||
proc initFoo(N: static[int]): Foo[N] = discard
|
||||
proc initContainsFoo(size: static[int]): ContainsFoo[size] = discard
|
||||
var a: Foo[10] # Works
|
||||
doAssert a is int
|
||||
let b = initFoo(10) # Works
|
||||
doAssert b is int
|
||||
let c = ContainsFoo[5]() # Works
|
||||
doAssert c.Ffoo is int
|
||||
let z = initContainsFoo(5) # Error: undeclared identifier: 'N'
|
||||
doAssert z.Ffoo is int
|
||||
|
||||
when false: # issue #22607, needs nkWhenStmt to be handled like nkRecWhen
|
||||
proc test[x: static bool](
|
||||
t: (
|
||||
|
||||
Reference in New Issue
Block a user