diff options
-rw-r--r-- | compiler/injectdestructors.nim | 11 | ||||
-rw-r--r-- | tests/destructor/tprevent_assign2.nim | 4 |
2 files changed, 12 insertions, 3 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index a03f85d02..c5056025b 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -186,8 +186,11 @@ template isUnpackedTuple(n: PNode): bool = ## hence unpacked tuples themselves don't need to be destroyed (n.kind == nkSym and n.sym.kind == skTemp and n.sym.typ.kind == tyTuple) -proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string) = +proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string; inferredFromCopy = false) = var m = "'" & opname & "' is not available for type <" & typeToString(t) & ">" + if inferredFromCopy: + m.add ", which is inferred from unavailable '=copy'" + if (opname == "=" or opname == "=copy" or opname == "=dup") and ri != nil: m.add "; requires a copy because it's not the last read of '" m.add renderTree(ri) @@ -430,6 +433,12 @@ proc passCopyToSink(n: PNode; c: var Con; s: var Scope): PNode = if op != nil and tfHasOwned notin typ.flags: if sfError in op.flags: c.checkForErrorPragma(n.typ, n, "=dup") + else: + let copyOp = getAttachedOp(c.graph, typ, attachedAsgn) + if copyOp != nil and sfError in copyOp.flags and + sfOverriden notin op.flags: + c.checkForErrorPragma(n.typ, n, "=dup", inferredFromCopy = true) + let src = p(n, c, s, normal) var newCall = newTreeIT(nkCall, src.info, src.typ, newSymNode(op), diff --git a/tests/destructor/tprevent_assign2.nim b/tests/destructor/tprevent_assign2.nim index 7d788fa5c..eb5588b1a 100644 --- a/tests/destructor/tprevent_assign2.nim +++ b/tests/destructor/tprevent_assign2.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "'=dup' is not available for type <Foo>; requires a copy because it's not the last read of 'otherTree'" + errormsg: "'=dup' is not available for type <Foo>, which is inferred from unavailable '=copy'; requires a copy because it's not the last read of 'otherTree'; another read is done here: tprevent_assign2.nim(51, 31); routine: preventThis" file: "tprevent_assign2.nim" line: 49 """ @@ -10,7 +10,7 @@ type proc `=destroy`(f: var Foo) = f.x = 0 proc `=copy`(a: var Foo; b: Foo) {.error.} # = a.x = b.x -proc `=dup`(a: Foo): Foo {.error.} + proc `=sink`(a: var Foo; b: Foo) = a.x = b.x proc createTree(x: int): Foo = |