Skip to content

Commit 8930ea7

Browse files
author
José Valim
committed
Do not attempt to load modules that have not been required, closes #4900
1 parent 01a1acd commit 8930ea7

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

lib/elixir/src/elixir_dispatch.erl

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ import_function(Meta, Name, Arity, E) ->
6060
end.
6161

6262
require_function(Meta, Receiver, Name, Arity, E) ->
63-
case is_element({Name, Arity}, get_optional_macros(Receiver)) of
63+
Required = is_element(Receiver, ?m(E, requires)),
64+
case is_element({Name, Arity}, get_macros(Receiver, Required)) of
6465
true -> false;
6566
false ->
6667
elixir_lexical:record_remote(Receiver, ?m(E, function), ?m(E, lexical_tracker)),
@@ -146,7 +147,7 @@ do_expand_import(Meta, {Name, Arity} = Tuple, Args, Module, E, Result) ->
146147
elixir_locals:record_import(Tuple, Receiver, Module, ?m(E, function)),
147148
{ok, Receiver, expand_macro_named(Meta, Receiver, Name, Arity, Args, E)};
148149
{import, Receiver} ->
149-
case expand_require([{require, false} | Meta], Receiver, Tuple, Args, E) of
150+
case expand_require([{required, true} | Meta], Receiver, Tuple, Args, E) of
150151
{ok, _, _} = Response -> Response;
151152
error -> {ok, Receiver, Name, Args}
152153
end;
@@ -161,19 +162,15 @@ do_expand_import(Meta, {Name, Arity} = Tuple, Args, Module, E, Result) ->
161162

162163
expand_require(Meta, Receiver, {Name, Arity} = Tuple, Args, E) ->
163164
check_deprecation(Meta, Receiver, Name, Arity, E),
164-
Module = ?m(E, module),
165+
Required = (Receiver == ?m(E, module)) orelse is_element(Receiver, ?m(E, requires)) orelse required(Meta),
165166

166-
case is_element(Tuple, get_optional_macros(Receiver)) of
167+
case is_element(Tuple, get_macros(Receiver, Required)) of
168+
true when Required ->
169+
elixir_lexical:record_remote(Receiver, Name, Arity, nil, ?line(Meta), ?m(E, lexical_tracker)),
170+
{ok, Receiver, expand_macro_named(Meta, Receiver, Name, Arity, Args, E)};
167171
true ->
168-
Requires = ?m(E, requires),
169-
case (Receiver == Module) orelse is_element(Receiver, Requires) orelse skip_require(Meta) of
170-
true ->
171-
elixir_lexical:record_remote(Receiver, Name, Arity, nil, ?line(Meta), ?m(E, lexical_tracker)),
172-
{ok, Receiver, expand_macro_named(Meta, Receiver, Name, Arity, Args, E)};
173-
false ->
174-
Info = {unrequired_module, {Receiver, Name, length(Args), Requires}},
175-
elixir_errors:form_error(Meta, ?m(E, file), ?MODULE, Info)
176-
end;
172+
Info = {unrequired_module, {Receiver, Name, length(Args), ?m(E, requires)}},
173+
elixir_errors:form_error(Meta, ?m(E, file), ?MODULE, Info);
177174
false ->
178175
error
179176
end.
@@ -220,8 +217,8 @@ caller(Line, E) ->
220217

221218
%% Helpers
222219

223-
skip_require(Meta) ->
224-
lists:keyfind(require, 1, Meta) == {require, false}.
220+
required(Meta) ->
221+
lists:keyfind(required, 1, Meta) == {required, true}.
225222

226223
find_dispatch(Meta, Tuple, Extra, E) ->
227224
case is_import(Meta) of
@@ -289,9 +286,20 @@ format_error({ambiguous_call, {Mod1, Mod2, Name, Arity}}) ->
289286
%% INTROSPECTION
290287

291288
%% Do not try to get macros from Erlang. Speeds up compilation a bit.
292-
get_optional_macros(erlang) -> [];
289+
get_macros(erlang, _) -> [];
290+
291+
get_macros(Receiver, false) ->
292+
case code:is_loaded(Receiver) of
293+
{file, _} ->
294+
try
295+
Receiver:'__info__'(macros)
296+
catch
297+
error:undef -> []
298+
end;
299+
false -> []
300+
end;
293301

294-
get_optional_macros(Receiver) ->
302+
get_macros(Receiver, true) ->
295303
case code:ensure_loaded(Receiver) of
296304
{module, Receiver} ->
297305
try

lib/elixir/src/elixir_module.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ add_beam_chunk(Bin, Id, ChunkData)
525525
%% the callback can't be expanded, invokes the given
526526
%% fun passing a possibly expanded AM:AF(Args).
527527
expand_callback(Line, M, F, Args, E, Fun) ->
528-
Meta = [{line, Line}, {require, false}],
528+
Meta = [{line, Line}, {required, true}],
529529

530530
{EE, ET} = elixir_dispatch:dispatch_require(Meta, M, F, Args, E, fun(AM, AF, AA) ->
531531
Fun(AM, AF, AA),

0 commit comments

Comments
 (0)