1

I want a function on a struct which returns an iterator to one of the struct's members. I tried something like the following, which doesn't work.

struct Foo {
    bar: Vec<String>,
}

impl Foo {
    fn baz(&self) -> Box<Iterator<Item = &String>> {
        Box::new(self.bar.iter())
    }
}

fn main() {
    let x = Foo { bar: vec!["quux".to_string()] };
    x.baz();
}

When compiling, I get the error below:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
 --> src/main.rs:7:27
  |
7 |         Box::new(self.bar.iter())
  |                           ^^^^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
 --> src/main.rs:6:5
  |
6 | /     fn baz(&self) -> Box<Iterator<Item = &String>> {
7 | |         Box::new(self.bar.iter())
8 | |     }
  | |_____^
note: ...so that reference does not outlive borrowed content
 --> src/main.rs:7:18
  |
7 |         Box::new(self.bar.iter())
  |                  ^^^^^^^^
  = note: but, the lifetime must be valid for the static lifetime...
note: ...so that expression is assignable (expected std::boxed::Box<std::iter::Iterator<Item=&std::string::String> + 'static>, found std::boxed::Box<std::iter::Iterator<Item=&std::string::String>>)
 --> src/main.rs:7:9
  |
7 |         Box::new(self.bar.iter())
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^

I also tried adding lifetime information as suggested elsewhere

struct Foo {
    bar: Vec<String>,
}

impl Foo {
    fn baz<'a>(&self) -> Box<Iterator<Item = &String> + 'a> {
        Box::new(self.bar.iter())
    }
}

fn main() {
    let x = Foo { bar: vec!["quux".to_string()] };
    x.baz();
}

Now my error is the following:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
 --> src/main.rs:7:27
  |
7 |         Box::new(self.bar.iter())
  |                           ^^^^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
 --> src/main.rs:6:5
  |
6 | /     fn baz<'a>(&self) -> Box<Iterator<Item = &String> + 'a> {
7 | |         Box::new(self.bar.iter())
8 | |     }
  | |_____^
note: ...so that reference does not outlive borrowed content
 --> src/main.rs:7:18
  |
7 |         Box::new(self.bar.iter())
  |                  ^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the method body at 6:5...
 --> src/main.rs:6:5
  |
6 | /     fn baz<'a>(&self) -> Box<Iterator<Item = &String> + 'a> {
7 | |         Box::new(self.bar.iter())
8 | |     }
  | |_____^
note: ...so that expression is assignable (expected std::boxed::Box<std::iter::Iterator<Item=&std::string::String> + 'a>, found std::boxed::Box<std::iter::Iterator<Item=&std::string::String>>)
 --> src/main.rs:7:9
  |
7 |         Box::new(self.bar.iter())
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Michael Mior
  • 28,107
  • 9
  • 89
  • 113
  • Please re-check the linked duplicates and note the differences in the lifetimes: `fn into_iterator<'a>(myvec: &'a Vec) -> Box + 'a>` and `fn to_words<'a>(text: &'a str) -> Box + 'a> ` compared to your `fn baz<'a>(&self) -> Box + 'a>`. – Shepmaster Jul 27 '17 at 20:05
  • @Shepmaster I noted that and solved my problem, but the solution was not immediately obvious to me and I was hoping to reopen to answer my own question. – Michael Mior Jul 27 '17 at 20:10

0 Answers0