@@ -658,6 +658,20 @@ defmodule Mix.Compilers.Elixir do
658658 reduce: { stale_modules , stale_modules , deps_exports , protocols_and_impls ( ) } do
659659 { modules , exports , deps_exports , protocols_and_impls } ->
660660 { manifest_modules , manifest_sources } = read_manifest ( manifest )
661+ all_modules = Enum . map ( manifest_modules , fn { mod , _ } -> mod end )
662+ dep_exports = Map . get ( deps_exports , app , % { } )
663+
664+ # Update modules, exports, and dep exports based on removed modules
665+ { modules , exports , dep_exports } =
666+ Enum . reduce ( dep_exports , { modules , exports , dep_exports } , fn
667+ { mod , _ } , { modules , exports , dep_exports } ->
668+ if mod in all_modules do
669+ { modules , exports , dep_exports }
670+ else
671+ { Map . put ( modules , mod , true ) , Map . put ( exports , mod , true ) ,
672+ Map . delete ( dep_exports , mod ) }
673+ end
674+ end )
661675
662676 dep_modules =
663677 for { module , module ( timestamp: timestamp ) } <- manifest_modules ,
@@ -671,47 +685,32 @@ defmodule Mix.Compilers.Elixir do
671685 dep_modules =
672686 fixpoint_non_compile_modules ( manifest_sources , Map . from_keys ( dep_modules , true ) )
673687
674- old_exports = Map . get ( deps_exports , app , % { } )
675-
676- # Update exports
677- { exports , new_exports } =
678- for { module , _ } <- dep_modules , reduce: { exports , [ ] } do
679- { exports , new_exports } ->
680- export =
681- if Code . ensure_loaded? ( module ) and function_exported? ( module , :__info__ , 1 ) do
682- module . __info__ ( :exports_md5 )
683- end
684-
685- # If the exports are the same, then the API did not change,
686- # so we do not mark the export as stale. Note this has to
687- # be very conservative. If the module is not loaded or if
688- # the exports were not there, we need to consider it a stale
689- # export.
690- exports =
691- if export && old_exports [ module ] == export ,
692- do: exports ,
693- else: Map . put ( exports , module , true )
694-
695- # Then we store the new export if any
696- new_exports =
697- if export ,
698- do: [ { module , export } | new_exports ] ,
699- else: new_exports
700-
701- { exports , new_exports }
702- end
703-
704- new_exports = Map . new ( new_exports )
688+ { exports , dep_exports } =
689+ Enum . reduce ( dep_modules , { exports , dep_exports } , fn { mod , _ } , { exports , dep_exports } ->
690+ export =
691+ if Code . ensure_loaded? ( mod ) and function_exported? ( mod , :__info__ , 1 ) do
692+ mod . __info__ ( :exports_md5 )
693+ end
705694
706- removed =
707- for { module , _ } <- old_exports ,
708- not is_map_key ( new_exports , module ) ,
709- do: { module , true } ,
710- into: % { }
695+ # If the exports are the same, then the API did not change,
696+ # so we do not mark the export as stale. Note this has to
697+ # be very conservative. If the module is not loaded or if
698+ # the exports were not there, we need to consider it a stale export.
699+ case dep_exports do
700+ # They still match, nothing to change
701+ % { ^ mod => ^ export } ->
702+ { exports , dep_exports }
703+
704+ # Now, it either matched and they are different, which means there was
705+ # an export at some point OR it didn't exist before, which means adding
706+ # it as an export is likely a no-op anyway
707+ _ ->
708+ { Map . put ( exports , mod , true ) , Map . put ( dep_exports , mod , export ) }
709+ end
710+ end )
711711
712- modules = modules |> Map . merge ( dep_modules ) |> Map . merge ( removed )
713- exports = Map . merge ( exports , removed )
714- deps_exports = Map . put ( deps_exports , app , new_exports )
712+ modules = Map . merge ( modules , dep_modules )
713+ deps_exports = Map . put ( deps_exports , app , dep_exports )
715714
716715 protocols_and_impls =
717716 protocols_and_impls_from_modules ( manifest_modules , protocols_and_impls )
0 commit comments