diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index bec8b49f4f..b18bcf34e1 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -411,7 +411,9 @@ proc passCopyToSink(n: PNode; c: var Con; s: var Scope): PNode = "if possible, rearrange your program's control flow to prevent it") % $n) else: if c.graph.config.selectedGC in {gcArc, gcOrc}: - assert(not containsGarbageCollectedRef(n.typ)) + assert(not containsManagedMemory(n.typ)) + if n.typ.skipTypes(abstractInst).kind in {tyOpenArray, tyVarargs}: + localError(c.graph.config, n.info, "cannot create an implicit openArray copy to be passed to a sink parameter") result.add newTree(nkAsgn, tmp, p(n, c, s, normal)) # Since we know somebody will take over the produced copy, there is # no need to destroy it. diff --git a/compiler/types.nim b/compiler/types.nim index b9fc4d4a28..b20bf9c06c 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -321,6 +321,13 @@ proc containsGarbageCollectedRef*(typ: PType): bool = # things that are garbage-collected) result = searchTypeFor(typ, isGCRef) +proc isManagedMemory(t: PType): bool = + result = t.kind in GcTypeKinds or + (t.kind == tyProc and t.callConv == ccClosure) + +proc containsManagedMemory*(typ: PType): bool = + result = searchTypeFor(typ, isManagedMemory) + proc isTyRef(t: PType): bool = result = t.kind == tyRef or (t.kind == tyProc and t.callConv == ccClosure)