fixes #24093; Dereferencing result of cast in single expression triggers unnecessary copy (#25143)

fixes #24093

transforms
```nim
let a = new array[1000, byte]
block:
  for _ in cast[typeof(a)](a)[]:
    discard
```
into
```nim
let a = new array[1000, byte]
block:
  let temp = cast[typeof(a)](a)
  for _ in temp[]:
    discard
```
So it keeps the same behavior with the manual version

(cherry picked from commit 08d74a1c27)
This commit is contained in:
ringabout
2025-09-09 22:16:12 +08:00
committed by narimiran
parent 516f5141ba
commit 99b09e6609

View File

@@ -828,12 +828,20 @@ proc transformFor(c: PTransf, n: PNode): PNode =
t = formal.ast.typ # better use the type that actually has a destructor.
elif t.destructor == nil and arg.typ.destructor != nil:
t = arg.typ
# generate a temporary and produce an assignment statement:
var temp = newTemp(c, t, formal.info)
#incl(temp.sym.flags, sfCursor)
addVar(v, temp)
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg, true))
newC.mapping[formal.itemId] = temp
if arg.kind in {nkDerefExpr, nkHiddenDeref}:
# optimizes for `[]` # bug #24093
var temp = newTemp(c, arg[0].typ, formal.info)
addVar(v, temp)
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg[0], true))
newC.mapping[formal.itemId] = newDeref(temp)
else:
# generate a temporary and produce an assignment statement:
var temp = newTemp(c, t, formal.info)
#incl(temp.sym.flags, sfCursor)
addVar(v, temp)
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg, true))
newC.mapping[formal.itemId] = temp
of paVarAsgn:
assert(skipTypes(formal.typ, abstractInst).kind in {tyVar, tyLent})
newC.mapping[formal.itemId] = arg