From 99b09e6609e5012a237b7ea34aed86c67328cf3f Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Tue, 9 Sep 2025 22:16:12 +0800 Subject: [PATCH] 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 08d74a1c272c25cbc7a0b5c2a9288a06cc23f619) --- compiler/transf.nim | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/compiler/transf.nim b/compiler/transf.nim index c6f0dbb332..197e073477 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -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