summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSasha Fonseca <sashaafm@users.noreply.github.com>2022-01-05 14:17:50 +0000
committerGitHub <noreply@github.com>2022-01-05 15:17:50 +0100
commit27b53b8be584f9c0d3201b5b21ec872d55778227 (patch)
treeef8af910d3dec8d359f75dfdefd9e373a3018659
parent2474c1dddff6f2e66f16caff6f9792352b29276c (diff)
downloadelixir-27b53b8be584f9c0d3201b5b21ec872d55778227.tar.gz
Raise ArgumentError when defdelegating points to the delegating module (#11545)
-rw-r--r--lib/elixir/lib/kernel.ex7
-rw-r--r--lib/elixir/test/elixir/kernel_test.exs10
2 files changed, 17 insertions, 0 deletions
diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex
index b9af22f89..47c58565a 100644
--- a/lib/elixir/lib/kernel.ex
+++ b/lib/elixir/lib/kernel.ex
@@ -5562,6 +5562,13 @@ defmodule Kernel do
target =
Keyword.get(opts, :to) || raise ArgumentError, "expected to: to be given as argument"
+ as = Keyword.get(opts, :as)
+
+ if target == __MODULE__ and is_nil(as) do
+ raise ArgumentError,
+ "defdelegate function is calling itself, which will lead to an infinite loop. You should either change the value of the :to option or specify the :as option"
+ end
+
if is_list(funs) do
IO.warn(
"passing a list to Kernel.defdelegate/2 is deprecated, please define each delegate separately",
diff --git a/lib/elixir/test/elixir/kernel_test.exs b/lib/elixir/test/elixir/kernel_test.exs
index 01760982e..9ce715846 100644
--- a/lib/elixir/test/elixir/kernel_test.exs
+++ b/lib/elixir/test/elixir/kernel_test.exs
@@ -896,6 +896,16 @@ defmodule KernelTest do
end
end
+ test "raises when :to targeting the delegating module is given without the :as option" do
+ assert_raise ArgumentError,
+ ~r/defdelegate function is calling itself, which will lead to an infinite loop. You should either change the value of the :to option or specify the :as option/,
+ fn ->
+ defmodule ImplAttributes do
+ defdelegate foo(), to: __MODULE__
+ end
+ end
+ end
+
defdelegate my_reverse(list \\ []), to: :lists, as: :reverse
defdelegate my_get(map \\ %{}, key, default \\ ""), to: Map, as: :get