You can look into my
generic-field-projection crate where I use a mixure of type level lists and runtime checks which get optimized away to get safe unique paths.
Here's how it works,
ProjectToSet projects a reference to a set of fields as (which are represented as types that implement the
Field trait). The
Field trait is unsafe to implement, and provides a function
name. This function provides a unique path that identifies the field as an iterator. (for example,
foo.bar.x would be
["bar", "x"] as an iterator). This iterator is build of
std::iter::Chain, making it really easy for LLVM to see what is going on.
project::from_mut then calls
FindOverlap to see if any of these "names" overlap (meaning that the fields would alias).
FindOverlap is a type that simulates generic closures. It goes through every field-type in the set pair-wise and figures out if the names overlap. If any of the names overlap, then it return true. If
FindOverlap returns true, then
project::from_mut will raise a panic and be on it's way. Otherwise it will do the projection.
For all cases that I tried (up to 16 fields), LLVM was able to see through all the checks and reduce
project::from_mut to just the pointer arithmetic. (through simple inlineing and const propogation)
This is fairly complex, but in the end you get robust, efficient, and safe code which I find to be worth the cost.