Skip to content

Implement AsRef, Borrow for std::cell::Ref, RefMut #215

Closed as not planned
Closed as not planned
@dhardy

Description

@dhardy

Proposal

Problem statement

Implement AsRef, Borrow for std::cell::Ref, RefMut.

Motivation, use-cases

Why? Because we can. This is what AsRef and Borrow are for? (More generally: any impl of Deref should impl AsRef too?)

Further motivation is that it appears we should be able to do the following.

trait Foo<T: ?Sized> {
    type Ref<'b>: std::borrow::Borrow<T>
    where
        Self: 'b;
        
    fn borrow(&self) -> Self::Ref<'_>;
}

struct MyCell(std::cell::RefCell<String>);
impl Foo<str> for MyCell {
    // error[E0277]: the trait bound `Ref<'b, str>: Borrow<str>` is not satisfied
    type Ref<'b> = std::cell::Ref<'b, str>;
    
    fn borrow(&self) -> Self::Ref<'_> {
        std::cell::Ref::map(self.0.borrow(), String::as_str)
    }
}

However, since std::cell::Ref does not implement Borrow<str>, we need <MyCell as Foo>::Ref to be a wrapper around std::cell::Ref like this:

struct MyStrRef<'b>(std::cell::Ref<'b, str>);
impl<'b> std::borrow::Borrow<str> for MyStrRef<'b> {
    fn borrow(&self) -> &str {
        &self.0
    }
}

impl Foo<str> for MyCell {
    // error[E0277]: the trait bound `Ref<'b, str>: Borrow<str>` is not satisfied
    type Ref<'b> = MyStrRef<'b>;
    
    fn borrow(&self) -> Self::Ref<'_> {
        MyStrRef(std::cell::Ref::map(self.0.borrow(), String::as_str))
    }
}

Here, MyStrRef is boilerplate which should not be necessary.

Solution

rust-lang/rust#101981

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions