0

I can't seem to find anything about lifetimes for my specific situation. The search function has correct lifetimes and works fine, but then the search_case_insensitive function tells me the lifetime is too short, but I don't understand why.

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<(&'a str, i32)> {
    //do something
}

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<(&'a str, i32)> {
    return search(&query.to_lowercase(), &contents.to_lowercase());
}

I get:

error[E0597]: borrowed value does not live long enough
  --> src/lib.rs:44:43
   |
44 |     return search(&query.to_lowercase(), &contents.to_lowercase());
   |                                           ^^^^^^^^^^^^^^^^^^^^^^^ - temporary value only lives until here
   |                                           |
   |                                           temporary value does not live long enough
   |
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 43:1...
  --> src/lib.rs:43:1
   |
43 | pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<(&'a str, i32)> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: consider using a `let` binding to increase its lifetime

I have tried doing things like let c = contents and using this new c value instead but get the same issue.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
dheiberg
  • 1,914
  • 14
  • 18
  • 1
    It is because `to_lowercase` returns a new instance of a `String`. Your lifetime requirements on the signatures then become nonsensical because the output `'a` lifetime can't match the lifetime of the input `'a` lifetime. I think you're trying to follow and edit one of the examples in the Rust book. If so, [I have an answer here for someone having a similar issue to yours if you're interested in looking](https://stackoverflow.com/a/51167728/1517578). – Simon Whitehead Jul 24 '18 at 23:42
  • @SimonWhitehead Thanks for the quick explanation and the detailed post you linked! I got it working with the workaround that you suggested with the `Into` stuff. It's quite a lot of extra work for something that feels like it should just be one minor adjustment away... – dheiberg Jul 25 '18 at 00:10
  • See also [Implementing a search() method to handle optional case sensitivity](https://stackoverflow.com/q/51332725/155423) – Shepmaster Jul 25 '18 at 01:05
  • @dheiberg That particular answer is the "easy path" in that it just allocates extra `String` instances in a few places (which, to be fair, is what many other languages/environments will do under the covers anyway). There is an even easier way to do that and that is to just use `String` instances everywhere. Now, because the example in the book uses references, you're inevitably going to run into lifetime issues which due to the way Rust works can be confusing and tricky. My "go-to-advice" for people new to Rust is to just use `String`s and optimize it later if need be. – Simon Whitehead Jul 25 '18 at 06:39
  • Alternatively, there's another option in that answer to continue using references and avoid allocations .. it just means duplicating a similar line (the one that searches). – Simon Whitehead Jul 25 '18 at 06:40
  • @SimonWhitehead Yes I'm still trying to learn the lifetime concept, not used to having to deal with it so explicitly. I go it working in the end with a mixture of using `String` everywhere and `.to_string()`. Thank you for your help, is there any resource in particular (other than the book) you would recommend for understanding lifetimes and how to actually make use of them? – dheiberg Jul 25 '18 at 09:43

0 Answers0