[solved] Cannot infer an appropriate lifetime due to conflicting requirements, E0495


#1

I try to learn how to implement a FromIterator trait; during which I stumbled upon a problem with inferring lifetime.

I collect a &str iterator and I try to assign the str references to a struct called Mime. Doing it hardcoded shows my intention (this compiles and runs as expected)
Mime { file_extension: "exe", mime_type : "application" }

however, when I try to unwrap() the value from the iterator, I get the before-mentioned error. I don’t understand how to interpret the “help” message I get as a hint. Doesn’t Mime<'b> prescribe that my object outlives the Item? How can I fix this error?

use std::io;
use std::io::prelude::*;
use std::iter::FromIterator;

struct Mime<'a> {
    file_extension : &'a str,
    mime_type : &'a str,
}

impl<'a, 'b> FromIterator<&'a str> for Mime<'b> {
    fn from_iter<I: IntoIterator<Item=&'a str>>(iter: I) -> Self {
        let mut read_elem = || iter.into_iter().next().unwrap();
        
        Mime { file_extension: read_elem(), mime_type : read_elem() }
      //  Mime { file_extension: "exe", mime_type : "application" }
    }
}

fn main() {
    let stdin = io::stdin();
    let mut lines = stdin.lock().lines().map(Result::unwrap);

    //create a closure to get the next String                     
    let mut read_line = || lines.next().unwrap();

    //read input fields
    let mimetype_count = read_line().parse::<usize>().unwrap();
    let file_count = read_line().parse::<usize>().unwrap();
    let mut mimes : Vec<Mime> = Vec::new();    
    
    for _ in 0..mimetype_count {
        let decoded_mime = read_line().split_whitespace().collect::<Mime>();
        mimes.push(decoded_mime);
    }

    for elem in mimes {
        println!("{}/{}", elem.file_extension, elem.mime_type);
    }
}

I receive:
The following code generates E0495:

cannot infer an appropriate lifetime due to conflicting requirements; 
help: consider using an explicit lifetime parameter as shown: 
fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self
/tmp/retrieve_mime.rs:12 
let mut read_elem = || iter.into_iter().next().unwrap();`
                                               ^~~~~~

#2

Although there are a couple other errors that pop up afterwards, you can solve this immediate problem by adding a lifetime bound on 'a:

impl<'b, 'a: 'b> FromIterator<&'a str> for Mime<'b> {

#3

Interesting, that construct wasn’t covered in the Rust Guide - lifetimes. Thanks for pointing it out!

And indeed, this becomes the second error to tackle:

error: use of moved value: `read_elem` [E0382]

#4

It’s covered in the nomicon, at least.


#5

aha, so it requires the Dark Arts :imp: