summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semstmts.nim8
-rw-r--r--tests/destructor/tdestructor_too_late.nim14
2 files changed, 20 insertions, 2 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index dfa592549..1b7d61376 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1622,7 +1622,9 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
         else: break
       if obj.kind in {tyObject, tyDistinct, tySequence, tyString}:
         obj = canonType(c, obj)
-        if obj.destructor.isNil:
+        if obj.attachedOps[attachedDestructor] == s:
+          discard "forward declared destructor"
+        elif obj.destructor.isNil and tfCheckedForDestructor notin obj.flags:
           obj.attachedOps[attachedDestructor] = s
         else:
           prevDestructor(c, obj.destructor, obj, n.info)
@@ -1687,7 +1689,9 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
         obj = canonType(c, obj)
         #echo "ATTACHING TO ", obj.id, " ", s.name.s, " ", cast[int](obj)
         let k = if name == "=": attachedAsgn else: attachedSink
-        if obj.attachedOps[k].isNil:
+        if obj.attachedOps[k] == s:
+          discard "forward declared op"
+        elif obj.attachedOps[k].isNil and tfCheckedForDestructor notin obj.flags:
           obj.attachedOps[k] = s
         else:
           prevDestructor(c, obj.attachedOps[k], obj, n.info)
diff --git a/tests/destructor/tdestructor_too_late.nim b/tests/destructor/tdestructor_too_late.nim
new file mode 100644
index 000000000..d279280ba
--- /dev/null
+++ b/tests/destructor/tdestructor_too_late.nim
@@ -0,0 +1,14 @@
+discard """
+  errmsg: "cannot bind another '=destroy' to: Obj; previous declaration was constructed here implicitly: tdestructor_too_late.nim(7, 16)"
+"""
+type Obj* = object
+  v*: int
+
+proc something(this: sink Obj) = 
+  discard
+
+proc `=destroy`(this: var Obj) =
+  echo "igotdestroyed"
+  this.v = -1
+
+var test* = Obj(v: 42)
\ No newline at end of file