Skip to content

Commit 759457e

Browse files
ggcampinhoJosé Valim
authored andcommitted
Fix @impl attribute for default arguments (#6595)
`Module.compile_impl/6` was ignoring the default attributes when compiling the impl, now it checks the count of default attributes and adds an impl for each one. Fixes #6550
1 parent bfa894a commit 759457e

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

lib/elixir/lib/module.ex

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,15 +1192,28 @@ defmodule Module do
11921192
case :ets.take(table, :impl) do
11931193
[{:impl, value, _, _}] ->
11941194
impls = :ets.lookup_element(table, {:elixir, :impls}, 2)
1195-
impl = {{name, length(args)}, kind, line, file, value}
1196-
:ets.insert(table, {{:elixir, :impls}, [impl | impls]})
1195+
{total, defaults} = args_count(args, 0, 0)
1196+
1197+
impl = for arity <- total..(total - defaults), into: impls do
1198+
{{name, arity}, kind, line, file, value}
1199+
end
1200+
1201+
:ets.insert(table, {{:elixir, :impls}, impl})
11971202
[] ->
11981203
:ok
11991204
end
12001205

12011206
:ok
12021207
end
12031208

1209+
defp args_count([{:\\, _, _} | tail], total, defaults) do
1210+
args_count(tail, total + 1, defaults + 1)
1211+
end
1212+
defp args_count([_head | tail], total, defaults) do
1213+
args_count(tail, total + 1, defaults)
1214+
end
1215+
defp args_count([], total, defaults), do: {total, defaults}
1216+
12041217
@doc false
12051218
def check_behaviours_and_impls(env, table, all_definitions, overridable_pairs) do
12061219
behaviours = :ets.lookup_element(table, :behaviour, 2)

lib/elixir/test/elixir/kernel/impl_test.exs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ defmodule Kernel.ImplTest do
1717
end
1818

1919
defmodule Behaviour do
20-
@callback foo :: any
20+
@callback foo() :: any
21+
end
22+
23+
defmodule BehaviourWithArgument do
24+
@callback foo(any) :: any
2125
end
2226

2327
defmodule MacroBehaviour do
@@ -285,6 +289,20 @@ defmodule Kernel.ImplTest do
285289
end) =~ "got @impl Kernel.ImplTest.MacroBehaviour for def bar/0 but the given behaviour was not declared with @behaviour"
286290
end
287291

292+
test "does not warn for @impl when using default arguments" do
293+
assert capture_err(fn ->
294+
Code.eval_string ~S"""
295+
defmodule Kernel.ImplTest.ImplAttributes do
296+
@behaviour Kernel.ImplTest.Behaviour
297+
@behaviour Kernel.ImplTest.BehaviourWithArgument
298+
299+
@impl true
300+
def foo(args \\ []), do: args
301+
end
302+
"""
303+
end) == ""
304+
end
305+
288306
test "does not warn for no @impl when overriding callback" do
289307
assert capture_err(fn ->
290308
Code.eval_string """

0 commit comments

Comments
 (0)