Iterator next method lifetime mismatch - rust

I'm trying to create an Iterator interface using the csv crate such that I can return a HashMap of col-name: value and am running into a lifetime error I cannot figure out.
For the code below:
use csv::{
Reader,
StringRecord,
StringRecordsIter,
};
use std::collections::HashMap;
use std::fs::File;
pub struct Handler {
pub reader: Reader<File>
}
impl Handler {
pub fn new(file: File) -> Handler {
Handler { reader: Reader::from_reader(file) }
}
}
// type Row = HashMap<String, String>;
pub struct Row<'r> {
number: usize,
fields: HashMap<&'r str, &'r str>,
}
pub struct CSVIterator<'f> {
current_row: usize,
headers: StringRecord,
records: StringRecordsIter<'f, File>,
}
impl<'f> CSVIterator<'f> {
pub fn new(handler: &'f mut Handler) -> CSVIterator<'f> {
CSVIterator {
current_row: 0,
headers: handler.reader.headers().unwrap().clone(),
records: handler.reader.records(),
}
}
}
impl<'f> Iterator for CSVIterator<'f> {
type Item = Row<'f>;
fn next(&mut self) -> Option<Self::Item> {
let next_record = self.records.next();
if next_record.is_none() {
return None;
}
let record = next_record.unwrap().unwrap();
let fields = make_fields(&record, &self.headers);
let row = Row {
number: self.current_row,
fields: fields,
};
return Some(row)
}
}
fn make_fields<'r>(
record: &'r StringRecord, header: &'r StringRecord
) -> HashMap<&'r str, &'r str> {
let mut row: HashMap<&str, &str> = HashMap::new();
for (colname, value) in header.iter().zip(record) {
row.insert(colname, value);
}
row
}
I'm getting the following error:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/csvio.rs:55:43
|
55 | let fields = make_fields(&record, &self.headers);
| ^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
--> src/csvio.rs:47:13
|
47 | fn next(&mut self) -> Option<Self::Item> {
| ^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/csvio.rs:55:43
|
55 | let fields = make_fields(&record, &self.headers);
| ^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'f` as defined here...
--> src/csvio.rs:44:6
|
44 | impl<'f> Iterator for CSVIterator<'f> {
| ^^
note: ...so that the types are compatible
--> src/csvio.rs:47:46
|
47 | fn next(&mut self) -> Option<Self::Item> {
| ______________________________________________^
48 | | let next_record = self.records.next();
49 | |
50 | | if next_record.is_none() {
... |
61 | | return Some(row)
62 | | }
| |_____^
= note: expected `<CSVIterator<'f> as Iterator>`
found `<CSVIterator<'_> as Iterator>`
For more information about this error, try `rustc --explain E0495`.
I may not intuitively understand the lifetime requirements for the next method here, can someone point me in the right direction?
Thanks!

Related

Rust: how to bound the lifetime of Iterator::next()?

The following code doesn't compile:
struct Things {
things: Vec<usize>
}
struct ThingsIterMut<'a> {
contents: &'a mut Vec<usize>,
indices: std::slice::Iter<'a, usize>
}
impl<'a> Iterator for ThingsIterMut<'a> {
type Item = &'a mut usize;
fn next(&mut self) -> Option<Self::Item> {
match self.indices.next() {
None => None,
Some(i) => self.contents.get_mut(*i)
}
}
}
impl Things {
pub fn iter_mut<'a>(&'a mut self) -> ThingsIterMut<'a> {
ThingsIterMut {
contents: &mut self.things,
indices: self.things.iter()
}
}
}
fn main() {
println!("Hello, world!");
}
It complains:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:16:24
|
16 | Some(i) => self.contents.get_mut(*i)
| ^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 13:5...
--> src/main.rs:13:5
|
13 | fn next(&mut self) -> Option<Self::Item> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:16:24
|
16 | Some(i) => self.contents.get_mut(*i)
| ^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 10:6...
--> src/main.rs:10:6
|
10 | impl<'a> Iterator for ThingsIterMut<'a> {
| ^^
note: ...so that the types are compatible
--> src/main.rs:13:46
|
13 | fn next(&mut self) -> Option<Self::Item> {
| ______________________________________________^
14 | | match self.indices.next() {
15 | | None => None,
16 | | Some(i) => self.contents.get_mut(*i)
17 | | }
18 | | }
| |_____^
= note: expected `std::iter::Iterator`
found `std::iter::Iterator`
Changing next to next(&'a mut self) dose not work (signature mismatch), neither does change self.contents.get_mut() to self.contents.get_mut::<'a>().
What's the correct way to address this issue?
I see two problems. The first is that your iter_mut function tries to return both a mutable and an immutable reference to self.things.
It is easier to see why the borrow checker doesn't allow this by simplifying it:
fn main() {
let mut things = vec![1, 2, 3];
let contents = &mut things;
let indices = things.iter(); // borrows self_things immutably
let things_iter_mut = (contents, indices);
}
The second problem that you are trying to return a longer reference than you pass into the next function.
struct Things<'things> {
contents: &'things mut Vec<usize>,
}
impl<'things> Things<'things> {
// This won't compile! The 'borrow lifetime is implied.
// But here you can see that the borrow might be shorter than
// what we are returning.
fn next(&'borrow mut self) -> &'things mut Vec<usize> {
self.contents
}
// This will compile. Because the returned reference lives
// just as long as the argument.
fn next(&'things mut self) -> &'things mut Vec<usize> {
self.contents
}
}

How to implement a non-consuming mutable std::iter::Iterator for a data structure

I have a data structure called VecCircular and for a non-consuming immutable implementation of std::iter::Iterator, I followed the guidelines here. here is my code:
pub struct VecCircularIterator<'a, T> {
vec_circular: &'a VecCircular<T>,
index: usize,
}
impl<'a, T> std::iter::IntoIterator for &'a VecCircular<T> {
type Item = &'a T;
type IntoIter = VecCircularIterator<'a, T>;
fn into_iter(self) -> Self::IntoIter {
VecCircularIterator {
vec_circular: &self,
index: self.front_index,
}
}
}
impl<'a, T> std::iter::Iterator for VecCircularIterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
return None;
} else {
let item = &self.vec_circular[self.index];
self.index = (self.index + 1) % self.vec_circular.capacity;
return Some(item);
}
}
}
but when I try to change that implementation to a mutable one:
pub struct VecCircularIterator<'a, T> {
vec_circular: &'a mut VecCircular<T>,
index: usize,
}
impl<'a, T> std::iter::IntoIterator for &'a VecCircular<T> {
type Item = &'a T;
type IntoIter = VecCircularIterator<'a, T>;
fn into_iter(self) -> Self::IntoIter {
VecCircularIterator {
vec_circular: &mut self,
index: self.front_index,
}
}
}
impl<'a, T> std::iter::Iterator for VecCircularIterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
return None;
} else {
let item = &self.vec_circular[self.index];
self.index = (self.index + 1) % self.vec_circular.capacity;
return Some(item);
}
}
}
I get the following error:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/queue/mod.rs:143:25
|
143 | let item = &self.vec_circular[self.index];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 139:5...
--> src/queue/mod.rs:139:5
|
139 | / fn next(&mut self) -> Option<&'a T> {
140 | | if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
141 | | return None;
142 | | } else {
... |
146 | | }
147 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/queue/mod.rs:143:25
|
143 | let item = &self.vec_circular[self.index];
| ^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 137:6...
--> src/queue/mod.rs:137:6
|
137 | impl<'a, T> std::iter::Iterator for VecCircularIterator<'a, T> {
| ^^
note: ...so that the types are compatible
--> src/queue/mod.rs:139:41
|
139 | fn next(&mut self) -> Option<&'a T> {
| _________________________________________^
140 | | if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
141 | | return None;
142 | | } else {
... |
146 | | }
147 | | }
| |_____^
= note: expected `std::option::Option<&'a T>`
found `std::option::Option<&T>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
error: could not compile `rudac`.
I'm a little shaky on rust lifetime parameters and I can't figure out what to do here.
An Iterator cannot yield borrowed values from within itself. The API declaration for next would otherwise have to tie the Self::Item with a lifetime to self.
You could yield the value instead of a reference e.g., something like this (but your code example is incomplete (missing VecCircular) so it's hard to guess what's a good way to do it):
impl<T> std::iter::Iterator for VecCircularIterator<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
return None;
} else {
let item = self.vec_circular[self.index];
self.index = (self.index + 1) % self.vec_circular.capacity;
return item;
}
}
}
Also note that there is a problem with your into_iter method. into_iter consumes self so if you assign a reference to vec_circular it will not live long enough (it goes out of scope once into_iter returns).
Btw. since it looks like you are implementing a queue on your own, you may also be interested in VecDeque from the standard library. It also provides Iter, which can yield references. It does that by not owning the VecDeque itself and instead just borrows a slice from it.

How can I write a boxed closure which mutates a reference to a struct?

I have some code that looks like this:
type Callback<T> = Box<Fn(&T) -> ()>;
struct Foo {
name: String,
}
impl Foo {
fn name_updater(&mut self) -> Callback<String> {
Box::new(|new_name| {
self.name = *new_name;
})
}
}
This code doesn't compile because the closure requires the static lifetime. However I'm unsure if this will resolve the question and because there aren't explicit lifetimes, it's not immediately clear to me what I'd need to do to resolve that.
Here is an example of the compilation error:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/lib.rs:9:9
|
9 | / Box::new(|new_name| {
10 | | self.name = *new_name;
11 | | })
| |__________^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 8:5...
--> src/lib.rs:8:5
|
8 | / fn name_updater(&mut self) -> Callback<String> {
9 | | Box::new(|new_name| {
10 | | self.name = *new_name;
11 | | })
12 | | }
| |_____^
note: ...so that the type `[closure#src/lib.rs:9:18: 11:10 self:&mut &mut Foo]` will meet its required lifetime bounds
--> src/lib.rs:9:9
|
9 | / Box::new(|new_name| {
10 | | self.name = *new_name;
11 | | })
| |__________^
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r std::string::String) + 'static)>
found std::boxed::Box<dyn for<'r> std::ops::Fn(&'r std::string::String)>
How can I write a closure that is capable of mutating the struct's name property?
You need to bound a lifetime to your closure because you borrow something aka &mut self:
type Callback<'a, T> = Box<dyn FnMut(&T) -> () + 'a>;
#[derive(Debug)]
struct Foo {
name: String,
}
impl Foo {
fn name_updater(&mut self) -> Callback<str> {
Box::new(move |new_name| {
self.name.replace_range(.., new_name);
})
}
}
fn main() {
let mut foo = Foo {
name: String::from("foo"),
};
foo.name_updater()("bar");
println!("{:?}", foo);
}
Also note that you don't need to use a box:
#[derive(Debug)]
struct Foo {
name: String,
}
impl Foo {
fn name_updater<'a>(&'a mut self) -> impl FnMut(&str) -> () + 'a {
move |new_name| {
self.name.replace_range(.., new_name);
}
}
}
fn main() {
let mut foo = Foo {
name: String::from("foo"),
};
foo.name_updater()("bar");
println!("{:?}", foo);
}

Create a struct pointing to another

How can I create the Item instance pointing to the database received as parameter?
struct Something {}
struct Database<'a> {
something: &'a Something,
}
struct Item<'a> {
database: &'a mut Database<'a>,
}
impl<'a> Item<'a> {
fn new(database: &'a mut Database) -> Self {
let mut obj = Self { database };
obj
}
}
This produces the error:
error[E0308]: mismatched types
--> src/main.rs:16:13
|
16 | database
| ^^^^^^^^ lifetime mismatch
|
= note: expected type `&'a mut Database<'a>`
found type `&'a mut Database<'_>`
note: the lifetime 'a as defined on the impl at 13:1...
--> src/main.rs:13:1
|
13 | / impl<'a> Item<'a> {
14 | | fn new(database: &'a mut Database) -> Self {
15 | | let mut obj = Self {
16 | | database
... |
20 | | }
21 | | }
| |_^
note: ...does not necessarily outlive the anonymous lifetime #1 defined on the method body at 14:5
--> src/main.rs:14:5
|
14 | / fn new(database: &'a mut Database) -> Self {
15 | | let mut obj = Self {
16 | | database
17 | | };
18 | |
19 | | obj
20 | | }
| |_____^
I do not understand if the error is in the return type (Self) or another thing.
You defined Database to require a lifetime parameter. That means you also have to give it one. The error message is really helpful here and your problem is fixed by simply doing what it says:
expected type `&'a mut Database<'a>`
found type `&'a mut Database<'_>`
It suffices to simply add <'a> to Database in the signature of new.
N.B.: Always read error messages from top to bottom. Usually by resolving the first error all the successive ones disappear.
struct Something {}
struct Database<'a> {
something: &'a Something
}
struct Item<'a> {
database: &'a mut Database<'a>
}
impl<'a> Item<'a> {
fn new(database: &'a mut Database<'a>) -> Self {
let mut obj = Self {
database
};
obj
}
}
fn main() {
let something = &Something {};
let mut database = Database { something };
let item = Item::new(&mut database);
}
Playground

Anonymous vs struct lifetime for assignment

For this code (trimmed some, sorry not more), I get a lifetime problem:
fn main() {
println!("Hello, world!");
}
#[derive(Debug)]
pub struct Token<'a> {
pub line: usize,
// Col in code points.
pub col: usize,
// Index in bytes.
pub index: usize,
pub state: TokenState,
pub text: &'a str,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum TokenState {
VSpace,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ParseState {
Expr,
}
pub struct Node<'a> {
kids: Vec<Node<'a>>,
state: ParseState,
token: Option<&'a Token<'a>>,
}
impl<'a> Node<'a> {
fn new(state: ParseState) -> Node<'a> {
Node {
kids: vec![],
state,
token: None,
}
}
fn new_token(token: &'a Token<'a>) -> Node<'a> {
// TODO Control state? Some token state?
Node {
kids: vec![],
state: ParseState::Expr,
token: Some(&token),
}
}
fn push_if(&mut self, node: Node<'a>) {
if !node.kids.is_empty() {
self.kids.push(node);
}
}
}
pub fn parse<'a>(tokens: &'a Vec<Token<'a>>) -> Node<'a> {
let mut root = Node::new(ParseState::Expr);
let mut parser = Parser {
index: 0,
tokens: tokens,
};
parser.parse_block(&mut root);
root
}
struct Parser<'a> {
index: usize,
tokens: &'a Vec<Token<'a>>,
}
impl<'a> Parser<'a> {
fn parse_block(&mut self, parent: &mut Node) {
loop {
let mut row = Node::new(ParseState::Expr);
match self.peek() {
Some(_) => {
self.parse_row(&mut row);
}
None => {
break;
}
}
parent.push_if(row);
}
}
fn parse_row(&mut self, parent: &mut Node) {
loop {
match self.next() {
Some(ref token) => match token.state {
TokenState::VSpace => break,
_ => {
parent.kids.push(Node::new_token(&token));
}
},
None => break,
}
}
}
fn next(&mut self) -> Option<&Token> {
let index = self.index;
if index < self.tokens.len() {
self.index += 1;
}
self.tokens.get(index)
}
fn peek(&mut self) -> Option<&Token> {
self.tokens.get(self.index)
}
}
(playground)
This is the error message:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:90:24
|
90 | match self.next() {
| ^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 72:1...
--> src/main.rs:72:1
|
72 | / impl<'a> Parser<'a> {
73 | | fn parse_block(&mut self, parent: &mut Node) {
74 | | loop {
75 | | let mut row = Node::new(ParseState::Expr);
... |
112| | }
113| | }
| |_^
note: ...so that the type `Parser<'a>` is not borrowed for too long
--> src/main.rs:90:19
|
90 | match self.next() {
| ^^^^
note: but, the lifetime must be valid for the anonymous lifetime #3 defined on the method body at 88:5...
--> src/main.rs:88:5
|
88 | / fn parse_row(&mut self, parent: &mut Node) {
89 | | loop {
90 | | match self.next() {
91 | | Some(ref token) => match token.state {
... |
99 | | }
100| | }
| |_____^
note: ...so that expression is assignable (expected Node<'_>, found Node<'_>)
--> src/main.rs:94:42
|
94 | parent.kids.push(Node::new_token(&token));
| ^^^^^^^^^^^^^^^^^^^^^^^
All the references should be tied to the same outside lifetime. In my full code (of which I just have an excerpt here), I expect to hang onto the original parsed source, and I'm trying to tie everything to that.
I know the error messages are trying to be helpful, but I'm really unsure what the conflict is. And I'm unsure what other lifetime questions here are related to the same issue I have or not.
Let's take a look at the signature of Parser::next:
fn next(&mut self) -> Option<&Token>
This function promises to return an Option<&Token>. There are elided lifetimes here; let's rewrite the signature to make them explicit:
fn next<'b>(&'b mut self) -> Option<&'b Token<'b>>
We can now see that next is generic over lifetime 'b. Notice how the return type uses 'b, not 'a. This is valid in itself, because the compiler can infer that 'b is a shorter than 'a, and mutable references (&'a mut T) are covariant over 'a ("covariant" in this context means that we can substitute lifetime 'a with a shorter lifetime). But what the function ends up promising is that the result lives at least as long as itself, while it can in fact live at least as long as 'a.
In Parser::parse_row, you're trying to take the result of Parser::next and insert it into parent. Let's look at Parser::parse_row's signature:
fn parse_row(&mut self, parent: &mut Node)
We have some omitted lifetimes here again. Let's spell them out:
fn parse_row<'b, 'c, 'd>(&'b mut self, parent: &'c mut Node<'d>)
'c is not going to be important, so we can ignore it.
If we try to compile now, the last two notes are different:
note: but, the lifetime must be valid for the lifetime 'd as defined on the method body at 88:5...
--> src/main.rs:88:5
|
88 | / fn parse_row<'b, 'c, 'd>(&'b mut self, parent: &'c mut Node<'d>) {
89 | | loop {
90 | | match self.next() {
91 | | Some(ref token) => match token.state {
... |
99 | | }
100| | }
| |_____^
note: ...so that expression is assignable (expected Node<'d>, found Node<'_>)
--> src/main.rs:94:42
|
94 | parent.kids.push(Node::new_token(&token));
| ^^^^^^^^^^^^^^^^^^^^^^^
Now, one of the anonymous lifetimes is identified as 'd. The other is still an anonymous lifetime, and that's an artifact of how the compiler manipulates lifetimes, but we can think of it as being 'b here.
The problem should be a bit clearer now: we're trying to push a Node<'b> into a collection of Node<'d> objects. It's important that the type be exactly Node<'d>, because mutable references (&'a mut T) are invariant over T ("invariant" means it can't change).
Let's make the lifetimes match. First, we'll change next's signature to match what we can actually return:
fn next(&mut self) -> Option<&'a Token<'a>>
This means that now, when we call self.next() in parse_row, we'll be able to construct a Node<'a>. A Node<'x> can only store Node<'x> objects (per your definition of Node), so the parent parameter's referent must also be of type Node<'a>.
fn parse_row(&mut self, parent: &mut Node<'a>)
If we try to compile now, we'll get an error in Parser::parse_block on the call to parse_row. The problem is similar to what we just saw. parse_block's signature is:
fn parse_block(&mut self, parent: &mut Node)
which expands to:
fn parse_block<'b, 'c, 'd>(&'b mut self, parent: &'c mut Node<'d>)
Here's the error the compiler gives with this elaborated signature:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/main.rs:78:26
|
78 | self.parse_row(&mut row);
| ^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 72:1...
--> src/main.rs:72:1
|
72 | / impl<'a> Parser<'a> {
73 | | fn parse_block<'b, 'c, 'd>(&'b mut self, parent: &'c mut Node<'d>) {
74 | | loop {
75 | | let mut row = Node::new(ParseState::Expr);
... |
112| | }
113| | }
| |_^
note: ...so that types are compatible (expected &mut Parser<'_>, found &mut Parser<'a>)
--> src/main.rs:78:26
|
78 | self.parse_row(&mut row);
| ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'd as defined on the method body at 73:5...
--> src/main.rs:73:5
|
73 | / fn parse_block<'b, 'c, 'd>(&'b mut self, parent: &'c mut Node<'d>) {
74 | | loop {
75 | | let mut row = Node::new(ParseState::Expr);
76 | | match self.peek() {
... |
85 | | }
86 | | }
| |_____^
note: ...so that types are compatible (expected &mut Node<'_>, found &mut Node<'d>)
--> src/main.rs:84:20
|
84 | parent.push_if(row);
| ^^^^^^^
The compiler is unable to infer the type of row (specifically, the lifetime in its type Node<'x>). On one hand, the call to parse_row means it should be Node<'a>, but the call to push_if means it should be Node<'d>. 'a and 'd are unrelated, so the compiler doesn't know how to unify them.
The solution is easy, and it's the same as above: just make parent have type &mut Node<'a>.
fn parse_block(&mut self, parent: &mut Node<'a>)
Now your code compiles!

Resources