     end
   end
 
-  # files x, waiting for x: POSSIBLE ERROR! Release processes so we get the failures
-
+  # spawned 1, waiting for 1: Release it!
+  defp spawn_workers([], spawned, waiting, files, result, warnings, state)
+       when map_size(waiting) == map_size(spawned) and map_size(waiting) == 1 do
+    {pid, _, _iterator} = :maps.next(:maps.iterator(waiting))
+    spawn_workers([{pid, :not_found}], spawned, waiting, files, result, warnings, state)
+  end
+
+  # spawned x, waiting for x: POSSIBLE ERROR! Release processes so we get the failures
   defp spawn_workers([], spawned, waiting, files, result, warnings, state)
        when map_size(waiting) == map_size(spawned) do
-    # Single entry, just release it.
-    with 1 <- map_size(waiting), [%{pid: pid}] <- files, %{^pid => _} <- waiting do
-      spawn_workers([{pid, :not_found}], spawned, waiting, files, result, warnings, state)
+    # There is potentially a deadlock. We will release modules with
+    # the following order:
+    #
+    #   1. Code.ensure_compiled/1 checks without a known definition (deadlock = soft)
+    #   2. Code.ensure_compiled/1 checks with a known definition (deadlock = soft)
+    #   3. Struct/import/require/ensure_compiled! checks without a known definition (deadlock = hard)
+    #   4. Modules without a known definition
+    #   5. Code invocation (deadlock = raise)
+    #
+    # The reason for step 3 and 4 is to not treat typos as deadlocks and
+    # help developers handle those sooner. However, this can have false
+    # positives in case multiple modules are defined in the same file
+    # and the module we are waiting for is defined later on.
+    #
+    # Finally, note there is no difference between hard and raise, the
+    # difference is where the raise is happening, inside the compiler
+    # or in the caller.
+    waiting_list = Map.to_list(waiting)
+
+    deadlocked =
+      deadlocked(waiting_list, :soft, false) ||
+        deadlocked(waiting_list, :soft, true) ||
+        deadlocked(waiting_list, :hard, false) ||
+        without_definition(waiting_list, files)
+
+    if deadlocked do
+      spawn_workers(deadlocked, spawned, waiting, files, result, warnings, state)
     else
-      _ ->
-        # There is potentially a deadlock. We will release modules with
-        # the following order:
-        #
-        #   1. Code.ensure_compiled/1 checks without a known definition (deadlock = soft)
-        #   2. Code.ensure_compiled/1 checks with a known definition (deadlock = soft)
-        #   3. Struct/import/require/ensure_compiled! checks without a known definition (deadlock = hard)
-        #   4. Modules without a known definition
-        #   5. Code invocation (deadlock = raise)
-        #
-        # The reason for step 3 and 4 is to not treat typos as deadlocks and
-        # help developers handle those sooner. However, this can have false
-        # positives in case multiple modules are defined in the same file
-        # and the module we are waiting for is defined later on.
-        #
-        # Finally, note there is no difference between hard and raise, the
-        # difference is where the raise is happening, inside the compiler
-        # or in the caller.
-        waiting_list = Map.to_list(waiting)
-
-        deadlocked =
-          deadlocked(waiting_list, :soft, false) ||
-            deadlocked(waiting_list, :soft, true) || deadlocked(waiting_list, :hard, false) ||
-            without_definition(waiting_list, files)
-
-        if deadlocked do
-          spawn_workers(deadlocked, spawned, waiting, files, result, warnings, state)
-        else
-          errors = handle_deadlock(waiting, files)
-          {{:error, errors, warnings}, state}
-        end
-    end
-  end
-
-  # No more queue, but spawned and length(waiting) do not match
+      errors = handle_deadlock(waiting, files)
+      {{:error, errors, warnings}, state}
+    end
+  end
+
+  # No more queue, but spawned and map_size(waiting) do not match
   defp spawn_workers([], spawned, waiting, files, result, warnings, state) do
     wait_for_messages([], spawned, waiting, files, result, warnings, state)
   end

      {:DOWN, ref, :process, pid, reason} when is_map_key(spawned, ref) ->
        # async spawned processes have no file, so we always have to delete the ref directly
        spawned = Map.delete(spawned, ref)
        waiting = delete_waiting(waiting, pid)
        {file, new_spawned, new_files} = discard_file_pid(spawned, files, pid)

        if file do

      end

    {available, Map.put(result, {kind, module}, value)}
  end

  defp update_timing(files, pid, key) do
