Skip to content

Commit 8de8ca4

Browse files
committed
Do not set step to nil in ranges
Closes #12076
1 parent a342311 commit 8de8ca4

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

lib/elixir/lib/kernel.ex

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3862,8 +3862,18 @@ defmodule Kernel do
38623862
end
38633863

38643864
defp range(:guard, first, last) do
3865+
# We need to compute the step using guards. We don't have conditionals,
3866+
# but we can emulate them using a map access.
3867+
step =
3868+
quote do
3869+
:erlang.map_get(
3870+
:erlang.>(unquote(first), unquote(last)),
3871+
%{false: unquote(1), true: unquote(-1)}
3872+
)
3873+
end
3874+
38653875
# TODO: Deprecate me inside guard when sides are not integers on Elixir v1.17
3866-
{:%{}, [], [__struct__: Elixir.Range, first: first, last: last, step: nil]}
3876+
{:%{}, [], [__struct__: Elixir.Range, first: first, last: last, step: step]}
38673877
end
38683878

38693879
defp range(:match, first, last) do
@@ -4355,18 +4365,6 @@ defmodule Kernel do
43554365

43564366
defp small_literal_list?(_list), do: false
43574367

4358-
defp in_range(left, first, last, nil) do
4359-
# TODO: nil steps are only supported due to x..y in guards. Remove me on Elixir 2.0.
4360-
quote do
4361-
:erlang.is_integer(unquote(left)) and :erlang.is_integer(unquote(first)) and
4362-
:erlang.is_integer(unquote(last)) and
4363-
((:erlang."=<"(unquote(first), unquote(last)) and
4364-
unquote(increasing_compare(left, first, last))) or
4365-
(:erlang.<(unquote(last), unquote(first)) and
4366-
unquote(decreasing_compare(left, first, last))))
4367-
end
4368-
end
4369-
43704368
defp in_range(left, first, last, step) when is_integer(step) do
43714369
in_range_literal(left, first, last, step)
43724370
end

lib/elixir/test/elixir/range_test.exs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ defmodule RangeTest do
3535
assert Range.new(3, 1, -2) == 3..1//-2
3636
end
3737

38-
test "op" do
38+
test "fields" do
3939
assert (1..3).first == 1
4040
assert (1..3).last == 3
4141
assert (1..3).step == 1
@@ -57,6 +57,12 @@ defmodule RangeTest do
5757
assert Range.shift(10..0//-2, -2) == 14..4//-2
5858
end
5959

60+
test "in guard equality" do
61+
case {1, 1..1} do
62+
{n, range} when range == n..n -> true
63+
end
64+
end
65+
6066
test "limits are integer only" do
6167
first = 1.0
6268
last = 3.0

0 commit comments

Comments
 (0)