about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/nonzero.rs4
-rw-r--r--src/libcore/ops/mod.rs3
-rw-r--r--src/libcore/ops/unsize.rs36
-rw-r--r--src/libcore/pin.rs8
-rw-r--r--src/libcore/ptr.rs8
5 files changed, 55 insertions, 4 deletions
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 118e75e1ee7..436cd1fc057 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -10,7 +10,7 @@
 
 //! Exposes the NonZero lang item which provides optimization hints.
 
-use ops::CoerceUnsized;
+use ops::{CoerceUnsized, DispatchFromDyn};
 
 /// 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: DispatchFromDyn<U>, U> DispatchFromDyn<NonZero<U>> for NonZero<T> {}
diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs
index ce4f45762de..edfa6df11ac 100644
--- a/src/libcore/ops/mod.rs
+++ b/src/libcore/ops/mod.rs
@@ -201,3 +201,6 @@ pub use self::generator::{Generator, GeneratorState};
 
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 pub use self::unsize::CoerceUnsized;
+
+#[unstable(feature = "dispatch_from_dyn", issue = "0")]
+pub use self::unsize::DispatchFromDyn;
diff --git a/src/libcore/ops/unsize.rs b/src/libcore/ops/unsize.rs
index da72f374842..4d9a40a1b90 100644
--- a/src/libcore/ops/unsize.rs
+++ b/src/libcore/ops/unsize.rs
@@ -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.
 }
 
@@ -77,3 +77,37 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
 // *const T -> *const U
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
+
+
+/// This is used for object safety, to check that a method's receiver type can be dispatched on.
+///
+/// example impl:
+///
+/// ```
+/// # #![feature(dispatch_from_dyn, unsize)]
+/// # use std::{ops::DispatchFromDyn, marker::Unsize};
+/// # struct Rc<T: ?Sized>(::std::rc::Rc<T>);
+/// impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T>
+/// where
+///     T: Unsize<U>,
+/// {}
+/// ```
+#[unstable(feature = "dispatch_from_dyn", issue = "0")]
+#[cfg_attr(not(stage0), lang = "dispatch_from_dyn")]
+pub trait DispatchFromDyn<T> {
+    // Empty.
+}
+
+// &T -> &U
+#[unstable(feature = "dispatch_from_dyn", issue = "0")]
+impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
+// &mut T -> &mut U
+#[unstable(feature = "dispatch_from_dyn", issue = "0")]
+impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
+// *const T -> *const U
+#[unstable(feature = "dispatch_from_dyn", issue = "0")]
+impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
+// *mut T -> *mut U
+#[unstable(feature = "dispatch_from_dyn", issue = "0")]
+impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
+
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index a03c080fb3f..68de82d2945 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -91,7 +91,7 @@
 
 use fmt;
 use marker::Sized;
-use ops::{Deref, DerefMut, CoerceUnsized};
+use ops::{Deref, DerefMut, CoerceUnsized, DispatchFromDyn};
 
 #[doc(inline)]
 pub use marker::Unpin;
@@ -325,4 +325,10 @@ where
 {}
 
 #[unstable(feature = "pin", issue = "49150")]
+impl<'a, P, U> DispatchFromDyn<Pin<U>> for Pin<P>
+where
+    P: DispatchFromDyn<U>,
+{}
+
+#[unstable(feature = "pin", issue = "49150")]
 impl<P> Unpin for Pin<P> {}
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 36852b10fac..62ccf6c865c 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -75,7 +75,7 @@
 
 use convert::From;
 use intrinsics;
-use ops::CoerceUnsized;
+use ops::{CoerceUnsized, DispatchFromDyn};
 use fmt;
 use hash;
 use marker::{PhantomData, Unsize};
@@ -2796,6 +2796,9 @@ impl<T: ?Sized> Copy for Unique<T> { }
 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> DispatchFromDyn<Unique<U>> for Unique<T> 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 {
         fmt::Pointer::fmt(&self.as_ptr(), f)
@@ -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 = "dispatch_from_dyn", issue = "0")]
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> 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 {