From 8493f1934a820d9ccbe9c6fc4ad74a6d8c3c2ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 3 Mar 2025 12:54:49 +0100 Subject: [PATCH] Do not raise when Stream.cycle is explicitly halted, closes #14307 --- 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 495edcf12bd..a69e7f5d3b9 100644 --- a/lib/elixir/lib/stream.ex +++ b/lib/elixir/lib/stream.ex @@ -1444,7 +1444,7 @@ defmodule Stream do defp check_cycle_first_element(reduce) do fn acc -> case reduce.(acc) do - {state, []} when state in [:done, :halted] -> + {state, []} when state in [:done, :halted] and elem(acc, 0) != :halt -> 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 483849c4f22..e19c21381bf 100644 --- a/lib/elixir/test/elixir/enum_test.exs +++ b/lib/elixir/test/elixir/enum_test.exs @@ -1517,6 +1517,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"}]