C and Rust make various guarantees about data layout which programmers rely upon. C compilers cannot turn an array of structs into a struct of arrays because the layout of arrays is guaranteed, and needed to make common and trivial C accesses work which work by pointer arithmetic.
Turning an array of structs into a struct of arrays is indeed an optimization that would be possible in a language that did not make such guarantees about data layout. Perhaps it would be interesting to have a data structure that provides less guarantees on lower level access that in turn could be more aggressively optimized.
Looking it up “aggregate” is a C++ term for which the standard indeed does explicitly allow various optimizations and guarantees about data layout are weakened; this is not the case with C arrays.
Do you have any practical evidence to C compilers altering the data layout of an array in any way?
The reference to non-escaping aggregates, describes the compiler optimizing a local only struct by keeping the individual elements in registers during usage, and because the struct as a whole does not leave the local scope, these elements are just discarded when that scope closes.
Both of these transformations/optimizations are performed by all three industrial C and C++ compilers (gcc/llvm/msvc).
The problem is that there are lots of operations which imply the existence of part of an object, like passing around pointers or allocating single objects at a time, and that would disable these layout optimizations. An optimization that's easy to break isn't useful even if it would help a lot; you want them to be predictable more than anything.