nimskull icon indicating copy to clipboard operation
nimskull copied to clipboard

value is implicitly moved even though it's used afterwards

Open zerbina opened this issue 2 months ago • 0 comments

Example

type Object = object
  has: bool

var wasDestroyed = false

proc `=destroy`(x: var Object) =
  if x.has:
    wasDestroyed = true

proc f_sink(x: sink Object) =
  discard

proc test() =
  var o = Object(has: true)
  try:
    try:
      f_sink(o) # must not be sunken
      raise CatchableError.newException("")
    except IOError:
      # omitting the inner try makes the code work as expected
      discard "not reached"
  except CatchableError:
    doAssert not wasDestroyed
    discard o # use `o`, preventing it from being moved earlier

test()

Actual Output

The assertion fails, as o was erroneously sunken into the call argument.

Expected Output

The program compiles and runs without error. o is used beyond the procedure call, so it should not be moved.

Additional Information

The culprit is here: https://github.com/nim-works/nimskull/blob/f401e73639c2d15f2aefbad04c96199c8308b3dc/compiler/sem/mirexec.nim#L524-L533

There's no connection between the raise and the outer except in the control-flow graph, due to a missing edge between the inner and outer except.

zerbina avatar May 09 '24 00:05 zerbina