Skip to content

Commit 0ded67d

Browse files
uesteibarJosé Valim
authored andcommitted
Don't remove docs for previous function declaration on @impl true (#7383)
Signed-off-by: José Valim <[email protected]>
1 parent abbf173 commit 0ded67d

File tree

2 files changed

+48
-10
lines changed

2 files changed

+48
-10
lines changed

lib/elixir/lib/module.ex

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,8 @@ defmodule Module do
12101210
if kind in [:defp, :defmacrop, :typep] do
12111211
if doc, do: {:error, :private_doc}, else: :ok
12121212
else
1213-
compile_doc(data_table_for(module), line, kind, function_tuple, signature, doc, __ENV__)
1213+
table = data_table_for(module)
1214+
compile_doc(table, line, kind, function_tuple, signature, doc, __ENV__, false)
12141215
:ok
12151216
end
12161217
end
@@ -1229,13 +1230,13 @@ defmodule Module do
12291230
_since = compile_since(table)
12301231

12311232
# TODO: Store @since and @deprecated alongside the docs
1232-
{line, doc} = get_doc_info(table, env, impl)
1233-
compile_doc(table, line, kind, pair, args, doc, env)
1233+
{line, doc} = get_doc_info(table, env)
1234+
compile_doc(table, line, kind, pair, args, doc, env, impl)
12341235

12351236
:ok
12361237
end
12371238

1238-
defp compile_doc(_table, line, kind, {name, arity}, _args, doc, env)
1239+
defp compile_doc(_table, line, kind, {name, arity}, _args, doc, env, _impl)
12391240
when kind in [:defp, :defmacrop] do
12401241
if doc do
12411242
error_message =
@@ -1246,16 +1247,18 @@ defmodule Module do
12461247
end
12471248
end
12481249

1249-
defp compile_doc(table, line, kind, pair, args, doc, env) do
1250+
defp compile_doc(table, line, kind, pair, args, doc, env, impl) do
12501251
signature = build_signature(args, env)
12511252

12521253
case :ets.lookup(table, {:doc, pair}) do
12531254
[] ->
1255+
doc = if is_nil(doc) && impl, do: false, else: doc
12541256
:ets.insert(table, {{:doc, pair}, line, kind, signature, doc})
12551257

12561258
[{doc_tuple, line, _current_kind, current_sign, current_doc}] ->
12571259
signature = merge_signatures(current_sign, signature, 1)
12581260
doc = if is_nil(doc), do: current_doc, else: doc
1261+
doc = if is_nil(doc) && impl, do: false, else: doc
12591262
:ets.insert(table, {doc_tuple, line, kind, signature, doc})
12601263
end
12611264
end
@@ -1750,16 +1753,13 @@ defmodule Module do
17501753
value
17511754
end
17521755

1753-
defp get_doc_info(table, env, impl) do
1756+
defp get_doc_info(table, env) do
17541757
case :ets.take(table, :doc) do
17551758
[{:doc, {_, _} = pair, _, _}] ->
17561759
pair
17571760

1758-
[] when impl == false ->
1759-
{env.line, nil}
1760-
17611761
[] ->
1762-
{env.line, false}
1762+
{env.line, nil}
17631763
end
17641764
end
17651765

lib/elixir/test/elixir/kernel/docs_test.exs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,42 @@ defmodule Kernel.DocsTest do
211211
] = docs[:callback_docs]
212212
end
213213
end
214+
215+
test "@impl true doesn't set @doc false if previous implementation has docs" do
216+
write_beam(
217+
defmodule Docs do
218+
defmodule SampleBehaviour do
219+
@callback foo(any()) :: any()
220+
@callback bar() :: any()
221+
@callback baz() :: any()
222+
end
223+
224+
@behaviour SampleBehaviour
225+
226+
@doc "Foo docs"
227+
def foo(nil), do: nil
228+
229+
@impl true
230+
def foo(_), do: false
231+
232+
@impl true
233+
def bar(), do: true
234+
235+
@doc "Baz docs"
236+
@impl true
237+
def baz(), do: true
238+
239+
def fuz(), do: true
240+
end
241+
)
242+
243+
docs = Code.get_docs(Docs, :all)
244+
245+
assert [
246+
{{:bar, 0}, _, :def, [], false},
247+
{{:baz, 0}, _, :def, [], "Baz docs"},
248+
{{:foo, 1}, _, :def, [{:arg1, [], _}], "Foo docs"},
249+
{{:fuz, 0}, _, :def, [], nil}
250+
] = docs[:docs]
251+
end
214252
end

0 commit comments

Comments
 (0)