It's doable in principle. You can make the Vec shared mutable, e.g. with a RefCell. The index doesn't also need shared mutation so it might make sense to separate things out a little bit between an iterable/collection type and the iterator itself, e.g.
use std::cell::RefCell;
struct GrowingIterable {
data: RefCell<Vec<String>>,
}
struct GrowingIter<'a> {
data: &'a RefCell<Vec<String>>,
index: usize,
}
impl<'a> IntoIterator for &'a GrowingIterable {
type IntoIter = GrowingIter<'a>;
type Item = String;
fn into_iter(self) -> GrowingIter<'a> {
GrowingIter {
data: &self.data,
index: 0,
}
}
}
impl Iterator for GrowingIter<'_> {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
let data = self.data.borrow();
if self.index == data.len() {
return None;
}
let item = data.get(self.index).unwrap().to_string();
self.index += 1;
Some(item)
}
}
fn main() {
let data = ["drt".to_string(), "more".to_string(), "tup".to_string()];
let ads = ["fok".to_string(), "bara".to_string()];
let grow = GrowingIterable {
data: data.to_vec().into(),
};
let mut ads_i = ads.iter();
for x in &grow {
println!("{x}");
if let Some(el) = ads_i.next() {
grow.data.borrow_mut().push(el.clone())
}
}
}
(playground)
That being said, I would probably just follow the approach in this case of using a while let loop. Those aren't much syntactic overhead anyway. I've used while let replacing for loop before for somewhat comparable cases: for example, if you sometimes want to skip or consume additional items within one loop iteration (by additional calls to .next), that's a simple approach. In my view, pushing extra items to the iterator is similarly affecting the iterator while it's being iterated on in a way that the use of while let syntax can be a good indicator for "careful, we're doing some slightly more complex iteration/loop pattern here".
If you want Iterator-like combinators, another option could be to use some sort of "lending iterator" primitive; and pass a mutable view of the whole data alongside the item. No true for loops, but at least you get a for_each method (and you could do other things like map, filter, and more... with it):
// [dependencies]
// lending-iterator = "0.1.7"
use lending_iterator::prelude::*;
struct GrowingIter {
data: Vec<String>,
index: usize,
}
#[gat]
impl LendingIterator for GrowingIter {
type Item<'a> = (String, &'a mut Vec<String>);
fn next(&mut self) -> Option<Self::Item<'_>> {
if self.index == self.data.len() {
return None;
}
let item = self.data.get(self.index).unwrap().to_string();
self.index += 1;
Some((item, &mut self.data))
}
}
fn main() {
let data = ["drt".to_string(), "more".to_string(), "tup".to_string()];
let ads = ["fok".to_string(), "bara".to_string()];
let grow = GrowingIter {
data: data.to_vec(),
index: 0,
};
let mut ads_i = ads.iter();
grow.for_each(|(x, data)| {
println!("{x}");
if let Some(el) = ads_i.next() {
data.push(el.clone())
}
});
}
Last but not least, for the specific case of appending things to the end of a Vec<String>, this one has an additional property that makes the shared mutability particularly harmless: if you only push new String items to the end of the Vec, that action itself will never affect any of the other existing items (besides possibly moving the String if the Vec grows) so then in particular any &str references stay valid. There are crates that offer APIs to make use of this property, in particular e.g. the elsa crate. With it, you can do the same kind of thing as the RefCell version above, but with less overhead both syntactically, and implementation wise (and no possibility to accidentally hold a "guard" value for too long that it'd produce run-time errors).
Notably, it basically comes with the iterator type you're trying to make here already pre-included 
// [dependencies]
// elsa = "1.11.2"
use elsa::FrozenVec;
fn main() {
let data = ["drt".to_string(), "more".to_string(), "tup".to_string()];
let ads = ["fok".to_string(), "bara".to_string()];
let grow = FrozenVec::from(data.to_vec());
let mut ads_i = ads.iter();
for x in grow.iter() {
println!("{x}");
if let Some(el) = ads_i.next() {
grow.push(el.clone())
}
}
}
(above, x will be &str)