Skip to content

Commit

Permalink
Add CoerceSized impls throughout libstd
Browse files Browse the repository at this point in the history
This will make receiver types like `Rc<Self>` and `Pin<&mut Self>`
object-safe.
  • Loading branch information
mikeyhew committed Nov 1, 2018
1 parent 9f59da2 commit 192900e
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 6 deletions.
5 changes: 4 additions & 1 deletion src/liballoc/boxed.rs
Expand Up @@ -77,7 +77,7 @@ use core::iter::FusedIterator;
use core::marker::{Unpin, Unsize};
use core::mem;
use core::pin::Pin;
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
use core::ops::{CoerceUnsized, CoerceSized, Deref, DerefMut, Generator, GeneratorState};
use core::ptr::{self, NonNull, Unique};
use core::task::{LocalWaker, Poll};

Expand Down Expand Up @@ -696,6 +696,9 @@ impl<'a, A, R> FnOnce<A> for Box<dyn FnBox<A, Output = R> + Send + 'a> {
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}

#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<Box<T>> for Box<U> {}

#[stable(feature = "box_slice_clone", since = "1.3.0")]
impl<T: Clone> Clone for Box<[T]> {
fn clone(&self) -> Self {
Expand Down
1 change: 1 addition & 0 deletions src/liballoc/lib.rs
Expand Up @@ -86,6 +86,7 @@
#![feature(box_syntax)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
#![feature(coerce_sized)]
#![feature(core_intrinsics)]
#![feature(custom_attribute)]
#![feature(dropck_eyepatch)]
Expand Down
8 changes: 7 additions & 1 deletion src/liballoc/rc.rs
Expand Up @@ -255,7 +255,7 @@ use core::marker;
use core::marker::{Unpin, Unsize, PhantomData};
use core::mem::{self, align_of_val, forget, size_of_val};
use core::ops::Deref;
use core::ops::CoerceUnsized;
use core::ops::{CoerceUnsized, CoerceSized};
use core::pin::Pin;
use core::ptr::{self, NonNull};
use core::convert::From;
Expand Down Expand Up @@ -297,6 +297,9 @@ impl<T: ?Sized> !marker::Sync for Rc<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}

#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<Rc<T>> for Rc<U> {}

impl<T> Rc<T> {
/// Constructs a new `Rc<T>`.
///
Expand Down Expand Up @@ -1176,6 +1179,9 @@ impl<T: ?Sized> !marker::Sync for Weak<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}

#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<Weak<T>> for Weak<U> {}

impl<T> Weak<T> {
/// Constructs a new `Weak<T>`, without allocating any memory.
/// Calling [`upgrade`][Weak::upgrade] on the return value always gives [`None`].
Expand Down
7 changes: 6 additions & 1 deletion src/liballoc/sync.rs
Expand Up @@ -25,7 +25,7 @@ use core::cmp::Ordering;
use core::intrinsics::abort;
use core::mem::{self, align_of_val, size_of_val};
use core::ops::Deref;
use core::ops::CoerceUnsized;
use core::ops::{CoerceUnsized, CoerceSized};
use core::pin::Pin;
use core::ptr::{self, NonNull};
use core::marker::{Unpin, Unsize, PhantomData};
Expand Down Expand Up @@ -214,6 +214,9 @@ unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}

#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<Arc<T>> for Arc<U> {}

/// `Weak` is a version of [`Arc`] that holds a non-owning reference to the
/// managed value. The value is accessed by calling [`upgrade`] on the `Weak`
/// pointer, which returns an [`Option`]`<`[`Arc`]`<T>>`.
Expand Down Expand Up @@ -254,6 +257,8 @@ unsafe impl<T: ?Sized + Sync + Send> Sync for Weak<T> {}

#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<Weak<T>> for Weak<U> {}

#[stable(feature = "arc_weak", since = "1.4.0")]
impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> {
Expand Down
4 changes: 3 additions & 1 deletion src/libcore/nonzero.rs
Expand Up @@ -10,7 +10,7 @@

//! Exposes the NonZero lang item which provides optimization hints.

use ops::CoerceUnsized;
use ops::{CoerceUnsized, CoerceSized};

/// A wrapper type for raw pointers and integers that will never be
/// NULL or 0 that might allow certain optimizations.
Expand All @@ -20,3 +20,5 @@ use ops::CoerceUnsized;
pub(crate) struct NonZero<T>(pub(crate) T);

impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {}

impl<T: CoerceUnsized<U>, U: CoerceSized<T>> CoerceSized<NonZero<T>> for NonZero<U> {}
9 changes: 8 additions & 1 deletion src/libcore/pin.rs
Expand Up @@ -91,7 +91,7 @@

use fmt;
use marker::Sized;
use ops::{Deref, DerefMut, CoerceUnsized};
use ops::{Deref, DerefMut, CoerceUnsized, CoerceSized};

#[doc(inline)]
pub use marker::Unpin;
Expand Down Expand Up @@ -324,5 +324,12 @@ where
P: CoerceUnsized<U>,
{}

#[unstable(feature = "pin", issue = "49150")]
impl<'a, P, U> CoerceSized<Pin<P>> for Pin<U>
where
P: CoerceUnsized<U>,
U: CoerceSized<P>,
{}

#[unstable(feature = "pin", issue = "49150")]
impl<P> Unpin for Pin<P> {}
8 changes: 7 additions & 1 deletion src/libcore/ptr.rs
Expand Up @@ -75,7 +75,7 @@

use convert::From;
use intrinsics;
use ops::CoerceUnsized;
use ops::{CoerceUnsized, CoerceSized};
use fmt;
use hash;
use marker::{PhantomData, Unsize};
Expand Down Expand Up @@ -2795,6 +2795,9 @@ impl<T: ?Sized> Copy for Unique<T> { }
#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { }

#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized, U: ?Sized> CoerceSized<Unique<T>> for Unique<U> where T: Unsize<U> { }

#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> fmt::Pointer for Unique<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down Expand Up @@ -2951,6 +2954,9 @@ impl<T: ?Sized> Copy for NonNull<T> { }
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }

#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized, U: ?Sized> CoerceSized<NonNull<T>> for NonNull<U> where T: Unsize<U> { }

#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> fmt::Debug for NonNull<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down

0 comments on commit 192900e

Please sign in to comment.