use std::borrow::Cow;
use std::ops::Range;
pub struct F {
s: String,
}
impl F {
pub fn get_content(&self) -> Cow<str> {
Cow::Borrowed(&self.s)
}
pub fn get_span(&self, span: Range<usize>) -> Option<Cow<str>> {
self.get_content().get(span).map(|s| Cow::Borrowed(s))
}
}
This, of course, raises a borrow error:
error[E0515]: cannot return value referencing temporary value
--> <source>:14:9
|
14 | self.get_content().get(span).map(|s| Cow::Borrowed(s))
| ------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| temporary value created here
error: aborting due to previous error
Even with explicit lifetimes it won't compile.
In my understanding this should be safe and possible, because get_content is ties to self, but get_span is tied to self as well, and calling &'a self should return a Cow<'a, str>, doesn't it?
The problem is that get_content might return a Cow::Owned, in which case in get_span you're gonna return a non-owned Cow that references a value that will be freed at the end of the function.
Concretely, the Deref impl for Cow ties the lifetime of the returned reference to that of the &Cow itself (that's the only possible way due to the signature of Deref::deref()). I.e., for Cow<'a, str>, its deref impl returns &'self str, and not&'a str.