Skip to content

Commit aee5dc2

Browse files
jcabotcJosé Valim
authored andcommitted
Fix protocols diff calculation between compilations (#6339)
1 parent 4092c83 commit aee5dc2

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

lib/mix/lib/mix/tasks/compile.protocols.ex

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,20 @@ defmodule Mix.Tasks.Compile.Protocols do
193193
Map.put(protocols, protocol, true)
194194
end)
195195

196+
removed_metadata =
197+
old_metadata -- new_metadata
198+
199+
removed_protocols =
200+
for {protocol, :protocol, _beam} <- removed_metadata,
201+
remove_consolidated(protocol, output),
202+
do: {protocol, true},
203+
into: %{}
204+
196205
protocols =
197-
Enum.reduce(old_metadata -- new_metadata, protocols, fn
198-
{_, {:impl, protocol}, _beam}, protocols ->
199-
Map.put(protocols, protocol, true)
200-
{protocol, :protocol, _beam}, protocols ->
201-
remove_consolidated(protocol, output)
202-
protocols
203-
end)
206+
for {_, {:impl, protocol}, _beam} <- removed_metadata,
207+
not Map.has_key?(removed_protocols, protocol),
208+
do: {protocol, true},
209+
into: protocols
204210

205211
Map.keys(protocols)
206212
end

lib/mix/test/mix/tasks/compile.protocols_test.exs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,41 @@ defmodule Mix.Tasks.Compile.ProtocolsTest do
4242
end
4343
end
4444

45+
test "compiles after converting a protocol into a standard module", context do
46+
Mix.Project.push MixTest.Case.Sample
47+
48+
in_tmp context.test, fn ->
49+
File.mkdir_p!("lib")
50+
assert Mix.Task.run("compile")
51+
52+
# Define a local protocol
53+
File.write!("lib/protocol.ex", """
54+
defprotocol Compile.Protocol do
55+
def foo(a)
56+
end
57+
58+
defimpl Compile.Protocol, for: Integer do
59+
def foo(a), do: a
60+
end
61+
""")
62+
assert compile_elixir_and_protocols() == :ok
63+
mark_as_old!("_build/dev/lib/sample/consolidated/Elixir.Compile.Protocol.beam")
64+
File.rm!("lib/protocol.ex")
65+
66+
# Define a standard module
67+
File.write!("lib/protocol.ex", """
68+
defmodule Compile.Protocol do
69+
end
70+
""")
71+
assert compile_elixir_and_protocols() == :noop
72+
73+
# Delete a local protocol
74+
File.rm!("lib/protocol.ex")
75+
assert compile_elixir_and_protocols() == :noop
76+
refute File.regular?("_build/dev/lib/sample/consolidated/Elixir.Compile.Protocol.beam")
77+
end
78+
end
79+
4580
test "compiles and consolidates deps protocols", context do
4681
Mix.Project.push MixTest.Case.Sample
4782

0 commit comments

Comments
 (0)