Add CoerceSized impls throughout libstd

This will make receiver types like `Rc<Self>` and `Pin<&mut Self>`
object-safe.
This commit is contained in:
Michael Hewson 2018-09-20 03:18:00 -04:00
parent 9f59da2864
commit 192900e7c2
7 changed files with 36 additions and 6 deletions

View File

@ -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};
@ -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 {

View File

@ -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)]

View File

@ -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;
@ -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>`.
///
@ -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`].

View File

@ -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};
@ -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>>`.
@ -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> {

View File

@ -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.
@ -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> {}

View File

@ -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;
@ -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> {}

View File

@ -75,7 +75,7 @@
use convert::From;
use intrinsics;
use ops::CoerceUnsized;
use ops::{CoerceUnsized, CoerceSized};
use fmt;
use hash;
use marker::{PhantomData, Unsize};
@ -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 {
@ -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 {