Fix Enum.slice/2 for ranges with step > 1 sliced by step > 1 (#15144)

When slicing a Range with step > 1 using a slice range that also has
step > 1, the formula for calculating the step in the slicer function
was incorrect.
This commit is contained in:
Panagiotis Nezis
2026-03-07 08:56:13 +01:00
committed by GitHub
parent 9a663cf3fa
commit 47d72d94d8
2 changed files with 11 additions and 1 deletions
+1 -1
View File
@@ -5224,7 +5224,7 @@ defimpl Enumerable, for: Range do
end
def slice(first.._//step = range) do
{:ok, Range.size(range), &slice(first + &1 * step, step + &3 - 1, &2)}
{:ok, Range.size(range), &slice(first + &1 * step, step * &3, &2)}
end
# TODO: Remove me on v2.0
+10
View File
@@ -2341,6 +2341,16 @@ defmodule EnumTest.Range do
assert Enum.slice(1..10//2, -5..-1) == [1, 3, 5, 7, 9]
assert Enum.slice(1..10//2, -5..-3) == [1, 3, 5]
# Range with step > 1 sliced by a range with step > 1
assert Enum.slice(1..10//2, 0..4//2) == [1, 5, 9]
assert Enum.slice(1..10//2, 0..4//3) == [1, 7]
assert Enum.slice(1..10//2, 1..4//2) == [3, 7]
assert Enum.slice(0..20//3, 0..6//2) == [0, 6, 12, 18]
# Range with negative step sliced by a range with step > 1
assert Enum.slice(10..1//-2, 0..4//2) == [10, 6, 2]
assert Enum.slice(20..0//-3, 0..6//2) == [20, 14, 8, 2]
assert_raise ArgumentError,
"Enum.slice/2 does not accept ranges with negative steps, got: 1..3//-2",
fn -> Enum.slice(1..5, 1..3//-2) end