set isn't just a builtin, it is a POSIX special builtin. There are a few builtin commands which are standards-specified to be found in a command search before anything else -
$PATH is not searched, function names are not searched, and etc. Most builtins which are not special are actually required by the POSIX standard to be found in your
$PATH before the shell will run any of its own builtin procedures. This is true of
echo and most others (though whether the standard is honored in this respect has been a matter of contention at the open group mailing lists in the past), but not of
All of these are reserved names of the shell, and they have special attributes other than their order of preference for command search as well. For example, you cannot define a shell function with any of those names in a standards-compliant shell. This is a good thing - it enables people to write portable scripts safely. These are baseline commands from which an experienced script-writer can establish a secure and reliable foothold in his or her environment. Invading this namespace is not advisable.
However, if you do desire to invade it, you can do so portably with
alias. The order of shell expansion enables this work-around. Because the
alias is expanded while the command is being read, whatever you replace the
set name with in your definition will expand correctly, it just probably should not expand to one of those names.
So you could do:
...which will work just fine.