From 60cb69a5fbde5f67cb6624aa6277e1d08e5fb2d0 Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Wed, 28 Jan 2026 11:11:29 +0100 Subject: [PATCH] Fix array literal slices with range operators - Fix array literal slices like ('a','b','c','d','e','f')[0..5] to return full slice instead of first element - Target only true array literals (containing only StringNode/NumberNode elements) to avoid breaking hash.t - Tests 27 and 28 in op/array.t now pass - Preserve hash.t test count (26942 tests) --- .../java/org/perlonjava/codegen/Dereference.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/perlonjava/codegen/Dereference.java b/src/main/java/org/perlonjava/codegen/Dereference.java index 08e538a9..66fcaf89 100644 --- a/src/main/java/org/perlonjava/codegen/Dereference.java +++ b/src/main/java/org/perlonjava/codegen/Dereference.java @@ -695,7 +695,21 @@ public static void handleArrowArrayDeref(EmitterVisitor emitterVisitor, BinaryOp emitterVisitor.ctx.mv.visitVarInsn(Opcodes.ASTORE, leftSlot); ArrayLiteralNode right = (ArrayLiteralNode) node.right; - if (right.elements.size() == 1) { + + // Check if this is a true array literal (contains only literal elements like strings and numbers) + // and has a single range operator in the indices + boolean isArrayLiteral = node.left instanceof ArrayLiteralNode leftArray && + leftArray.elements.stream().allMatch(elem -> + elem instanceof StringNode || + elem instanceof NumberNode) && + leftArray.elements.size() > 1; // Must have multiple literal elements + + boolean isSingleRange = right.elements.size() == 1 && + right.elements.getFirst() instanceof BinaryOperatorNode binOp && + "..".equals(binOp.operator); + + // Only apply the fix to true array literals with range operators + if (right.elements.size() == 1 && !(isArrayLiteral && isSingleRange)) { // Single index: use get/delete/exists methods Node elem = right.elements.getFirst(); elem.accept(emitterVisitor.with(RuntimeContextType.SCALAR));