Skip to content

Commit bba5542

Browse files
committed
Do not warn on conditional requires or requires from quote
1 parent c9b529a commit bba5542

File tree

11 files changed

+63
-59
lines changed

11 files changed

+63
-59
lines changed

lib/elixir/lib/code.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ defmodule Code do
604604
all imports, requires and aliases defined in the current environment
605605
will be automatically carried over:
606606
607-
iex> require Integer
607+
iex> require Integer, warn: false
608608
iex> {result, binding} = Code.eval_string("if Integer.is_odd(a), do: a + b", [a: 1, b: 2], __ENV__)
609609
iex> result
610610
3

lib/elixir/lib/kernel/lexical_tracker.ex

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ defmodule Kernel.LexicalTracker do
2121
:gen_server.call(pid, :references, @timeout)
2222
end
2323

24+
@doc """
25+
Invoked during module expansion to annotate a require
26+
must be warned if unused.
27+
"""
28+
def warn_require(pid, meta, module) do
29+
:gen_server.cast(pid, {:warn_require, module, meta})
30+
module
31+
end
32+
2433
@doc """
2534
Invoked during module expansion to annotate an alias
2635
must be warned if unused.
@@ -163,9 +172,7 @@ defmodule Kernel.LexicalTracker do
163172

164173
def handle_call(:unused_requires, _from, state) do
165174
unused_requires =
166-
for {module, meta} <- state.requires,
167-
Map.get(state.references, module) != :compile,
168-
Keyword.get(meta[:opts], :warn, true) != false do
175+
for {module, meta} <- state.requires, Map.get(state.references, module) != :compile do
169176
{module, meta}
170177
end
171178

@@ -267,7 +274,7 @@ defmodule Kernel.LexicalTracker do
267274
{:noreply, put_in(state.imports[module][@warn_key], true)}
268275
end
269276

270-
def handle_cast({:add_require, module, meta}, state) do
277+
def handle_cast({:warn_require, module, meta}, state) do
271278
{:noreply, put_in(state.requires[module], meta)}
272279
end
273280

lib/elixir/lib/macro/env.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ defmodule Macro.Env do
300300
301301
iex> Macro.Env.required?(__ENV__, Integer)
302302
false
303-
iex> require Integer
303+
iex> require Integer, warn: false
304304
iex> Macro.Env.required?(__ENV__, Integer)
305305
true
306306

lib/elixir/lib/protocol.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ defmodule Protocol do
10321032
# expression (and therefore most likely a compile-time one).
10331033
behaviour =
10341034
if is_atom(protocol) do
1035-
quote(do: require(unquote(protocol), warn: false))
1035+
quote(do: require(unquote(protocol)))
10361036
else
10371037
quote(do: protocol)
10381038
end

lib/elixir/src/elixir_expand.erl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,20 @@ expand({require, Meta, [Ref, Opts]}, S, E) ->
121121
elixir_aliases:ensure_loaded(Meta, ERef, ET),
122122
RE = elixir_aliases:require(Meta, ERef, EOpts, ET, true),
123123
{ok, _, EU} = alias(Meta, ERef, false, EOpts, RE),
124-
{ERef, ST, EU};
124+
125+
Quoted =
126+
case should_warn(Meta, EOpts, EU) of
127+
false ->
128+
ERef;
129+
130+
Pid when ?key(EU, function) /= nil ->
131+
?tracker:warn_require(Pid, Meta, ERef);
132+
133+
Pid ->
134+
{{'.', Meta, [?tracker, warn_require]}, Meta, [Pid, Meta, ERef]}
135+
end,
136+
137+
{Quoted, ST, EU};
125138

126139
false ->
127140
file_error(Meta, E, ?MODULE, {expected_compile_time_module, require, Ref})

lib/elixir/src/elixir_lexical.erl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ run(#{tracers := Tracers} = E, ExecutionCallback, AfterExecutionCallback) ->
3434
trace({alias_expansion, _Meta, Lookup, _Result}, #{lexical_tracker := Pid}) ->
3535
?tracker:alias_dispatch(Pid, Lookup),
3636
ok;
37-
trace({require, Meta, Module, Opts}, #{lexical_tracker := Pid, module := CurrentModule}) ->
37+
trace({require, Meta, Module, _Opts}, #{lexical_tracker := Pid}) ->
3838
case lists:keyfind(from_macro, 1, Meta) of
3939
{from_macro, true} -> ?tracker:remote_dispatch(Pid, Module, compile);
40-
_ ->
41-
?tracker:add_export(Pid, Module),
42-
?tracker:add_require(Pid, Module, [{module, CurrentModule}, {opts, Opts} | Meta])
40+
_ -> ?tracker:add_export(Pid, Module)
4341
end,
4442
ok;
4543
trace({struct_expansion, _Meta, Module, _Keys}, #{lexical_tracker := Pid}) ->

lib/elixir/test/elixir/kernel/lexical_tracker_test.exs

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -91,56 +91,22 @@ defmodule Kernel.LexicalTrackerTest do
9191
assert D.collect_unused_imports(config[:pid]) == [{String, %{}}]
9292
end
9393

94-
test "unused requires", config do
95-
D.add_require(config[:pid], String, module: TestModule, opts: [])
96-
assert D.collect_unused_requires(config[:pid]) == [{String, [module: TestModule, opts: []]}]
97-
end
98-
99-
test "used requires are not unused", config do
100-
D.add_require(config[:pid], String, module: TestModule, opts: [])
101-
D.remote_dispatch(config[:pid], String, :compile)
102-
assert D.collect_unused_requires(config[:pid]) == []
103-
end
104-
105-
test "requires with warn: false are not unused", config do
106-
D.add_require(config[:pid], String, module: TestModule, opts: [warn: false])
107-
assert D.collect_unused_requires(config[:pid]) == []
108-
end
109-
110-
test "requires with warn: true are unused when not referenced", config do
111-
D.add_require(config[:pid], String, module: TestModule, opts: [warn: true])
112-
113-
assert D.collect_unused_requires(config[:pid]) == [
114-
{String, [module: TestModule, opts: [warn: true]]}
115-
]
116-
end
117-
118-
test "multiple unused requires", config do
119-
D.add_require(config[:pid], String, module: TestModule, opts: [])
120-
D.add_require(config[:pid], List, module: TestModule, opts: [])
121-
122-
assert D.collect_unused_requires(config[:pid]) == [
123-
{List, [module: TestModule, opts: []]},
124-
{String, [module: TestModule, opts: []]}
125-
]
94+
test "imports with no warn are not unused", config do
95+
D.add_import(config[:pid], String, [], 1, false)
96+
assert D.collect_unused_imports(config[:pid]) == []
12697
end
12798

128-
test "mixed used and unused requires", config do
129-
D.add_require(config[:pid], String, module: TestModule, opts: [])
130-
D.add_require(config[:pid], List, module: TestModule, opts: [])
99+
test "unused requires", config do
100+
D.warn_require(config[:pid], [], String)
101+
D.warn_require(config[:pid], [], List)
131102
D.remote_dispatch(config[:pid], String, :compile)
132-
assert D.collect_unused_requires(config[:pid]) == [{List, [module: TestModule, opts: []]}]
103+
assert D.collect_unused_requires(config[:pid]) == [{List, []}]
133104
end
134105

135106
test "function calls do not count as macro usage", config do
136-
D.add_require(config[:pid], String, module: TestModule, opts: [])
107+
D.warn_require(config[:pid], [], String)
137108
D.remote_dispatch(config[:pid], String, :runtime)
138-
assert D.collect_unused_requires(config[:pid]) == [{String, [module: TestModule, opts: []]}]
139-
end
140-
141-
test "imports with no warn are not unused", config do
142-
D.add_import(config[:pid], String, [], 1, false)
143-
assert D.collect_unused_imports(config[:pid]) == []
109+
assert D.collect_unused_requires(config[:pid]) == [{String, []}]
144110
end
145111

146112
test "unused aliases", config do

lib/elixir/test/elixir/kernel/macros_test.exs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,22 @@ defmodule Kernel.MacrosTest.Nested do
1010
defmacro do_identity!(do: x) do
1111
x
1212
end
13+
14+
defmacro unused_require do
15+
quote do
16+
require Integer
17+
end
18+
end
1319
end
1420

1521
defmodule Kernel.MacrosTest do
1622
use ExUnit.Case, async: true
1723

1824
Kernel.MacrosTest.Nested = require Kernel.MacrosTest.Nested, as: Nested
1925

26+
# Unused require from macro should not warn
27+
Kernel.MacrosTest.Nested.unused_require()
28+
2029
@spec my_macro :: Macro.t()
2130
defmacro my_macro do
2231
quote(do: 1 + 1)

lib/elixir/test/elixir/kernel/warning_test.exs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,7 +2274,7 @@ defmodule Kernel.WarningTest do
22742274
["nofile:2:3", "unused require Application"],
22752275
"""
22762276
defmodule Sample do
2277-
require Application
2277+
require Application
22782278
def a, do: nil
22792279
end
22802280
"""
@@ -2283,13 +2283,26 @@ defmodule Kernel.WarningTest do
22832283
assert_warn_compile(
22842284
["nofile:1:1", "unused require Logger"],
22852285
"""
2286-
require Logger
2286+
require Logger
22872287
"""
22882288
)
22892289
after
22902290
purge(Sample)
22912291
end
22922292

2293+
test "conditional require" do
2294+
assert capture_err(fn ->
2295+
defmodule KernelTest.ConditionalRequire do
2296+
if false do
2297+
require Integer
2298+
def fun(x), do: Integer.is_odd(x)
2299+
end
2300+
end
2301+
end) == ""
2302+
after
2303+
purge(Sample)
2304+
end
2305+
22932306
defp purge(module) when is_atom(module) do
22942307
:code.purge(module)
22952308
:code.delete(module)

lib/logger/lib/logger/app.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
defmodule Logger.App do
66
@moduledoc false
77

8-
require Logger
98
use Application
109

1110
@doc false

0 commit comments

Comments
 (0)