mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-27 09:43:58 +00:00
fixes #25464; gives a deprecated warning when =dup is not provided while there being a custom =copy (#25485)
Gives a deprecated warning to keep backwards compatibility fixes #25464
This commit is contained in:
@@ -558,6 +558,15 @@ proc declareTempOf(c: var TLiftCtx; body: PNode; value: PNode): PNode =
|
||||
v.addVar(result, value)
|
||||
body.add v
|
||||
|
||||
proc errorDupCustomCopy(c: var TLiftCtx; t: PType) {.inline.} =
|
||||
## Emit an error when generating `=dup` code and a custom `=copy` hook
|
||||
## exists
|
||||
if c.kind == attachedDup:
|
||||
let op2 = getAttachedOp(c.g, t, attachedAsgn)
|
||||
if op2 != nil and sfOverridden in op2.flags:
|
||||
localError(c.g.config, c.info,
|
||||
"'=dup' is not provided while a custom '=copy' is defined for type '" & typeToString(t) & "'")
|
||||
|
||||
proc addIncStmt(c: var TLiftCtx; body, i: PNode) =
|
||||
let incCall = genBuiltin(c, mInc, "inc", i)
|
||||
incCall.add lowerings.newIntLit(c.g, c.info, 1)
|
||||
@@ -1056,6 +1065,9 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
if c.kind == attachedDup:
|
||||
var op2 = getAttachedOp(c.g, t, attachedAsgn)
|
||||
if op2 != nil and sfOverridden in op2.flags:
|
||||
# warn if a custom '=copy' exists but no '=dup' is provided
|
||||
message(c.g.config, c.info, warnDeprecated,
|
||||
"'=dup' is not provided while a custom '=copy' is defined for type '" & typeToString(t) & "'; this will become a compile time error in the future")
|
||||
#markUsed(c.g.config, c.info, op, c.g.usageSym)
|
||||
onUse(c.info, op2)
|
||||
body.add newHookCall(c, t.assignment, x, y)
|
||||
@@ -1065,6 +1077,7 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
fillBodyObjT(c, t, body, x, y)
|
||||
of tyDistinct:
|
||||
if not considerUserDefinedOp(c, t, body, x, y):
|
||||
errorDupCustomCopy(c, t)
|
||||
fillBody(c, t.elementType, body, x, y)
|
||||
of tyTuple:
|
||||
fillBodyTup(c, t, body, x, y)
|
||||
|
||||
39
tests/destructor/tdup_from_copy.nim
Normal file
39
tests/destructor/tdup_from_copy.nim
Normal file
@@ -0,0 +1,39 @@
|
||||
discard """
|
||||
errormsg: "'=dup' is not provided while a custom '=copy' is defined for type 'Foo'"
|
||||
"""
|
||||
|
||||
type Foo = distinct int
|
||||
|
||||
var counter = 0
|
||||
|
||||
proc `=destroy`(pkt: var Foo) =
|
||||
if cast[int](pkt) != 0:
|
||||
echo cast[int](pkt)
|
||||
|
||||
proc `=copy`(a: var Foo, b: Foo) =
|
||||
if cast[int](a) == cast[int](b):
|
||||
return
|
||||
|
||||
`=destroy`(a)
|
||||
if cast[int](b) == 0:
|
||||
zeroMem(addr a, sizeof(Foo))
|
||||
else:
|
||||
counter += 1
|
||||
copyMem(addr a, addr counter, sizeof(Foo))
|
||||
echo "copy!"
|
||||
|
||||
proc makeFoo(): Foo =
|
||||
counter += 1
|
||||
cast[Foo](counter)
|
||||
|
||||
|
||||
type Bar = object
|
||||
val: Foo
|
||||
|
||||
|
||||
proc consume(x: sink Bar) =
|
||||
discard
|
||||
|
||||
let x = Bar(val: makeFoo())
|
||||
consume(x)
|
||||
discard x
|
||||
Reference in New Issue
Block a user