parent
6a621b35e7
commit
0c41ac792b
2 changed files with 58 additions and 2 deletions
|
|
@ -462,6 +462,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
|
|
||||||
case c.kind
|
case c.kind
|
||||||
of attachedAsgn, attachedDeepCopy:
|
of attachedAsgn, attachedDeepCopy:
|
||||||
|
# XXX: replace these with assertions.
|
||||||
if t.assignment == nil:
|
if t.assignment == nil:
|
||||||
return # protect from recursion
|
return # protect from recursion
|
||||||
body.add newHookCall(c, t.assignment, x, y)
|
body.add newHookCall(c, t.assignment, x, y)
|
||||||
|
|
@ -827,7 +828,10 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||||
if typ.kind == tyDistinct:
|
if typ.kind == tyDistinct:
|
||||||
return produceSymDistinctType(g, c, typ, kind, info)
|
return produceSymDistinctType(g, c, typ, kind, info)
|
||||||
|
|
||||||
result = symPrototype(g, typ, typ.owner, kind, info)
|
result = typ.attachedOps[kind]
|
||||||
|
if result == nil:
|
||||||
|
result = symPrototype(g, typ, typ.owner, kind, info)
|
||||||
|
|
||||||
var a = TLiftCtx(info: info, g: g, kind: kind, c: c, asgnForType:typ)
|
var a = TLiftCtx(info: info, g: g, kind: kind, c: c, asgnForType:typ)
|
||||||
a.fn = result
|
a.fn = result
|
||||||
|
|
||||||
|
|
@ -947,9 +951,18 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
|
||||||
let lastAttached = if g.config.selectedGC == gcOrc: attachedDispose
|
let lastAttached = if g.config.selectedGC == gcOrc: attachedDispose
|
||||||
else: attachedSink
|
else: attachedSink
|
||||||
|
|
||||||
|
# bug #15122: We need to produce all prototypes before entering the
|
||||||
|
# mind boggling recursion. Hacks like these imply we shoule rewrite
|
||||||
|
# this module.
|
||||||
|
var generics: array[attachedDestructor..attachedDispose, bool]
|
||||||
|
for k in attachedDestructor..lastAttached:
|
||||||
|
generics[k] = canon.attachedOps[k] != nil
|
||||||
|
if not generics[k]:
|
||||||
|
canon.attachedOps[k] = symPrototype(g, canon, canon.owner, k, info)
|
||||||
|
|
||||||
# we generate the destructor first so that other operators can depend on it:
|
# we generate the destructor first so that other operators can depend on it:
|
||||||
for k in attachedDestructor..lastAttached:
|
for k in attachedDestructor..lastAttached:
|
||||||
if canon.attachedOps[k] == nil:
|
if not generics[k]:
|
||||||
discard produceSym(g, c, canon, k, info)
|
discard produceSym(g, c, canon, k, info)
|
||||||
else:
|
else:
|
||||||
inst(canon.attachedOps[k], canon)
|
inst(canon.attachedOps[k], canon)
|
||||||
|
|
|
||||||
43
tests/arc/theavy_recursion.nim
Normal file
43
tests/arc/theavy_recursion.nim
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
discard """
|
||||||
|
output: "yay"
|
||||||
|
cmd: "nim c --gc:arc $file"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #15122
|
||||||
|
|
||||||
|
import tables
|
||||||
|
|
||||||
|
type
|
||||||
|
BENodeKind* = enum
|
||||||
|
tkEof,
|
||||||
|
tkBytes,
|
||||||
|
tkList,
|
||||||
|
tkDict
|
||||||
|
|
||||||
|
BENode* = object
|
||||||
|
case kind: BENodeKind
|
||||||
|
of tkBytes: strVal: string
|
||||||
|
of tkList: listVal: seq[BENode]
|
||||||
|
of tkDict: dictVal*: Table[string, BENode]
|
||||||
|
else:
|
||||||
|
discard
|
||||||
|
|
||||||
|
proc unused(s: string): BENode =
|
||||||
|
# bad:
|
||||||
|
result = BENode(kind: tkBytes, strVal: "abc")
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
var data = {
|
||||||
|
"examples": {
|
||||||
|
"values": BENode(
|
||||||
|
kind: tkList,
|
||||||
|
listVal: @[BENode(kind: tkBytes, strVal: "test")]
|
||||||
|
)
|
||||||
|
}.toTable()
|
||||||
|
}.toTable()
|
||||||
|
|
||||||
|
# For ARC listVal is empty for some reason
|
||||||
|
doAssert data["examples"]["values"].listVal[0].strVal == "test"
|
||||||
|
|
||||||
|
main()
|
||||||
|
echo "yay"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue