diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-05-12 02:49:47 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-11 20:49:47 +0200 |
commit | ebbad9e9604d778c32838c981c8748f3675d2659 (patch) | |
tree | 72e3bec49ef59c620ce3b59e81e53c03b535234c | |
parent | c00448358121bbf6b5e1fcfe39bb6eb3359d6462 (diff) | |
download | Nim-ebbad9e9604d778c32838c981c8748f3675d2659.tar.gz |
cursor fields cannot form reference cycles (#21832)
* cursor fields cannot form a reference cycle * fixes typo * fixes position
-rw-r--r-- | compiler/types.nim | 21 | ||||
-rw-r--r-- | tests/types/tcyclic.nim | 20 |
2 files changed, 28 insertions, 13 deletions
diff --git a/compiler/types.nim b/compiler/types.nim index 97cc439c0..96dbd26b2 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -374,15 +374,18 @@ proc canFormAcycleAux(g: ModuleGraph; marker: var IntSet, typ: PType, orig: PTyp proc canFormAcycleNode(g: ModuleGraph; marker: var IntSet, n: PNode, orig: PType, withRef: bool, hasTrace: bool): bool = result = false if n != nil: - result = canFormAcycleAux(g, marker, n.typ, orig, withRef, hasTrace) - if not result: - case n.kind - of nkNone..nkNilLit: - discard - else: - for i in 0..<n.len: - result = canFormAcycleNode(g, marker, n[i], orig, withRef, hasTrace) - if result: return + var hasCursor = n.kind == nkSym and sfCursor in n.sym.flags + # cursor fields don't own the refs, which cannot form reference cycles + if hasTrace or not hasCursor: + result = canFormAcycleAux(g, marker, n.typ, orig, withRef, hasTrace) + if not result: + case n.kind + of nkNone..nkNilLit: + discard + else: + for i in 0..<n.len: + result = canFormAcycleNode(g, marker, n[i], orig, withRef, hasTrace) + if result: return proc sameBackendType*(x, y: PType): bool diff --git a/tests/types/tcyclic.nim b/tests/types/tcyclic.nim index fc2852c49..651394c8b 100644 --- a/tests/types/tcyclic.nim +++ b/tests/types/tcyclic.nim @@ -51,10 +51,7 @@ cyclicNo((Cyclone, )) cyclicNo(Acyclic) cyclicYes(LinkedNode) - -when false: - # todo fix me - cyclicNo(LinkedNodeWithCursor) +cyclicNo(LinkedNodeWithCursor) # cursor doesn't increase rc, cannot form a cycle type ObjectWithoutCycles = object @@ -121,3 +118,18 @@ block: proc `=trace`(x: var myseq[Node]; env: pointer) = discard cyclicYes(Node) + +block: + type + Foo = object + id: ptr ref Foo + + cyclicNo(Foo) + +block: + type + InheritableObj = object of RootObj + InheritableRef = ref object of RootObj + + cyclicYes(InheritableObj) + cyclicYes(InheritableRef) |