fixes #3476
This commit is contained in:
parent
e94a6ec1f9
commit
86e2d6ee90
2 changed files with 50 additions and 2 deletions
|
|
@ -243,14 +243,14 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
# generic[void](), generic[int]()
|
# generic[void](), generic[int]()
|
||||||
# see ttypeor.nim test.
|
# see ttypeor.nim test.
|
||||||
var i = 0
|
var i = 0
|
||||||
newSeq(entry.concreteTypes, fn.typ.len+gp.len)
|
newSeq(entry.concreteTypes, fn.typ.len+gp.len-1)
|
||||||
for s in instantiateGenericParamList(c, gp, pt):
|
for s in instantiateGenericParamList(c, gp, pt):
|
||||||
addDecl(c, s)
|
addDecl(c, s)
|
||||||
entry.concreteTypes[i] = s.typ
|
entry.concreteTypes[i] = s.typ
|
||||||
inc i
|
inc i
|
||||||
pushProcCon(c, result)
|
pushProcCon(c, result)
|
||||||
instantiateProcType(c, pt, result, info)
|
instantiateProcType(c, pt, result, info)
|
||||||
for j in 0 .. result.typ.len-1:
|
for j in 1 .. result.typ.len-1:
|
||||||
entry.concreteTypes[i] = result.typ.sons[j]
|
entry.concreteTypes[i] = result.typ.sons[j]
|
||||||
inc i
|
inc i
|
||||||
if tfTriggersCompileTime in result.typ.flags:
|
if tfTriggersCompileTime in result.typ.flags:
|
||||||
|
|
|
||||||
48
tests/generics/tvarseq_caching.nim
Normal file
48
tests/generics/tvarseq_caching.nim
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
discard """
|
||||||
|
output: '''@[1, 2, 3]
|
||||||
|
@[4.0, 5.0, 6.0]
|
||||||
|
@[1, 2, 3]
|
||||||
|
@[4.0, 5.0, 6.0]
|
||||||
|
@[1, 2, 3]
|
||||||
|
@[4, 5, 6]'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #3476
|
||||||
|
|
||||||
|
proc foo[T]: var seq[T] =
|
||||||
|
## Problem! Bug with generics makes every call to this proc generate
|
||||||
|
## a new seq[T] instead of retrieving the `items {.global.}` variable.
|
||||||
|
var items {.global.}: seq[T]
|
||||||
|
return items
|
||||||
|
|
||||||
|
proc foo2[T]: ptr seq[T] =
|
||||||
|
## Workaround! By returning by `ptr` instead of `var` we can get access to
|
||||||
|
## the `items` variable, but that means we have to explicitly deref at callsite.
|
||||||
|
var items {.global.}: seq[T]
|
||||||
|
return addr items
|
||||||
|
|
||||||
|
proc bar[T]: var seq[int] =
|
||||||
|
## Proof. This proc correctly retrieves the `items` variable. Notice the only thing
|
||||||
|
## that's changed from `foo` is that it returns `seq[int]` instead of `seq[T]`.
|
||||||
|
var items {.global.}: seq[int]
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
foo[int]() = @[1, 2, 3]
|
||||||
|
foo[float]() = @[4.0, 5.0, 6.0]
|
||||||
|
|
||||||
|
foo2[int]()[] = @[1, 2, 3]
|
||||||
|
foo2[float]()[] = @[4.0, 5.0, 6.0]
|
||||||
|
|
||||||
|
bar[int]() = @[1, 2, 3]
|
||||||
|
bar[float]() = @[4, 5, 6]
|
||||||
|
|
||||||
|
|
||||||
|
echo foo[int]() # prints 'nil' - BUG!
|
||||||
|
echo foo[float]() # prints 'nil' - BUG!
|
||||||
|
|
||||||
|
echo foo2[int]()[] # prints '@[1, 2, 3]'
|
||||||
|
echo foo2[float]()[] # prints '@[4.0, 5.0, 6.0]'
|
||||||
|
|
||||||
|
echo bar[int]() # prints '@[1, 2, 3]'
|
||||||
|
echo bar[float]() # prints '@[4, 5, 6]'
|
||||||
Loading…
Add table
Add a link
Reference in a new issue