This is what I came up with:
Depending on the value of switch switch sys::*allow-defstruct-redefinition*. In order to allow the structure to be redefined, we delete the structure class, if there is already one.
The undefined behavior is now
1. use of an existing struct from before the redefinition.
2. creation of functions with the same name as a structure element that has been removed.
3. running existing compiled code that uses an accessor for a slot that has changed relative position in the structure.
#2 can be fixed by removing the source transformation for the accessor.
(sys::%set-function-info accessor nil). It's not hard - involves iterating through the accessors just before the defstruct is redefined.
I don't think I'm going to bother fixing this at the moment.
#3 can be avoided by (declare (notinline accessor)) in the function being defined. Arguably this is what should be done if (declare (optimize (debug 3))).
I could also have sys::not-inline-p return true if debug is 3. I may try to do this, since it will be easy to forget to recompile.
We could at least provide warnings for such functions if we recorded that the source transform was applied, during compilation
BTW, if you have an existing (regular) class and create a defstruct with the same name, it blows away the previous class.
That probably deserves a warning.
Comments welcome.
Alan