From e12b377ac3cc25f880626d512b9cfac5d43079b1 Mon Sep 17 00:00:00 2001 From: sabiwara Date: Sun, 2 Mar 2025 09:26:23 +0900 Subject: [PATCH 1/2] Fix zipping on cycle stream Close https://github.com/elixir-lang/elixir/issues/14306 --- lib/elixir/lib/stream.ex | 2 +- lib/elixir/test/elixir/enum_test.exs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/elixir/lib/stream.ex b/lib/elixir/lib/stream.ex index 07fd4a701eb..73f5508df36 100644 --- a/lib/elixir/lib/stream.ex +++ b/lib/elixir/lib/stream.ex @@ -1447,7 +1447,7 @@ defmodule Stream do defp check_cycle_first_element(reduce) do fn acc -> case reduce.(acc) do - {state, []} when state in [:done, :halted] -> + {:done, []} -> raise ArgumentError, "cannot cycle over an empty enumerable" other -> diff --git a/lib/elixir/test/elixir/enum_test.exs b/lib/elixir/test/elixir/enum_test.exs index d39c415514d..c9529dec51e 100644 --- a/lib/elixir/test/elixir/enum_test.exs +++ b/lib/elixir/test/elixir/enum_test.exs @@ -1521,6 +1521,18 @@ defmodule EnumTest do assert Enum.zip([], []) == [] end + test "zip/2 with infinite streams" do + assert Enum.zip([], Stream.cycle([1, 2])) == [] + assert Enum.zip([], Stream.cycle(1..2)) == [] + assert Enum.zip(.., Stream.cycle([1, 2])) == [] + assert Enum.zip(.., Stream.cycle(1..2)) == [] + + assert Enum.zip(Stream.cycle([1, 2]), ..) == [] + assert Enum.zip(Stream.cycle(1..2), ..) == [] + assert Enum.zip(Stream.cycle([1, 2]), ..) == [] + assert Enum.zip(Stream.cycle(1..2), ..) == [] + end + test "zip/1" do assert Enum.zip([[:a, :b], [1, 2], ["foo", "bar"]]) == [{:a, 1, "foo"}, {:b, 2, "bar"}] From f040f1c76d07d1d5894b709c3827af955db477dd Mon Sep 17 00:00:00 2001 From: sabiwara Date: Sun, 2 Mar 2025 09:38:52 +0900 Subject: [PATCH 2/2] Add test for cycling over empty enumerable --- lib/elixir/test/elixir/stream_test.exs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/elixir/test/elixir/stream_test.exs b/lib/elixir/test/elixir/stream_test.exs index 47de51beb2a..e78ff7cd83f 100644 --- a/lib/elixir/test/elixir/stream_test.exs +++ b/lib/elixir/test/elixir/stream_test.exs @@ -245,6 +245,10 @@ defmodule StreamTest do Stream.cycle(%{}) |> Enum.to_list() end + assert_raise ArgumentError, "cannot cycle over an empty enumerable", fn -> + Stream.cycle(..) |> Enum.to_list() + end + assert Stream.cycle([1, 2, 3]) |> Stream.take(5) |> Enum.to_list() == [1, 2, 3, 1, 2] assert Enum.take(stream, 5) == [1, 2, 3, 1, 2] end