diff options
author | Sasha Fonseca <sashaafm@users.noreply.github.com> | 2022-01-05 14:17:50 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-05 15:17:50 +0100 |
commit | 27b53b8be584f9c0d3201b5b21ec872d55778227 (patch) | |
tree | ef8af910d3dec8d359f75dfdefd9e373a3018659 | |
parent | 2474c1dddff6f2e66f16caff6f9792352b29276c (diff) | |
download | elixir-27b53b8be584f9c0d3201b5b21ec872d55778227.tar.gz |
Raise ArgumentError when defdelegating points to the delegating module (#11545)
-rw-r--r-- | lib/elixir/lib/kernel.ex | 7 | ||||
-rw-r--r-- | lib/elixir/test/elixir/kernel_test.exs | 10 |
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 |