The old value is not dismantled by field and then put together, rather the syntax is just a shorthand for taking point, setting some of the fields on that value, then returning the resulting value.
So your first example is short-hand for
let mut point = Point3d { x: 0, y: 0, z: 0 };
point = {
let new_value = point;
new_value.y = 1;
new_value
};
This desugaring clearly doesn't work if the types don't match.
If you're wondering why this is, it's because Rust doesn't do structural typing like that. Rust is designed so that the xy and z in Point3d are totally different from the x and y in Point2d. This is because although in your case they are very similar, the fields of types can mean different things depending on the context of the type. You wouldn't want to accidentally fill in inner on one type with a completely different type's inner for example. They likely serve a completely different purpose despite having the same name.