You cannot use an iterator here because calling push might reallocate, moving where the vector's data is stored. This would break the iterator, since the iterator is fixed to a specific location in memory.
You might like this article, which is about a similar situation. In that other situation, it is possible to use an iterator, but it is not in your case.
There could be something like Vec::<T>::split_at_mut_vec(&mut self, i: usize) -> (&[T], VecEnd<T>).
It would be like split_at_mut, but the last part would be a wrapper for the second slice, with all the Vec's methods and traits, except it would panic or Err when moving is needed by the allocator. (this is not a problem if you pre-allocate the Vec) It cannot break the slice reference, and you can use the Vec again when VecEnd is dropped.
let mut v = vec![1,2,3];
let l = v.len();
v.resize(l*2, 0); // useless init with zeros
let (s1, s2) = v.split_at_mut(l); // useless bound check (l <= l*2)
s1.iter().zip(s2.iter_mut()).for_each(|(a, b)| *b = a + 1); // too much iteration overhead because we know s1.len() == s2.len()
It can be optimized (see comments) but it would be unsafe and "not very concise"...