If M-x compile obeys dir-locals that could work, yes.
I checked (by creating a .dir-locals.el containing a setting for the
exec-path variable in compliation-mode) and it doesn't seem to read
exec-path from dir-locals.
Another option is to use process-file's file-name-handler-alist.
So we'd maintain a mapping from visited filenames to the environment
that that filename is in, and make sure that visited filenames in a
nonstandard environment are present in file-name-handler-alist.
Tying environments to filenames in this way makes sense when an
environment corresponds to a project which exists in the filesystem. In
that case we can just put the project root directory into
file-name-handler-alist, and instantly everything in the project works
in the new environment.
And for running one-off commands (to send my mail, or something else not
associated with any project) I've always been able to just wrap the
command with a let-binding of exec-path and process-environment. (The
environment package could provide a new macro to do that)
So then there would be two ways to enter a different environment for Emacs:
One for projects and based on file-name-handler-alist, and one for single
commands and based on let-binding. I think that would be enough to start.
Does this approach (putting project root directories into
file-name-handler-alist) sound like something that could be accepted
into core Emacs? If so I'll get started.