Skip to content

Commit

Permalink
Add the CoerceSized trait
Browse files Browse the repository at this point in the history
- add the CoerceSized trait and set it up as a lang item

Object safety still uses CoerceUnsized for now
  • Loading branch information
mikeyhew committed Sep 4, 2018
1 parent 3e8c5bc commit a63a201
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 9 deletions.
5 changes: 4 additions & 1 deletion src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ use core::fmt;
use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
use core::hash::{Hash, Hasher};
use core::iter::FusedIterator;
use core::marker::{Unpin, Unsize};
use core::marker::{Unpin, Unsize, CoerceSized};
use core::mem;
use core::pin::PinMut;
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
Expand Down Expand Up @@ -670,6 +670,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
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
#![feature(box_syntax)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
#![feature(coerce_sized)]
#![cfg_attr(stage0, feature(const_fn))]
#![cfg_attr(not(stage0), feature(min_const_fn))]
#![feature(core_intrinsics)]
Expand Down
7 changes: 6 additions & 1 deletion src/liballoc/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub use core::marker::Unpin;
use core::convert::From;
use core::fmt;
use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
use core::marker::Unsize;
use core::marker::{Unsize, CoerceSized};
use core::ops::{CoerceUnsized, Deref, DerefMut};
use core::task::{Context, Poll};

Expand Down Expand Up @@ -256,6 +256,11 @@ impl<T: ?Sized> fmt::Pointer for PinBox<T> {
#[unstable(feature = "pin", issue = "49150")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}

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



#[unstable(feature = "pin", issue = "49150")]
impl<T: ?Sized> Unpin for PinBox<T> {}

Expand Down
8 changes: 7 additions & 1 deletion src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ use core::fmt;
use core::hash::{Hash, Hasher};
use core::intrinsics::abort;
use core::marker;
use core::marker::{Unsize, PhantomData};
use core::marker::{Unsize, CoerceSized, PhantomData};
use core::mem::{self, align_of_val, forget, size_of_val};
use core::ops::Deref;
use core::ops::CoerceUnsized;
Expand Down Expand Up @@ -295,6 +295,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 @@ -1171,6 +1174,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`] on the return value always gives [`None`].
Expand Down
7 changes: 6 additions & 1 deletion src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use core::mem::{self, align_of_val, size_of_val};
use core::ops::Deref;
use core::ops::CoerceUnsized;
use core::ptr::{self, NonNull};
use core::marker::{Unsize, PhantomData};
use core::marker::{Unsize, CoerceSized, PhantomData};
use core::hash::{Hash, Hasher};
use core::{isize, usize};
use core::convert::From;
Expand Down Expand Up @@ -212,6 +212,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 @@ -252,6 +255,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
2 changes: 1 addition & 1 deletion src/libcompiler_builtins
29 changes: 29 additions & 0 deletions src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use cell::UnsafeCell;
use cmp;
use hash::Hash;
use hash::Hasher;
use ops::CoerceUnsized;

/// Types that can be transferred across thread boundaries.
///
Expand Down Expand Up @@ -135,6 +136,34 @@ pub trait Unsize<T: ?Sized> {
// Empty.
}

/// Pointers to unsized types that can be coerced to a pointer to a sized type,
/// as long as pointee is actually a value of that sized type. This is used for
/// object safety, to check that a method's receiver type can be coerced from the version where Self is dyn Trait to the version where Self is the erased sized type T that implements Trait.
///
/// CoerceSized is implemented for:
/// - &[T] is CoerceSized<&[T; N]> for any N
/// - &Trait is CoerceSized<&T> for any T: Trait
/// - and similarly for &mut T, *const T, *mut T, Box<T>, Rc<T>, Arc<T>
#[unstable(feature = "coerce_sized", issue = "0")]
#[cfg_attr(not(stage0), lang = "coerce_sized")]
pub trait CoerceSized<T> where T: CoerceUnsized<Self> {
// Empty.
}

// &U -> &T
#[unstable(feature = "coerce_sized", issue = "0")]
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<&'a T> for &'a U {}
// &mut U -> &mut T
#[unstable(feature = "coerce_sized", issue = "0")]
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<&'a mut T> for &'a mut U {}
// *const U -> *const T
#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<*const T> for *const U {}
// *mut U -> *mut T
#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<*mut T> for *mut U {}


/// Types whose values can be duplicated simply by copying bits.
///
/// By default, variable bindings have 'move semantics.' In other
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/ops/unsize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use marker::Unsize;
/// [nomicon-coerce]: ../../nomicon/coercions.html
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T> {
pub trait CoerceUnsized<T: ?Sized> {
// Empty.
}

Expand Down
5 changes: 4 additions & 1 deletion src/libcore/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

use fmt;
use future::{Future, UnsafeFutureObj};
use marker::{Sized, Unpin, Unsize};
use marker::{Sized, Unpin, Unsize, CoerceSized};
use task::{Context, Poll};
use ops::{Deref, DerefMut, CoerceUnsized};

Expand Down Expand Up @@ -141,6 +141,9 @@ impl<'a, T: ?Sized> fmt::Pointer for PinMut<'a, T> {
#[unstable(feature = "pin", issue = "49150")]
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinMut<'a, U>> for PinMut<'a, T> {}

#[unstable(feature = "pin", issue = "49150")]
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<PinMut<'a, T>> for PinMut<'a, U> {}

#[unstable(feature = "pin", issue = "49150")]
impl<'a, T: ?Sized> Unpin for PinMut<'a, T> {}

Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ language_item_table! {
DropTraitLangItem, "drop", drop_trait;

CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait;
CoerceSizedTraitLangItem, "coerce_sized", coerce_sized_trait;

AddTraitLangItem, "add", add_trait;
SubTraitLangItem, "sub", sub_trait;
Expand Down
2 changes: 1 addition & 1 deletion src/llvm
Submodule llvm updated 2350 files
2 changes: 1 addition & 1 deletion src/tools/clippy

0 comments on commit a63a201

Please sign in to comment.