summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorcooldome <cdome@bk.ru>2019-05-04 22:34:37 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-05-04 22:34:37 +0200
commitd3db189eb42c1c44d8be1a1fc847ed8db428638f (patch)
tree6156800598db9699a093056f890e83c5271f4ddc /compiler
parent9c3e23e0751881b16fab813fd3c2edc1b98b7f68 (diff)
downloadNim-d3db189eb42c1c44d8be1a1fc847ed8db428638f.tar.gz
Destructor lifting fixes #11149 (#11163)
* fixes #11149

* add test
Diffstat (limited to 'compiler')
-rw-r--r--compiler/injectdestructors.nim2
-rw-r--r--compiler/liftdestructors.nim17
-rw-r--r--compiler/sighashes.nim7
3 files changed, 16 insertions, 10 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim
index 0e414c975..0111bd4af 100644
--- a/compiler/injectdestructors.nim
+++ b/compiler/injectdestructors.nim
@@ -325,7 +325,7 @@ proc genOp(c: Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode =
 
   if op == nil:
     # give up and find the canonical type instead:
-    let h = sighashes.hashType(t, {CoType, CoConsiderOwned})
+    let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct})
     let canon = c.graph.canonTypes.getOrDefault(h)
     if canon != nil:
       op = canon.attachedOps[kind]
diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim
index 2dcaa7984..3e3b74f64 100644
--- a/compiler/liftdestructors.nim
+++ b/compiler/liftdestructors.nim
@@ -593,12 +593,13 @@ proc createTypeBoundOps(c: PContext; orig: PType; info: TLineInfo) =
   if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.skipTypes({tyAlias}).flags != {}: return
   incl orig.flags, tfCheckedForDestructor
 
-  let h = sighashes.hashType(orig, {CoType, CoConsiderOwned})
+  let h = sighashes.hashType(orig, {CoType, CoConsiderOwned, CoDistinct})
   var canon = c.graph.canonTypes.getOrDefault(h)
   var overwrite = false
   if canon == nil:
-    c.graph.canonTypes[h] = orig
-    canon = orig
+    let typ = orig.skipTypes({tyGenericInst, tyAlias})
+    c.graph.canonTypes[h] = typ
+    canon = typ
   elif canon != orig:
     overwrite = true
 
@@ -608,17 +609,17 @@ proc createTypeBoundOps(c: PContext; orig: PType; info: TLineInfo) =
   # 3. we have a lifted destructor.
   # 4. We have a custom destructor.
   # 5. We have a (custom) generic destructor.
-  let typ = canon.skipTypes({tyGenericInst, tyAlias})
+
   # we generate the destructor first so that other operators can depend on it:
   for k in attachedDestructor..attachedSink:
-    if typ.attachedOps[k] == nil:
-      discard produceSym(c, typ, k, info)
+    if canon.attachedOps[k] == nil:
+      discard produceSym(c, canon, k, info)
     else:
-      inst(typ.attachedOps[k], typ)
+      inst(canon.attachedOps[k], canon)
 
   if overwrite:
     for k in attachedDestructor..attachedSink:
-      orig.attachedOps[k] = typ.attachedOps[k]
+      orig.attachedOps[k] = canon.attachedOps[k]
 
   if not isTrival(orig.destructor):
     #or not isTrival(orig.assignment) or
diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim
index c69d58cd3..90c4cd18b 100644
--- a/compiler/sighashes.nim
+++ b/compiler/sighashes.nim
@@ -36,6 +36,7 @@ type
     CoOwnerSig
     CoIgnoreRange
     CoConsiderOwned
+    CoDistinct
 
 proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag])
 
@@ -97,7 +98,11 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
     for i in countup(0, sonsLen(t) - 1):
       c.hashType t.sons[i], flags
   of tyDistinct:
-    if {CoType, CoConsiderOwned} * flags == {CoType} or t.sym == nil:
+    if CoDistinct in flags:
+      if t.sym != nil: c.hashSym(t.sym)
+      if t.sym == nil or tfFromGeneric in t.flags:
+        c.hashType t.lastSon, flags
+    elif CoType in flags or t.sym == nil:
       c.hashType t.lastSon, flags
     else:
       c.hashSym(t.sym)