mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-06 07:38:24 +00:00
infer error for =dup if there is a custom =copy error hook (#22004)
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user