Where and how do overlays get applied?

I’ve been digging through the Nix source trying to find where exactly overlays get applied to derivations. I see that they get imported in pkgs/top-level/impure.nix and eventually get passed to the stdenv stages, but I don’t see the exact place where they end up interacting with the system.

Can someone please enlighten me?

The heart of the overlays can be found in stage.nix, where the package set is accumulated by performing a fold:

 # The complete chain of package set builders, applied from top to bottom
 toFix = lib.foldl' (lib.flip lib.extends) (self: {}) ([
    stdenvBootstappingAndPlatforms
    stdenvBootstappingAndPlatforms
    stdenvAdapters
    stdenvAdapters
    trivialBuilders
    trivialBuilders
    allPackages
    allPackages
    aliases
    aliases
    stdenvOverrides
    stdenvOverrides
    configOverrides
    configOverrides
  ] ++ overlays);

  # Use `overridePackages` to easily override this package set.
in
  # Warning: this function is very expensive and must not be used
  # Return the complete set of packages.
  # from within the nixpkgs repository.
  lib.fix toFix

first the boostrap + normal nixpkg package set is constructed. Then the overlays are applied, creating a final package set. The fix function forces the chain of overlays to be resolved. An example is given in fixed-points.nix:

  # Compute the fixed point of the given function `f`, which is usually an
  # attribute set that expects its final, non-recursive representation as an
  # argument:
  #
  #     f = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }
  #
  # Nix evaluates this recursion until all references to `self` have been
  # resolved. At that point, the final result is returned and `f x = x` holds:
  #
  #     nix-repl> fix f
  #     { bar = "bar"; foo = "foo"; foobar = "foobar"; }
  #
  #  Type: fix :: (a -> a) -> a
  #
  # See https://en.wikipedia.org/wiki/Fixed-point_combinator for further
  # details.
  fix = f: let x = f x; in x;