Robust LaTeX commands are either “naturally robust” - meaning that
they never need
\protect, or “self-protected” - meaning that
\protect built in to their definition in some
way. Self-protected commands, and fragile commands with
\protection are only robust in a context where the
mechanism is properly handled. The body of an
\protect properly, since
\edef is a TeX
primitive rather than a LaTeX command.
This problem is resolved by a LaTeX internal command
\protected@edef, which does the job of
\edef while keeping the
\protect mechanism working. There's a corresponding
\protected@xdef which does the job of
Of course, these commands need to be tended carefully, since they're internal: see "@" in control sequence names.