Nim icon indicating copy to clipboard operation
Nim copied to clipboard

Extraneous destructor call during environment init

Open arnetheduck opened this issue 10 months ago • 3 comments

Description

type NoCopy = object
  v:int

proc `=copy`(x: var NoCopy, y: NoCopy) {.error.}

proc `=destroy`(x: NoCopy) =
  echo "destroy ", x.v

proc caller(f: proc()) =
  f()

proc test2(vv: NoCopy) =
  echo "in here ", vv.v

proc test() =
  debugEcho "1"
  var v = NoCopy(v: 3)
  debugEcho "2"

  caller(proc() = echo v.v)

  debugEcho "4"
  test2(v)

test()

Nim Version

2.2.0

Current Output

1
destroy 0
2
3
4
in here 3
destroy 3

Expected Output

1
2
3
4
in here 3
destroy 3

Known Workarounds

No response

Additional Information

No response

arnetheduck avatar Feb 26 '25 10:02 arnetheduck

var :env
try:
  :env = [type node]()
  debugEcho ["1"]
  `=sink`(:env.v0, NoCopy(v: 3))
  debugEcho ["2"]
  caller((:anonymous, :env))
  debugEcho ["4"]
  test2(:env.v0)
finally:
  `=destroy`(:env)

In =sink(:env.v0, NoCopy(v: 3)), it needs to destroy the old data of :env.v0

ringabout avatar Feb 26 '25 11:02 ringabout

it needs to destroy the old data

semantically, this old data does not exist yet - ie we're initializing the environment for the first time.

The fact that an environment is being created doesn't really matter: either we're creating v on the stack or in the environment, but in both cases, there is no "prior instance".

arnetheduck avatar Feb 26 '25 11:02 arnetheduck

proc test() =
  debugEcho "1"
  var v = NoCopy(v: 3)
  debugEcho "2"
  test2(v)

Compare to this snippet - in this case, the stack memory of v is the "environment" in which v lives, and yet we do not first destroy the fictional "left-hand-side" instance before placing NoCopy(v: 3) onto it.

When emulating this behavior and pulling out v into a heap location so that it can be passed to a closure, we are not introducing any additional NoCopy instances - we're merely changing the memory location of the one instance that's been declared - this is a failure of the environment lifting to recognise that there was nothing to destroy to begin with.

arnetheduck avatar Feb 26 '25 11:02 arnetheduck