cabal build doesn't rebuild if executable is moved/deleted and inputs haven't changed since its last build.
If you compile a project with new-build and move/delete the executable, cabal doesn't actually check for the executables existence. So if none of the inputs have changed since the last build it will happily conclude "nothing to do!" and exit without building executable, leaving it impossible to rebuild deleted executables without nuking the cache.
Legit bug. This is an artifact of the fact that we don't currently track build products in recompilation avoidance, so there's no way to tell that an executable needs to be rebuilt in this case. The usual workaround is to edit a source file associated with the executable and then try rebuilding again.
I guess it's the same for all other intermediate build products like .o/.hi and libraries. Though in the former case I think ghc --make will rebuild them.