summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/liftdestructors.nim29
-rw-r--r--compiler/transf.nim3
2 files changed, 18 insertions, 14 deletions
diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim
index 4b69a9e9a..f861ce67a 100644
--- a/compiler/liftdestructors.nim
+++ b/compiler/liftdestructors.nim
@@ -327,6 +327,14 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
 
 proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
   createTypeBoundOps(c.g, c.c, t, body.info)
+  # recursions are tricky, so we might need to forward the generated
+  # operation here:
+  var t = t
+  if t.assignment == nil or t.destructor == nil:
+    let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct})
+    let canon = c.g.canonTypes.getOrDefault(h)
+    if canon != nil: t = canon
+
   case c.kind
   of attachedAsgn, attachedDeepCopy:
     doAssert t.assignment != nil
@@ -682,24 +690,23 @@ template inst(field, t) =
     else:
       localError(g.config, info, "unresolved generic parameter")
 
-proc isTrival(s: PSym): bool {.inline.} = s == nil or s.ast[bodyPos].len == 0
+proc isTrival(s: PSym): bool {.inline.} =
+  s == nil or (s.ast != nil and s.ast[bodyPos].len == 0)
 
 proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo) =
   ## In the semantic pass this is called in strategic places
   ## to ensure we lift assignment, destructors and moves properly.
   ## The later 'injectdestructors' pass depends on it.
-  if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.skipTypes({tyAlias}).flags != {}: return
+  if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.flags != {}: return
   incl orig.flags, tfCheckedForDestructor
 
-  let h = sighashes.hashType(orig, {CoType, CoConsiderOwned, CoDistinct})
+  let skipped = orig.skipTypes({tyGenericInst, tyAlias, tySink})
+
+  let h = sighashes.hashType(skipped, {CoType, CoConsiderOwned, CoDistinct})
   var canon = g.canonTypes.getOrDefault(h)
-  var overwrite = false
   if canon == nil:
-    let typ = orig.skipTypes({tyGenericInst, tyAlias, tySink})
-    g.canonTypes[h] = typ
-    canon = typ
-  if canon != orig:
-    overwrite = true
+    g.canonTypes[h] = skipped
+    canon = skipped
 
   # multiple cases are to distinguish here:
   # 1. we don't know yet if 'typ' has a nontrival destructor.
@@ -714,9 +721,7 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
       discard produceSym(g, c, canon, k, info)
     else:
       inst(canon.attachedOps[k], canon)
-
-  if overwrite:
-    for k in attachedDestructor..attachedSink:
+    if canon != orig:
       orig.attachedOps[k] = canon.attachedOps[k]
 
   if not isTrival(orig.destructor):
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 5660bcd8c..c63a26d10 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -1137,8 +1137,7 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache = true;
 
     incl(result.flags, nfTransf)
 
-    let cache = cache or prc.typ.callConv == ccInline
-    if cache:
+    if cache or prc.typ.callConv == ccInline:
       # genProc for inline procs will be called multiple times from different modules,
       # it is important to transform exactly once to get sym ids and locations right
       prc.transformedBody = result
revision' href='/ahoang/Nim/blame/install.txt?h=devel&id=0a2296b12313b8ce84e8190b6200885fdb06bf96'>^
99bcc233c ^
4d4b3b1c0 ^
db4f617af ^




9387913b7 ^
627e192f6 ^
9387913b7 ^
db4f617af ^




1f63d1c76 ^
053309e60 ^
1f63d1c76 ^
a58a2f382 ^
db4f617af ^








ff4a69b62 ^

db4f617af ^
300430fbb ^
e27e873b7 ^



1f63d1c76 ^
e27e873b7 ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68