Skip to content

Commit

Permalink
std: Add AsRef/AsMut impls to Box/Rc/Arc
Browse files Browse the repository at this point in the history
These common traits were left off originally by accident from these smart
pointers, and a past attempt (#26008) to add them was later reverted (#26160)
due to unexpected breakge (#26096) occurring. The specific breakage in worry is
the meaning of this return value changed:

    let a: Box<Option<T>> = ...;
    a.as_ref()

Currently this returns `Option<&T>` but after this change it will return
`&Option<T>` because the `AsRef::as_ref` method shares the same name as
`Option::as_ref`. A [crater report][crater] of this change, however, has shown
that the fallout of this change is quite minimal. These trait implementations
are "the right impls to add" to these smart pointers and would enable various
generalizations such as those in #27197.

[crater]: https://gist.github.com/anonymous/0ba4c3512b07641c0f99

This commit is a breaking change for the above reasons mentioned, and the
mitigation strategies look like any of:

    Option::as_ref(&a)
    a.as_ref().as_ref()
    (*a).as_ref()
  • Loading branch information
alexcrichton committed Oct 2, 2015
1 parent d9d9ca1 commit db76ac7
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1148,3 +1148,8 @@ impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {
&**self
}
}

#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
impl<T: ?Sized> AsRef<T> for Arc<T> {
fn as_ref(&self) -> &T { &**self }
}
10 changes: 10 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,3 +594,13 @@ impl<T: ?Sized> borrow::BorrowMut<T> for Box<T> {
&mut **self
}
}

#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
impl<T: ?Sized> AsRef<T> for Box<T> {
fn as_ref(&self) -> &T { &**self }
}

#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
impl<T: ?Sized> AsMut<T> for Box<T> {
fn as_mut(&mut self) -> &mut T { &mut **self }
}
5 changes: 5 additions & 0 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1117,3 +1117,8 @@ impl<T: ?Sized> borrow::Borrow<T> for Rc<T> {
&**self
}
}

#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
impl<T: ?Sized> AsRef<T> for Rc<T> {
fn as_ref(&self) -> &T { &**self }
}

0 comments on commit db76ac7

Please sign in to comment.