Skip to content

Commit 8fca53a

Browse files
committed
Ensure deprecated macros emit warnings
1 parent 76dfedb commit 8fca53a

File tree

3 files changed

+39
-9
lines changed

3 files changed

+39
-9
lines changed

lib/elixir/lib/macro/env.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ defmodule Macro.Env do
105105
vars: vars
106106
}
107107

108+
# Define the __struct__ callbacks by hand for bootstrap reasons.
108109
# TODO: Remove :vars field on v2.0
110+
@doc false
109111
def __struct__ do
110112
%{
111113
__struct__: __MODULE__,
@@ -130,6 +132,7 @@ defmodule Macro.Env do
130132
}
131133
end
132134

135+
@doc false
133136
def __struct__(kv) do
134137
Enum.reduce(kv, __struct__(), fn {k, v}, acc -> :maps.update(k, v, acc) end)
135138
end

lib/elixir/src/elixir_dispatch.erl

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ require_function(Meta, Receiver, Name, Arity, E) ->
7777
end.
7878

7979
remote_function(Meta, Receiver, Name, Arity, E) ->
80-
check_deprecated(Meta, Receiver, Name, Arity, E),
80+
check_deprecated(Meta, function, Receiver, Name, Arity, E),
8181

8282
case elixir_rewrite:inline(Receiver, Name, Arity) of
8383
{AR, AN} -> {remote, AR, AN, Arity};
@@ -161,7 +161,7 @@ do_expand_import(Meta, {Name, Arity} = Tuple, Args, Module, E, Result) ->
161161
elixir_locals:record_import(Tuple, Receiver, Module, ?key(E, function)),
162162
{ok, Receiver, Name, Args};
163163
{macro, Receiver} ->
164-
check_deprecated(Meta, Receiver, Name, Arity, E),
164+
check_deprecated(Meta, macro, Receiver, Name, Arity, E),
165165
elixir_env:trace({imported_macro, Meta, Receiver, Name, Arity}, E),
166166
elixir_locals:record_import(Tuple, Receiver, Module, ?key(E, function)),
167167
{ok, Receiver, expand_macro_named(Meta, Receiver, Name, Arity, Args, E)};
@@ -180,17 +180,18 @@ do_expand_import(Meta, {Name, Arity} = Tuple, Args, Module, E, Result) ->
180180
end.
181181

182182
expand_require(Meta, Receiver, {Name, Arity} = Tuple, Args, E) ->
183-
check_deprecated(Meta, Receiver, Name, Arity, E),
184183
Required = (Receiver == ?key(E, module)) orelse required(Meta) orelse is_element(Receiver, ?key(E, requires)),
185184

186185
case is_element(Tuple, get_macros(Receiver, Required)) of
187186
true when Required ->
187+
check_deprecated(Meta, macro, Receiver, Name, Arity, E),
188188
elixir_env:trace({remote_macro, Meta, Receiver, Name, Arity}, E),
189189
{ok, Receiver, expand_macro_named(Meta, Receiver, Name, Arity, Args, E)};
190190
true ->
191191
Info = {unrequired_module, {Receiver, Name, length(Args)}},
192192
elixir_errors:form_error(Meta, E, ?MODULE, Info);
193193
false ->
194+
check_deprecated(Meta, function, Receiver, Name, Arity, E),
194195
error
195196
end.
196197

@@ -361,12 +362,13 @@ elixir_imported_macros() ->
361362
error:undef -> []
362363
end.
363364

364-
check_deprecated(_, erlang, _, _, _) ->
365-
ok;
366-
check_deprecated(_, ?kernel, _, _, _) ->
367-
ok;
368-
check_deprecated(Meta, Receiver, Name, Arity, E) ->
369-
case (?key(E, function) == nil) andalso get_deprecations(Receiver) of
365+
check_deprecated(_, _, erlang, _, _, _) -> ok;
366+
check_deprecated(_, _, elixir_def, _, _, _) -> ok;
367+
check_deprecated(_, _, elixir_module, _, _, _) -> ok;
368+
check_deprecated(_, _, ?kernel, _, _, _) -> ok;
369+
check_deprecated(Meta, Kind, Receiver, Name, Arity, E) ->
370+
%% Any compile time behaviour cannot be verified by the runtime group pass.
371+
case ((?key(E, function) == nil) or (Kind == macro)) andalso get_deprecations(Receiver) of
370372
[_ | _] = Deprecations ->
371373
case lists:keyfind({Name, Arity}, 1, Deprecations) of
372374
{_, Message} ->

lib/elixir/test/elixir/module/types/integration_test.exs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,31 @@ defmodule Module.Types.IntegrationTest do
663663

664664
assert_warnings(files, warning)
665665
end
666+
667+
test "reports macro" do
668+
files = %{
669+
"a.ex" => """
670+
defmodule A do
671+
@deprecated "oops"
672+
defmacro a, do: :ok
673+
end
674+
""",
675+
"b.ex" => """
676+
defmodule B do
677+
require A
678+
def b, do: A.a()
679+
end
680+
"""
681+
}
682+
683+
warning = """
684+
warning: A.a/0 is deprecated. oops
685+
b.ex:3: B.b/0
686+
687+
"""
688+
689+
assert_warnings(files, warning)
690+
end
666691
end
667692

668693
defp assert_warnings(files, expected) when is_binary(expected) do

0 commit comments

Comments
 (0)