@@ -173,7 +173,7 @@ defmodule Mix.Compilers.Elixir do
173173 compiler_loop ( stale , stale_modules , dest , timestamp , opts , state )
174174 else
175175 { :ok , info , state } ->
176- { modules , _exports , sources , pending_modules , _pending_exports } = state
176+ { modules , _exports , sources , pending_modules , _stale_exports } = state
177177
178178 previous_warnings =
179179 if Keyword . get ( opts , :all_warnings , true ) ,
@@ -531,7 +531,7 @@ defmodule Mix.Compilers.Elixir do
531531
532532 defp remove_stale_entry ( entry , acc , sources , stale_exports , compile_path ) do
533533 module ( module: module , sources: source_files , export: export ) = entry
534- { rest , exports , changed , stale } = acc
534+ { rest , exports , changed , stale_modules } = acc
535535
536536 { compile_references , export_references , runtime_references } =
537537 Enum . reduce ( source_files , { [ ] , [ ] , [ ] } , fn file , { compile_acc , export_acc , runtime_acc } ->
@@ -548,20 +548,20 @@ defmodule Mix.Compilers.Elixir do
548548 # If I changed in disk or have a compile time reference to
549549 # something stale or have a reference to an old export,
550550 # I need to be recompiled.
551- has_any_key? ( changed , source_files ) or has_any_key? ( stale , compile_references ) or
551+ has_any_key? ( changed , source_files ) or has_any_key? ( stale_modules , compile_references ) or
552552 has_any_key? ( stale_exports , export_references ) ->
553553 remove_and_purge ( beam_path ( compile_path , module ) , module )
554554 changed = Enum . reduce ( source_files , changed , & Map . put ( & 2 , & 1 , true ) )
555- { rest , Map . put ( exports , module , export ) , changed , Map . put ( stale , module , true ) }
555+ { rest , Map . put ( exports , module , export ) , changed , Map . put ( stale_modules , module , true ) }
556556
557557 # If I have a runtime references to something stale,
558558 # I am stale too.
559- has_any_key? ( stale , runtime_references ) ->
560- { [ entry | rest ] , exports , changed , Map . put ( stale , module , true ) }
559+ has_any_key? ( stale_modules , runtime_references ) ->
560+ { [ entry | rest ] , exports , changed , Map . put ( stale_modules , module , true ) }
561561
562562 # Otherwise, we don't store it anywhere
563563 true ->
564- { [ entry | rest ] , exports , changed , stale }
564+ { [ entry | rest ] , exports , changed , stale_modules }
565565 end
566566 end
567567
@@ -1032,11 +1032,29 @@ defmodule Mix.Compilers.Elixir do
10321032 end
10331033 end
10341034
1035- defp each_cycle ( stale_modules , compile_path , timestamp , state ) do
1036- { modules , _exports , sources , pending_modules , pending_exports } = state
1035+ defp each_cycle ( runtime_modules , compile_path , timestamp , state ) do
1036+ { modules , _exports , sources , pending_modules , stale_exports } = state
1037+
1038+ stale_modules =
1039+ modules
1040+ |> Enum . map ( & module ( & 1 , :module ) )
1041+ |> Map . from_keys ( true )
1042+
1043+ # Because a module may be accidentally overridden in another file,
1044+ # we need to mark any pending module that has been defined as changed.
1045+ { pending_modules , changed } =
1046+ Enum . reduce ( pending_modules , { [ ] , [ ] } , fn module , { pending_acc , changed_acc } ->
1047+ if is_map_key ( stale_modules , module ( module , :module ) ) do
1048+ { pending_acc , module ( module , :sources ) ++ changed_acc }
1049+ else
1050+ { [ module | pending_acc ] , changed_acc }
1051+ end
1052+ end )
10371053
1054+ # We don't need to pass stale_modules here because
1055+ # runtime dependencies have already been marked as stale.
10381056 { pending_modules , exports , changed } =
1039- update_stale_entries ( pending_modules , sources , [ ] , % { } , pending_exports , compile_path )
1057+ update_stale_entries ( pending_modules , sources , changed , % { } , stale_exports , compile_path )
10401058
10411059 # For each changed file, mark it as changed.
10421060 # If compilation fails mid-cycle, they will be picked next time around.
@@ -1045,18 +1063,13 @@ defmodule Mix.Compilers.Elixir do
10451063 end
10461064
10471065 if changed == [ ] do
1048- stale_modules =
1049- modules
1050- |> Enum . map ( & module ( & 1 , :module ) )
1051- |> Map . from_keys ( true )
1052- |> Map . merge ( stale_modules )
1053-
1054- { _ , runtime_modules , sources } = fixpoint_runtime_modules ( sources , stale_modules )
1066+ { _ , runtime_modules , sources } =
1067+ fixpoint_runtime_modules ( sources , Map . merge ( stale_modules , runtime_modules ) )
10551068
10561069 runtime_paths =
10571070 Enum . map ( runtime_modules , & { & 1 , Path . join ( compile_path , Atom . to_string ( & 1 ) <> ".beam" ) } )
10581071
1059- state = { modules , exports , sources , pending_modules , pending_exports }
1072+ state = { modules , exports , sources , pending_modules , stale_exports }
10601073 { { :runtime , runtime_paths , [ ] } , state }
10611074 else
10621075 Mix.Utils . compiling_n ( length ( changed ) , :ex )
@@ -1085,7 +1098,7 @@ defmodule Mix.Compilers.Elixir do
10851098
10861099 defp each_file ( file , references , verbose , state , cwd ) do
10871100 { compile_references , export_references , runtime_references , compile_env } = references
1088- { modules , exports , sources , pending_modules , pending_exports } = state
1101+ { modules , exports , sources , pending_modules , stale_exports } = state
10891102
10901103 file = Path . relative_to ( file , cwd )
10911104
@@ -1114,22 +1127,22 @@ defmodule Mix.Compilers.Elixir do
11141127 compile_env: compile_env
11151128 )
11161129
1117- { modules , exports , [ source | sources ] , pending_modules , pending_exports }
1130+ { modules , exports , [ source | sources ] , pending_modules , stale_exports }
11181131 end
11191132
11201133 defp each_module ( file , module , kind , external , new_export , state , timestamp , cwd ) do
1121- { modules , exports , sources , pending_modules , pending_exports } = state
1134+ { modules , exports , sources , pending_modules , stale_exports } = state
11221135
11231136 file = Path . relative_to ( file , cwd )
11241137 external = process_external_resources ( external , cwd )
11251138
11261139 old_export = Map . get ( exports , module )
11271140
1128- pending_exports =
1141+ stale_exports =
11291142 if old_export && old_export != new_export do
1130- pending_exports
1143+ stale_exports
11311144 else
1132- Map . delete ( pending_exports , module )
1145+ Map . delete ( stale_exports , module )
11331146 end
11341147
11351148 { module_sources , existing_module? } =
@@ -1163,7 +1176,7 @@ defmodule Mix.Compilers.Elixir do
11631176 )
11641177
11651178 modules = prepend_or_merge ( modules , module , module ( :module ) , module , existing_module? )
1166- { modules , exports , [ source | sources ] , pending_modules , pending_exports }
1179+ { modules , exports , [ source | sources ] , pending_modules , stale_exports }
11671180 end
11681181
11691182 defp prepend_or_merge ( collection , key , pos , value , true ) do
0 commit comments