Skip to content

Commit a63a201

Browse files
committed
Add the CoerceSized trait
- add the CoerceSized trait and set it up as a lang item Object safety still uses CoerceUnsized for now
1 parent 3e8c5bc commit a63a201

File tree

12 files changed

+62
-9
lines changed

12 files changed

+62
-9
lines changed

src/liballoc/boxed.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use core::fmt;
6363
use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
6464
use core::hash::{Hash, Hasher};
6565
use core::iter::FusedIterator;
66-
use core::marker::{Unpin, Unsize};
66+
use core::marker::{Unpin, Unsize, CoerceSized};
6767
use core::mem;
6868
use core::pin::PinMut;
6969
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
@@ -670,6 +670,9 @@ impl<'a, A, R> FnOnce<A> for Box<dyn FnBox<A, Output = R> + Send + 'a> {
670670
#[unstable(feature = "coerce_unsized", issue = "27732")]
671671
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
672672

673+
#[unstable(feature = "coerce_sized", issue = "0")]
674+
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<Box<T>> for Box<U> {}
675+
673676
#[stable(feature = "box_slice_clone", since = "1.3.0")]
674677
impl<T: Clone> Clone for Box<[T]> {
675678
fn clone(&self) -> Self {

src/liballoc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
#![feature(box_syntax)]
8989
#![feature(cfg_target_has_atomic)]
9090
#![feature(coerce_unsized)]
91+
#![feature(coerce_sized)]
9192
#![cfg_attr(stage0, feature(const_fn))]
9293
#![cfg_attr(not(stage0), feature(min_const_fn))]
9394
#![feature(core_intrinsics)]

src/liballoc/pin.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub use core::marker::Unpin;
9191
use core::convert::From;
9292
use core::fmt;
9393
use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
94-
use core::marker::Unsize;
94+
use core::marker::{Unsize, CoerceSized};
9595
use core::ops::{CoerceUnsized, Deref, DerefMut};
9696
use core::task::{Context, Poll};
9797

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

259+
#[unstable(feature = "coerce_sized", issue = "0")]
260+
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<PinBox<T>> for PinBox<U> {}
261+
262+
263+
259264
#[unstable(feature = "pin", issue = "49150")]
260265
impl<T: ?Sized> Unpin for PinBox<T> {}
261266

src/liballoc/rc.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ use core::fmt;
252252
use core::hash::{Hash, Hasher};
253253
use core::intrinsics::abort;
254254
use core::marker;
255-
use core::marker::{Unsize, PhantomData};
255+
use core::marker::{Unsize, CoerceSized, PhantomData};
256256
use core::mem::{self, align_of_val, forget, size_of_val};
257257
use core::ops::Deref;
258258
use core::ops::CoerceUnsized;
@@ -295,6 +295,9 @@ impl<T: ?Sized> !marker::Sync for Rc<T> {}
295295
#[unstable(feature = "coerce_unsized", issue = "27732")]
296296
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
297297

298+
#[unstable(feature = "coerce_sized", issue = "0")]
299+
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<Rc<T>> for Rc<U> {}
300+
298301
impl<T> Rc<T> {
299302
/// Constructs a new `Rc<T>`.
300303
///
@@ -1171,6 +1174,9 @@ impl<T: ?Sized> !marker::Sync for Weak<T> {}
11711174
#[unstable(feature = "coerce_unsized", issue = "27732")]
11721175
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
11731176

1177+
#[unstable(feature = "coerce_sized", issue = "0")]
1178+
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<Weak<T>> for Weak<U> {}
1179+
11741180
impl<T> Weak<T> {
11751181
/// Constructs a new `Weak<T>`, without allocating any memory.
11761182
/// Calling [`upgrade`] on the return value always gives [`None`].

src/liballoc/sync.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use core::mem::{self, align_of_val, size_of_val};
2727
use core::ops::Deref;
2828
use core::ops::CoerceUnsized;
2929
use core::ptr::{self, NonNull};
30-
use core::marker::{Unsize, PhantomData};
30+
use core::marker::{Unsize, CoerceSized, PhantomData};
3131
use core::hash::{Hash, Hasher};
3232
use core::{isize, usize};
3333
use core::convert::From;
@@ -212,6 +212,9 @@ unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
212212
#[unstable(feature = "coerce_unsized", issue = "27732")]
213213
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
214214

215+
#[unstable(feature = "coerce_sized", issue = "0")]
216+
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceSized<Arc<T>> for Arc<U> {}
217+
215218
/// `Weak` is a version of [`Arc`] that holds a non-owning reference to the
216219
/// managed value. The value is accessed by calling [`upgrade`] on the `Weak`
217220
/// pointer, which returns an [`Option`]`<`[`Arc`]`<T>>`.
@@ -252,6 +255,8 @@ unsafe impl<T: ?Sized + Sync + Send> Sync for Weak<T> {}
252255

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

256261
#[stable(feature = "arc_weak", since = "1.4.0")]
257262
impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> {

src/libcore/marker.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use cell::UnsafeCell;
2020
use cmp;
2121
use hash::Hash;
2222
use hash::Hasher;
23+
use ops::CoerceUnsized;
2324

2425
/// Types that can be transferred across thread boundaries.
2526
///
@@ -135,6 +136,34 @@ pub trait Unsize<T: ?Sized> {
135136
// Empty.
136137
}
137138

139+
/// Pointers to unsized types that can be coerced to a pointer to a sized type,
140+
/// as long as pointee is actually a value of that sized type. This is used for
141+
/// 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.
142+
///
143+
/// CoerceSized is implemented for:
144+
/// - &[T] is CoerceSized<&[T; N]> for any N
145+
/// - &Trait is CoerceSized<&T> for any T: Trait
146+
/// - and similarly for &mut T, *const T, *mut T, Box<T>, Rc<T>, Arc<T>
147+
#[unstable(feature = "coerce_sized", issue = "0")]
148+
#[cfg_attr(not(stage0), lang = "coerce_sized")]
149+
pub trait CoerceSized<T> where T: CoerceUnsized<Self> {
150+
// Empty.
151+
}
152+
153+
// &U -> &T
154+
#[unstable(feature = "coerce_sized", issue = "0")]
155+
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<&'a T> for &'a U {}
156+
// &mut U -> &mut T
157+
#[unstable(feature = "coerce_sized", issue = "0")]
158+
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<&'a mut T> for &'a mut U {}
159+
// *const U -> *const T
160+
#[unstable(feature = "coerce_sized", issue = "0")]
161+
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<*const T> for *const U {}
162+
// *mut U -> *mut T
163+
#[unstable(feature = "coerce_sized", issue = "0")]
164+
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<*mut T> for *mut U {}
165+
166+
138167
/// Types whose values can be duplicated simply by copying bits.
139168
///
140169
/// By default, variable bindings have 'move semantics.' In other

src/libcore/ops/unsize.rs

Lines changed: 1 addition & 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

src/libcore/pin.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
use fmt;
1010
use future::{Future, UnsafeFutureObj};
11-
use marker::{Sized, Unpin, Unsize};
11+
use marker::{Sized, Unpin, Unsize, CoerceSized};
1212
use task::{Context, Poll};
1313
use ops::{Deref, DerefMut, CoerceUnsized};
1414

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

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

src/librustc/middle/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ language_item_table! {
252252
DropTraitLangItem, "drop", drop_trait;
253253

254254
CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait;
255+
CoerceSizedTraitLangItem, "coerce_sized", coerce_sized_trait;
255256

256257
AddTraitLangItem, "add", add_trait;
257258
SubTraitLangItem, "sub", sub_trait;

src/llvm

Submodule llvm updated 2350 files

src/tools/clippy

0 commit comments

Comments
 (0)