Skip to content

Commit be80a79

Browse files
committed
Add CoerceSized trait and lang item
This trait is more-or-less the reverse of CoerceUnsized, and will be used for object-safety checks. Receiver types like `Rc` will have to implement `CoerceSized` so that methods that use `Rc<Self>` as the receiver will be considered object-safe.
1 parent a920036 commit be80a79

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

src/libcore/ops/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,6 @@ pub use self::generator::{Generator, GeneratorState};
201201

202202
#[unstable(feature = "coerce_unsized", issue = "27732")]
203203
pub use self::unsize::CoerceUnsized;
204+
205+
#[unstable(feature = "coerce_sized", issue = "0")]
206+
pub use self::unsize::CoerceSized;

src/libcore/ops/unsize.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use marker::Unsize;
4343
/// [nomicon-coerce]: ../../nomicon/coercions.html
4444
#[unstable(feature = "coerce_unsized", issue = "27732")]
4545
#[lang = "coerce_unsized"]
46-
pub trait CoerceUnsized<T> {
46+
pub trait CoerceUnsized<T: ?Sized> {
4747
// Empty.
4848
}
4949

@@ -77,3 +77,34 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
7777
// *const T -> *const U
7878
#[unstable(feature = "coerce_unsized", issue = "27732")]
7979
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
80+
81+
82+
/// Pointers to unsized types that can be coerced to a pointer to a sized type,
83+
/// as long as pointee is actually a value of that sized type. This is used for
84+
/// object safety, to check that a method's receiver type can be coerced from the version
85+
/// where `Self = dyn Trait` to the version where `Self = T`, the erased, sized type
86+
/// of the underlying object.
87+
///
88+
/// CoerceSized is implemented for:
89+
/// - &[T] is CoerceSized<&[T; N]> for any N
90+
/// - &Trait is CoerceSized<&T> for any T: Trait
91+
/// - and similarly for &mut T, *const T, *mut T, Box<T>, Rc<T>, Arc<T>
92+
#[unstable(feature = "coerce_sized", issue = "0")]
93+
#[cfg_attr(not(stage0), lang = "coerce_sized")]
94+
pub trait CoerceSized<T> where T: CoerceUnsized<Self> {
95+
// Empty.
96+
}
97+
98+
// &U -> &T
99+
#[unstable(feature = "coerce_sized", issue = "0")]
100+
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<&'a T> for &'a U {}
101+
// &mut U -> &mut T
102+
#[unstable(feature = "coerce_sized", issue = "0")]
103+
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<&'a mut T> for &'a mut U {}
104+
// *const U -> *const T
105+
#[unstable(feature = "coerce_sized", issue = "0")]
106+
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<*const T> for *const U {}
107+
// *mut U -> *mut T
108+
#[unstable(feature = "coerce_sized", issue = "0")]
109+
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<*mut T> for *mut U {}
110+

src/librustc/middle/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ language_item_table! {
271271
DropTraitLangItem, "drop", drop_trait, Target::Trait;
272272

273273
CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait, Target::Trait;
274+
CoerceSizedTraitLangItem, "coerce_sized", coerce_sized_trait, Target::Trait;
274275

275276
AddTraitLangItem, "add", add_trait, Target::Trait;
276277
SubTraitLangItem, "sub", sub_trait, Target::Trait;

0 commit comments

Comments
 (0)