Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does returning a reference to Path from the function's stack work?

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.

like image 824
jittrfunc Avatar asked Dec 14 '18 19:12

jittrfunc


1 Answers

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.

like image 79
Sven Marnach Avatar answered Sep 18 '22 10:09

Sven Marnach