Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of an explicit lifetime for a method that doesn't take any arguments?

On page 295 of Programming Rust you can find the following:

Fortunately, the standard library includes the blanket implementation:

impl<'a, T, U> AsRef<U> for &'a T
where
    T: AsRef<U>,
    T: ?Sized,
    U: ?Sized,
{
    fn as_ref(&self) -> &U {
        (*self).as_ref()
    }
}

I'm confused at the use of &'a there. What is the context of that? It's not being used in an argument of as_ref nor tied to the output of &U. I don't think I fully understand lifetimes when used in this context.

I looked this up because I still didn't understand it and the answers still weren't clicking (making sense). I found convert.rs. This doesn't seem to have any lifetimes anywhere, but it implements the AsRef trait. So why does the book have this, and not the actual code in Rust? Where can I find the "blanket implementation" mentioned in the book?

like image 526
NO WAR WITH RUSSIA Avatar asked Nov 22 '25 03:11

NO WAR WITH RUSSIA


1 Answers

It's not being used in an argument of as_ref

It most certainly is. The function uses a shorthand notation, which can be expanded:

fn as_ref(&self) // becomes
fn as_ref(self: &Self) // becomes
fn as_ref(self: &&'a T)

nor tied to the output of &U

Correct.

So why does the book have this, and not the actual code in Rust?

Rust releases new stable versions every 6 weeks. Presumably the book does not, so it is likely that they are using an older version of Rust. Hopefully the book tells you the version they developed with.

As E_net4 already stated, the requirement to specify the 'a in this case was removed in Rust 1.31, as documented in the edition guide.

The code you provide from the book matches that found in Rust 1.30:

impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U>
{
    fn as_ref(&self) -> &U {
        <T as AsRef<U>>::as_ref(*self)
    }
}

The source code you looked at corresponds to Rust 1.37:

impl<T: ?Sized, U: ?Sized> AsRef<U> for &T where T: AsRef<U>
{
    fn as_ref(&self) -> &U {
        <T as AsRef<U>>::as_ref(*self)
    }
}

This is about 42 weeks of development time, plenty for the source code to have changed.

like image 125
Shepmaster Avatar answered Nov 24 '25 15:11

Shepmaster