diff options
author | cooldome <cdome@bk.ru> | 2019-05-04 22:34:37 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-05-04 22:34:37 +0200 |
commit | d3db189eb42c1c44d8be1a1fc847ed8db428638f (patch) | |
tree | 6156800598db9699a093056f890e83c5271f4ddc /compiler | |
parent | 9c3e23e0751881b16fab813fd3c2edc1b98b7f68 (diff) | |
download | Nim-d3db189eb42c1c44d8be1a1fc847ed8db428638f.tar.gz |
Destructor lifting fixes #11149 (#11163)
* fixes #11149 * add test
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/injectdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 17 | ||||
-rw-r--r-- | compiler/sighashes.nim | 7 |
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) |