Can the compiler be more precise about "borrowed value does not live long enough"?

Learning rust, I was writing a function that had to deal with owned + borrowed data. While writing the function, I ran into this compiler error:

The error pointed towards the origin (line 51) and the location where the scope ended (line 65). Furthermore, all references to string are marked as causing an error, which looks like this:

I didn't quite put 2 and 2 together, and it took me a while that in fact, the error was caused by a line that wasn't being highlighted, line 61, because it takes a borrowed value (first) and returns it as a CoW.

After changing that line, the compiler no longer complained:

Now, I'm still learning how to deal with the issue itself (without doing unnecessary copies, although I doubt that's possible here), but I wanted to ask more specifically about the returned error.

Is there a reason why the compiler can't more directly point towards the cause of the error? I'm very new to this, but from what I understand, I returned a borrowed reference at line 61, which caused the problem to appear in the first place, but the compiler never hinted that the problem might stem from there.

After re-reading the second error ("cannot move out of string because it is borrowed"), I thought maybe there is actually another way to solve this problem; don't move out the string variable, since it's being borrowed, and perhaps the compiler is simply picking one of the two solutions available to solve the problem.

But after rewriting all returns of string to Cow::from(""), the original error "borrowed value does not live long enough" was still there, and it didn't point me in the direction of line 61.

(I didn't expect this to work, as I figured the compiler still adds drop(string) at the end of the function, so it would be a problem either way, even if I didn't return string from the function)

Non-lexical lifetimes provide much better error messages sometimes; you can check it out by tossing #![feature(nll)] in your lib.rs and using nightly Rust. Maybe that helps?

Thanks Steve.

I believe I am using NLL now, but I'm not sure, I:

  • switched to nightly-2018-08-27-x86_64-apple-darwin (because latest nightly doesn't have RLS apparently)
  • validated with rustup which rls that the correct RLS version is in use
  • added #![feature(nll)] to lib.rs
  • updated VSCode to use the correct nightly version

but the compiler errors are the same (word for word), so either NLL doesn't influence these errors, or I did something wrong in enabling the feature (is there any way to tell if NLL is working as expected?)

I also tried the above without RLS/VS Code and simply did cargo build in both situations, giving equal output with or without the NLL attribute.