The following snippet is from rust source code for path.rs
impl AsRef<Path> for String {
fn as_ref(&self) -> &Path {
Path::new(self)
}
}
It seems to be returning a reference of a newly created Path
object from the stack frame. How does it bypass Rust's borrow checking rules? A stack object should have a lifetime for the current frame only and returning reference for temporary objects should produce an error.
The returned reference does not point to some object that is newly created inside of as_ref()
, but rather to the data of the string that was passed in as an argument.
Let's make the lifetimes in the relevant functions explicit. The prototype
fn as_ref(&self) -> &Path
can be desugared to
fn as_ref(&'a self) -> &'a Path
The type of self
is &'a String
, a reference to a string with lifetime 'a
.
Inside the function body, Path::new()
is called. According to the documentation, it is defined like this:
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &Path
Adding the elided lifetime gives
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &'a S) -> &'a Path
so the newly created Path
reference will have the same lifetime as the reference we passed in, which is exactly the required lifetime of the return value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With