diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index a2f97f12c9..1f9fbfde9b 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -343,7 +343,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = of tyString: if optSeqDestructors in p.config.globalOptions: genGenericAsgn(p, dest, src, flags) - elif (needToCopy notin flags and src.storage != OnStatic) or canMove(p, src.lode, dest): + elif ({needToCopy, needToCopySinkParam} * flags == {} and src.storage != OnStatic) or canMove(p, src.lode, dest): genRefAssign(p, dest, src) else: if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config): @@ -2345,8 +2345,13 @@ proc genMove(p: BProc; n: PNode; d: var TLoc) = else: linefmt(p, cpsStmts, "$1($2);$n", [rdLoc(b), byRefLoc(p, a)]) else: - let flags = if not canMove(p, n[1], d): {needToCopy} else: {} - genAssignment(p, d, a, flags) + if n[1].kind == nkSym and isSinkParam(n[1].sym): + var tmp = getTemp(p, n[1].typ.skipTypes({tySink})) + genAssignment(p, tmp, a, {needToCopySinkParam}) + genAssignment(p, d, tmp, {}) + resetLoc(p, tmp) + else: + genAssignment(p, d, a, {}) resetLoc(p, a) proc genDestroy(p: BProc; n: PNode) = diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 437928039f..f6a2a9b916 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -412,6 +412,7 @@ proc rdCharLoc(a: TLoc): Rope = type TAssignmentFlag = enum needToCopy + needToCopySinkParam needTempForOpenArray TAssignmentFlags = set[TAssignmentFlag] diff --git a/tests/refc/tsinkbug.nim b/tests/refc/tsinkbug.nim index 2cd762f405..de2ec98a54 100644 --- a/tests/refc/tsinkbug.nim +++ b/tests/refc/tsinkbug.nim @@ -15,3 +15,12 @@ var obj = AnObject(value: 42) echo "Value is: ", obj.value mutate(obj) echo "Value is: ", obj.value + +proc p(x: sink string) = + var y = move(x) + doAssert x.len == 0 + doAssert y.len == 4 + +p("1234") +var s = "oooo" +p(s)