Example code from strformat import `&` type X = distinct int proc `=sink`(p1: var X; p2: X) = echo &"=sink {cast[int](p2)}" proc `=copy`(p1: var X; p2: X) = echo &"=copy {cast[int](p2)}" proc `=destroy`(p: var X) = echo &"=destroy {cast[int](p)}" proc main = echo "~~~~~~~~~~" block: proc byLet(v: int): owned X = let x = X(v) x discard byLet(1) echo "~~~~~~~~~~" block: proc byVar(v: int): owned X = var x = X(v) x discard byVar(2) echo "~~~~~~~~~~" block: proc byCast(v: int): owned X = cast[X](v) discard byCast(3) echo "~~~~~~~~~~" block: proc byConv(v: int): owned X = (X)(v) discard byConv(4) echo "~~~~~~~~~~" block: proc byVarMove(v: int): owned X = var x = X(v) move(x) discard byVarMove(5) echo "~~~~~~~~~~" block: proc byVarWasMoved(v: int): owned X = var x = X(v) result = x wasMoved(x) discard byVarWasMoved(6) echo "~~~~~~~~~~" main() Run
Run $ nim r --gc:arc --expandArc:main test.nim ... ~~~~~~~~~~ =copy 1 =destroy 0 ~~~~~~~~~~ =copy 2 =destroy 0 ~~~~~~~~~~ =copy 3 =destroy 0 ~~~~~~~~~~ =destroy 4 ~~~~~~~~~~ =destroy 0 =destroy 5 ~~~~~~~~~~ =copy 6 =destroy 0 ~~~~~~~~~~ Run Output of `--expandArc:main` echo ["~~~~~~~~~~"] block :tmp: var :tmpD proc byLet(v: int): owned X = result = let x = X(v) x discard :tmpD = byLet(1) :tmpD `=destroy`(:tmpD) echo ["~~~~~~~~~~"] block :tmp_1: var :tmpD_1 proc byVar(v_1: int): owned X = result_1 = var x_1 = X(v_1) x_1 discard :tmpD_1 = byVar(2) :tmpD_1 `=destroy`(:tmpD_1) echo ["~~~~~~~~~~"] block :tmp_2: var :tmpD_2 proc byCast(v_2: int): owned X = result_2 = cast[X](v_2) discard :tmpD_2 = byCast(3) :tmpD_2 `=destroy`(:tmpD_2) echo ["~~~~~~~~~~"] block :tmp_3: var :tmpD_3 proc byConv(v_3: int): owned X = result_3 = X(v_3) discard :tmpD_3 = byConv(4) :tmpD_3 `=destroy`(:tmpD_3) echo ["~~~~~~~~~~"] block :tmp_4: var :tmpD_4 proc byVarMove(v_4: int): owned X = result_4 = var x_2 = X(v_4) move(x_2) discard :tmpD_4 = byVarMove(5) :tmpD_4 `=destroy`(:tmpD_4) echo ["~~~~~~~~~~"] block :tmp_5: var :tmpD_5 proc byVarWasMoved(v_5: int): owned X = var x_3 = X(v_5) result_5 = x_3 wasMoved(x_3) discard :tmpD_5 = byVarWasMoved(6) :tmpD_5 `=destroy`(:tmpD_5) echo ["~~~~~~~~~~"] Run 1. Why the directly returned value that has been cast will be copied 2. Some copy didn't show up with `--expandArc` 3. `move()` and `wasMoved()` only apply to `var` types, how can I tell the compiler my sink instead of copy intention?