Introduce explicit copy (#15330)
This commit is contained in:
parent
ae4ede6b00
commit
a3e9cc5234
3 changed files with 28 additions and 1 deletions
|
|
@ -408,7 +408,7 @@ proc passCopyToSink(n: PNode; c: var Con; s: var Scope): PNode =
|
||||||
if isLValue(n) and not isCapturedVar(n) and n.typ.skipTypes(abstractInst).kind != tyRef and c.inSpawn == 0:
|
if isLValue(n) and not isCapturedVar(n) and n.typ.skipTypes(abstractInst).kind != tyRef and c.inSpawn == 0:
|
||||||
message(c.graph.config, n.info, hintPerformance,
|
message(c.graph.config, n.info, hintPerformance,
|
||||||
("passing '$1' to a sink parameter introduces an implicit copy; " &
|
("passing '$1' to a sink parameter introduces an implicit copy; " &
|
||||||
"if possible, rearrange your program's control flow to prevent it") % $n)
|
"if possible, rearrange your program's control flow to prevent it or use 'copy($1)' to hint the compiler it is intentional") % $n)
|
||||||
else:
|
else:
|
||||||
if c.graph.config.selectedGC in {gcArc, gcOrc}:
|
if c.graph.config.selectedGC in {gcArc, gcOrc}:
|
||||||
assert(not containsGarbageCollectedRef(n.typ))
|
assert(not containsGarbageCollectedRef(n.typ))
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,11 @@ proc move*[T](x: var T): T {.magic: "Move", noSideEffect.} =
|
||||||
result = x
|
result = x
|
||||||
wasMoved(x)
|
wasMoved(x)
|
||||||
|
|
||||||
|
func copy*[T](x: T): T {.inline.} =
|
||||||
|
## make explicit copy of the argument `x`, used to signal to the compiler
|
||||||
|
## the copy is intentional
|
||||||
|
result = x
|
||||||
|
|
||||||
type
|
type
|
||||||
range*[T]{.magic: "Range".} ## Generic type to construct range types.
|
range*[T]{.magic: "Range".} ## Generic type to construct range types.
|
||||||
array*[I, T]{.magic: "Array".} ## Generic type to construct
|
array*[I, T]{.magic: "Array".} ## Generic type to construct
|
||||||
|
|
|
||||||
22
tests/arc/tcopytosink_warning.nim
Normal file
22
tests/arc/tcopytosink_warning.nim
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nim c --gc:arc $file"
|
||||||
|
nimout: '''tcopytosink_warning.nim(17, 7) Hint: myhint [User]
|
||||||
|
tcopytosink_warning.nim(19, 9) Hint: passing 'x' to a sink parameter introduces an implicit copy; if possible, rearrange your program's control flow to prevent it or use 'copy(x)' to hint the compiler it is intentional [Performance]
|
||||||
|
'''
|
||||||
|
output: "x"
|
||||||
|
"""
|
||||||
|
import macros
|
||||||
|
|
||||||
|
proc test(v: var seq[string], x: sink string) =
|
||||||
|
v.add x
|
||||||
|
|
||||||
|
var v = @["a", "b", "c"]
|
||||||
|
var x = "x"
|
||||||
|
|
||||||
|
static:
|
||||||
|
hint("myhint")
|
||||||
|
test(v, copy(x)) # no warning
|
||||||
|
test(v, x) # produces warning
|
||||||
|
|
||||||
|
echo x # use after sink
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue