diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index c5920f4b34..d7f4e38d2c 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -1072,7 +1072,10 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, flags: set[MoveOrCopy if sameLocation(dest, ri): # rule (self-assignment-removal): result = newNodeI(nkEmpty, dest.info) - elif isCursor(dest): + elif isCursor(dest) or dest.typ.kind in {tyOpenArray, tyVarargs}: + # hoisted openArray parameters might end up here + # openArray types don't have a lifted assignment operation (it's empty) + # bug #22132 case ri.kind: of nkStmtListExpr, nkBlockExpr, nkIfExpr, nkCaseStmt, nkTryStmt: template process(child, s): untyped = moveOrCopy(dest, child, c, s, flags) diff --git a/tests/arc/topenarray.nim b/tests/arc/topenarray.nim index 0e45f3ec7b..67c512e4f8 100644 --- a/tests/arc/topenarray.nim +++ b/tests/arc/topenarray.nim @@ -50,3 +50,21 @@ proc f(a: var string) = var a = "Hello" f(a) doAssert a == "Hallo" + +# bug #22132 +block: + func foo[T](arr: openArray[T], idx: int = arr.low): string = + doAssert idx == 0 + return $arr + + let bug = ["0", "c", "a"] + + let str = foo(bug) + + const expected = """["0", "c", "a"]""" + doAssert str == expected + + const noBugConst = ["0", "c", "a"] + doAssert foo(noBugConst) == expected + let noBugSeq = @["0", "c", "a"] + doAssert foo(noBugSeq) == expected