diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 94aa22ae40..cef1b444fa 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -89,10 +89,11 @@ const errXCannotBeAssignedTo = "'$1' cannot be assigned to" errLetNeedsInit = "'let' symbol requires an initialization" -proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo) = - if typ == nil or sfGeneratedOp in tracked.owner.flags: +proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo; explicit = false) = + if typ == nil or (sfGeneratedOp in tracked.owner.flags and not explicit): # don't create type bound ops for anything in a function with a `nodestroy` pragma # bug #21987 + # unless this is an explicit call, bug #24626 return when false: let realType = typ.skipTypes(abstractInst) @@ -926,7 +927,7 @@ proc trackCall(tracked: PEffects; n: PNode) = # rebind type bounds operations after createTypeBoundOps call let t = n[1].typ.skipTypes({tyAlias, tyVar}) if a.sym != getAttachedOp(tracked.graph, t, TTypeAttachedOp(opKind)): - createTypeBoundOps(tracked, t, n.info) + createTypeBoundOps(tracked, t, n.info, explicit = true) let op = getAttachedOp(tracked.graph, t, TTypeAttachedOp(opKind)) if op != nil: n[0].sym = op diff --git a/tests/arc/tnodestroyexplicithook.nim b/tests/arc/tnodestroyexplicithook.nim new file mode 100644 index 0000000000..3342a53f5d --- /dev/null +++ b/tests/arc/tnodestroyexplicithook.nim @@ -0,0 +1,20 @@ +# issue #24626 + +proc arrayWith2[T](y: T, size: static int): array[size, T] {.noinit, nodestroy, raises: [].} = + ## Creates a new array filled with `y`. + for i in 0..size-1: + when defined(nimHasDup): + result[i] = `=dup`(y) + else: + wasMoved(result[i]) + `=copy`(result[i], y) + +proc useArray(x: seq[int]) = + var a = arrayWith2(x, 2) + +proc main = + let x = newSeq[int](100) + for i in 0..5: + useArray(x) + +main()