       |> MapSet.difference(all_paths)
       |> MapSet.to_list()
 
-    {changed, sources_stats} =
+    {modules, structs, changed, sources_stats} =
       if force do
-        # A config, path dependency or manifest has
-        # changed, let's just compile everything
+        # A config, path dependency or manifest has changed, let's just compile everything
         all_paths = MapSet.to_list(all_paths)
+
+        for module(module: module, beam: beam) <- all_modules,
+            do: remove_and_purge(beam, module)
 
         sources_stats =
           for path <- all_paths,
               into: %{},
               do: {path, Mix.Utils.last_modified_and_size(path)}
 
-        {all_paths, sources_stats}
+        # Now that we have deleted all beams, remember to remove the manifest.
+        # This is important in case mix compile --force fails, otherwise we
+        # would have an outdated manifest.
+        File.rm(manifest)
+
+        {[], %{}, all_paths, sources_stats}
       else
         # Otherwise let's start with the new sources
         new_paths =

        []
      end

    # Starts a server responsible for keeping track which files
    # were compiled and the dependencies between them.
    put_compiler_info({modules, structs, sources, modules, %{}})
    long_compilation_threshold = opts[:long_compilation_threshold] || 15


              do: {path, Mix.Utils.last_modified_and_size(path)}

        # Plus the sources that have changed in disk
        changed =
          for source(source: source, external: external, size: size) <- all_sources,
              {last_mtime, last_size} = Map.fetch!(sources_stats, source),
              times = Enum.map(external, &(sources_stats |> Map.fetch!(&1) |> elem(0))),
