Skip to content

Add Borrow and AsRef implementations to LazyCell and LazyLock #477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rick-de-water opened this issue Nov 6, 2024 · 3 comments
Closed
Labels
api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api

Comments

@rick-de-water
Copy link

Proposal

Problem statement

LazyCell and LazyLock are types that greatly simplify (often static) initialization, allowing the programmer to not worry about when a value is initialized, and simply treat it as if it is always initialized instead. While these types do implement the Deref trait, they lack AsRef and Borrow implementations. This can lead to a lot of &* prefixing in places where it could be avoided.

Motivating examples or use cases

As stated, the goal is to reduce the amount of &* prefixing. This is usually accomplished by asking for a impl AsRef<T> or impl Borrow<T> instead of &T directly. By implementing these traits for LazyCell and LazyLock, they will also be compatible with this technique.

use std::sync::LazyLock;
use std::borrow::Borrow;

struct User {
    name: String,
    active: bool
}

static USER: LazyLock<User> = LazyLock::new(|| {
    User {
        name: "Foo".to_owned(),
        active: true
    }
});

fn print_if_active(user: impl Borrow<User>) {
    let user = user.borrow();
    if user.active {
        println!("{}", user.name);
    }
}

fn main() {
    // What I have to do:
    print_if_active(&*USER);
    
    // What I want to do:
    //print_if_active(&USER);
}

One might argue that AsRef and Borrow should be cheap, and the first call to them might call a heavy function. But I believe that ship has already sailed, since they both already implement Deref.

Solution sketch

Add impl<T> AsRef<T> for LazyCell<T> and impl<T> AsRef<T> for LazyLock<T>, which both probably just call the Deref::deref to not have to deal with any internals.

Alternatives

I can't really think of any alternatives, other than keeping the more verbose &* prefixes.

Links and related work

What happens now?

This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.

Possible responses

The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):

  • We think this problem seems worth solving, and the standard library might be the right place to solve it.
  • We think that this probably doesn't belong in the standard library.

Second, if there's a concrete solution:

  • We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
  • We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.
@rick-de-water rick-de-water added api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api labels Nov 6, 2024
@rick-de-water rick-de-water changed the title Add Borrow and AsRef implementations to LazyCell and LazyLock Add Borrow and AsRef implementations to LazyCell and LazyLock Nov 6, 2024
@kennytm
Copy link
Member

kennytm commented Nov 6, 2024

i think the justification to reject #215 also applies here.

@rick-de-water
Copy link
Author

Yes, if reducing boilerplate is not enough of an argument then the rejection applies to this issue as well.

@joshtriplett
Copy link
Member

We reviewed this in today's libs-api meeting, and agreed that we need to reject this for the same reason as #215 : this would cause breakage if the inner type T implements AsRef.

Thanks @kennytm!

@dtolnay dtolnay closed this as not planned Won't fix, can't repro, duplicate, stale Mar 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api
Projects
None yet
Development

No branches or pull requests

4 participants