Of course it was â you forget the String that owns it, and then you never free it. Your iterator type doesn't have a Drop impl that would recreate an owned String and drop it.
You are over-complicating this way too much. You don't need any raw pointers or unsafe for this. All you need is: Playground.
fn next(&mut self) -> Option<(&str, &str)> {
let Some(next) = self.string[self.start..].find('\n') else {
return None;
};
let first = &self.string[self.start..][..next];
self.start += next + 1;
let end = self.string[self.start..].find('\n').unwrap_or(self.string[self.start..].len());
let second = &self.string[self.start..][..end];
Some((first, second))
}
Thank you for simplifying! I would like to use this implementation as impl Iterator, however lifetime issue comes up:
impl Iterator for LineTuples {
type Item = (&str, &str);
fn next(&mut self) -> Option<(&str, &str)> {
let Some(next) = self.string[self.start..].find('\n') else {
return None;
};
let first = &self.string[self.start..][..next];
self.start += next + 1;
let end = self.string[self.start..].find('\n').unwrap_or(self.string[self.start..].len());
let second = &self.string[self.start..][..end];
Some((first, second))
}
}
Do I need to have phantom lifetime on it, or is there some better solution?
There's no "lifetime issue" in my code. The lifetimes are exactly correct. The code compiles and runs (did you run the Playground?), and the lifetimes are as lenient as possible.
Allowing references with arbitrarily long lifetimes to be created from a local that will eventually be dropped is wrong (ie., unsound). An unbound lifetime, controlled by the caller, can be chosen to be 'static, which is very clearly nonsensical.
When you get a borrow checker error, you should not reach for unsafe. Use it as an opportunity to learn about how the compiler is saving you from unsound code instead.
days since someone tried and failed to use unsafe to circumvent the lifetime system.
Even experts get lifetime-related unsafe wrong. The chances of getting right while still learning Rust are ~ zero. Leave it alone until you have much more experience.
Looks like you implemented Iterator using the partial code in the reply, instead of using the more complete code in the playground that @paramagnetic provided.