Skip to content
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2241,7 +2241,7 @@ options! {
"Use WebAssembly error handling for wasm32-unknown-emscripten"),
enforce_type_length_limit: bool = (false, parse_bool, [TRACKED],
"enforce the type length limit when monomorphizing instances in codegen"),
experimental_default_bounds: bool = (false, parse_bool, [TRACKED],
experimental_default_bounds: bool = (true, parse_bool, [TRACKED],
"enable default bounds for experimental group of auto traits"),
export_executable_symbols: bool = (false, parse_bool, [TRACKED],
"export symbols from executables, as if they were dynamic libraries"),
Expand Down
10 changes: 8 additions & 2 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ use core::error::{self, Error};
use core::fmt;
use core::future::Future;
use core::hash::{Hash, Hasher};
use core::marker::{Tuple, Unsize};
use core::marker::{Move, Tuple, Unsize};
use core::mem::{self, SizedTypeProperties};
use core::ops::{
AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut,
Expand Down Expand Up @@ -2025,7 +2025,10 @@ unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Box<T, A> {}
// Handling arbitrary custom allocators (which can affect the `Box` layout heavily!)
// would need a lot of codegen and interpreter adjustments.
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T, Global> {}
impl<T: ?Sized + Unsize<U>, U: ?Sized + ?core::marker::Sized> DispatchFromDyn<Box<U>>
for Box<T, Global>
{
}

#[stable(feature = "box_borrow", since = "1.1.0")]
impl<T: ?Sized, A: Allocator> Borrow<T> for Box<T, A> {
Expand Down Expand Up @@ -2132,3 +2135,6 @@ impl<E: Error> Error for Box<E> {
Error::provide(&**self, request);
}
}

#[unstable(feature = "move_trait", issue = "none")]
unsafe impl<T: ?Sized> Move for Box<T> {}
3 changes: 3 additions & 0 deletions library/alloc/src/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V, A: Allocator + Clone> Drop for BTr
}
}

#[unstable(feature = "move_trait", issue = "none")]
unsafe impl<K, V, A: Allocator + Clone> core::marker::Move for BTreeMap<K, V, A> {}

// FIXME: This implementation is "wrong", but changing it would be a breaking change.
// (The bounds of the automatic `UnwindSafe` implementation have been like this since Rust 1.50.)
// Maybe we can fix it nonetheless with a crater run, or if the `UnwindSafe`
Expand Down
3 changes: 3 additions & 0 deletions library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3025,6 +3025,9 @@ impl<T, A: Allocator> IndexMut<usize> for VecDeque<T, A> {
}
}

#[unstable(feature = "move_trait", issue = "none")]
unsafe impl<T, A: Allocator> core::marker::Move for VecDeque<T, A> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> FromIterator<T> for VecDeque<T> {
#[track_caller]
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
#![feature(local_waker)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(move_trait)]
#![feature(panic_internals)]
#![feature(pattern)]
#![feature(pin_coerce_unsized_trait)]
Expand Down
5 changes: 4 additions & 1 deletion library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ use core::hash::{Hash, Hasher};
use core::intrinsics::abort;
#[cfg(not(no_global_oom_handling))]
use core::iter;
use core::marker::{PhantomData, Unsize};
use core::marker::{Move, PhantomData, Unsize};
use core::mem::{self, ManuallyDrop, align_of_val_raw};
use core::num::NonZeroUsize;
use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver};
Expand Down Expand Up @@ -2277,6 +2277,9 @@ unsafe impl<T: ?Sized, A: Allocator> DerefPure for UniqueRc<T, A> {}
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
impl<T: ?Sized> LegacyReceiver for Rc<T> {}

#[unstable(feature = "move_trait", issue = "none")]
unsafe impl<T: ?Sized, A: Allocator> Move for Rc<T, A> {}

#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Rc<T, A> {
/// Drops the `Rc`.
Expand Down
4 changes: 3 additions & 1 deletion library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use core::hash::{Hash, Hasher};
use core::intrinsics::abort;
#[cfg(not(no_global_oom_handling))]
use core::iter;
use core::marker::{PhantomData, Unsize};
use core::marker::{Move, PhantomData, Unsize};
use core::mem::{self, ManuallyDrop, align_of_val_raw};
use core::num::NonZeroUsize;
use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver};
Expand Down Expand Up @@ -271,6 +271,8 @@ pub struct Arc<
unsafe impl<T: ?Sized + Sync + Send, A: Allocator + Send> Send for Arc<T, A> {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: ?Sized + Sync + Send, A: Allocator + Sync> Sync for Arc<T, A> {}
#[unstable(feature = "move_trait", issue = "none")]
unsafe impl<T: ?Sized, A: Allocator> Move for Arc<T, A> {}

#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized, A: Allocator + UnwindSafe> UnwindSafe for Arc<T, A> {}
Expand Down
5 changes: 4 additions & 1 deletion library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ use core::cmp::Ordering;
use core::hash::{Hash, Hasher};
#[cfg(not(no_global_oom_handling))]
use core::iter;
use core::marker::PhantomData;
use core::marker::{Move, PhantomData};
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
use core::ops::{self, Index, IndexMut, Range, RangeBounds};
use core::ptr::{self, NonNull};
Expand Down Expand Up @@ -3908,6 +3908,9 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> {
}
}

#[unstable(feature = "move_trait", issue = "none")]
unsafe impl<T> Move for Vec<T> {}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T> const Default for Vec<T> {
Expand Down
1 change: 1 addition & 0 deletions library/alloctests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#![feature(int_format_into)]
#![feature(linked_list_cursors)]
#![feature(map_try_insert)]
#![feature(move_trait)]
#![feature(pattern)]
#![feature(trusted_len)]
#![feature(try_reserve_kind)]
Expand Down
18 changes: 9 additions & 9 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@

use crate::cmp::Ordering;
use crate::fmt::{self, Debug, Display};
use crate::marker::{PhantomData, Unsize};
use crate::marker::{Move, PhantomData, Unsize};
use crate::mem;
use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
use crate::panic::const_panic;
Expand Down Expand Up @@ -309,7 +309,7 @@ pub use once::OnceCell;
#[stable(feature = "rust1", since = "1.0.0")]
#[repr(transparent)]
#[rustc_pub_transparent]
pub struct Cell<T: ?Sized> {
pub struct Cell<T: ?Sized + ?Move> {
value: UnsafeCell<T>,
}

Expand All @@ -322,7 +322,7 @@ unsafe impl<T: ?Sized> Send for Cell<T> where T: Send {}
// having an explicit negative impl is nice for documentation purposes
// and results in nicer error messages.
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !Sync for Cell<T> {}
impl<T: ?Sized + ?Move> !Sync for Cell<T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Copy> Clone for Cell<T> {
Expand Down Expand Up @@ -668,7 +668,7 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
// `self: Cell<&Self>` won't work
// `self: CellWrapper<Self>` becomes possible
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Cell<U>> for Cell<T> {}
impl<T: DispatchFromDyn<U>, U: ?Move> DispatchFromDyn<Cell<U>> for Cell<T> {}

impl<T> Cell<[T]> {
/// Returns a `&[Cell<T>]` from a `&Cell<[T]>`
Expand Down Expand Up @@ -2090,12 +2090,12 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
#[stable(feature = "rust1", since = "1.0.0")]
#[repr(transparent)]
#[rustc_pub_transparent]
pub struct UnsafeCell<T: ?Sized> {
pub struct UnsafeCell<T: ?Sized + ?Move> {
value: T,
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !Sync for UnsafeCell<T> {}
impl<T: ?Sized + ?Move> !Sync for UnsafeCell<T> {}

impl<T> UnsafeCell<T> {
/// Constructs a new instance of `UnsafeCell` which will wrap the specified
Expand Down Expand Up @@ -2359,7 +2359,7 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
// `self: UnsafeCell<&Self>` won't work
// `self: UnsafeCellWrapper<Self>` becomes possible
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}
impl<T: DispatchFromDyn<U>, U: ?Move> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}

/// [`UnsafeCell`], but [`Sync`].
///
Expand All @@ -2377,7 +2377,7 @@ impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T>
#[repr(transparent)]
#[rustc_diagnostic_item = "SyncUnsafeCell"]
#[rustc_pub_transparent]
pub struct SyncUnsafeCell<T: ?Sized> {
pub struct SyncUnsafeCell<T: ?Sized + ?Move> {
value: UnsafeCell<T>,
}

Expand Down Expand Up @@ -2466,7 +2466,7 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell
// `self: SyncUnsafeCellWrapper<Self>` becomes possible
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
impl<T: DispatchFromDyn<U>, U: ?Move> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}

#[allow(unused)]
fn assert_coerce_unsized(
Expand Down
25 changes: 21 additions & 4 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ pub trait PointeeSized {
#[lang = "unsize"]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
pub trait Unsize<T: PointeeSized>: PointeeSized {
pub trait Unsize<T: PointeeSized + ?crate::marker::Move>: PointeeSized {
// Empty.
}

Expand Down Expand Up @@ -820,7 +820,7 @@ impl<T: PointeeSized> !Sync for *mut T {}
/// [drop check]: Drop#drop-check
#[lang = "phantom_data"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct PhantomData<T: PointeeSized>;
pub struct PhantomData<T: PointeeSized + ?crate::marker::Move>;

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: PointeeSized> Hash for PhantomData<T> {
Expand Down Expand Up @@ -914,7 +914,7 @@ pub trait DiscriminantKind {
pub unsafe auto trait Freeze {}

#[unstable(feature = "freeze", issue = "121675")]
impl<T: PointeeSized> !Freeze for UnsafeCell<T> {}
impl<T: PointeeSized + ?crate::marker::Move> !Freeze for UnsafeCell<T> {}
marker_impls! {
#[unstable(feature = "freeze", issue = "121675")]
unsafe Freeze for
Expand All @@ -934,7 +934,7 @@ marker_impls! {
#[lang = "unsafe_unpin"]
pub(crate) unsafe auto trait UnsafeUnpin {}

impl<T: ?Sized> !UnsafeUnpin for UnsafePinned<T> {}
impl<T: ?Sized + ?crate::marker::Move> !UnsafeUnpin for UnsafePinned<T> {}
unsafe impl<T: ?Sized> UnsafeUnpin for PhantomData<T> {}
unsafe impl<T: ?Sized> UnsafeUnpin for *const T {}
unsafe impl<T: ?Sized> UnsafeUnpin for *mut T {}
Expand Down Expand Up @@ -1366,3 +1366,20 @@ pub macro CoercePointee($item:item) {
pub trait CoercePointeeValidated {
/* compiler built-in */
}

/// Types that do not require a stable memory address, and so can be freely
/// `move`d.
#[lang = "default_trait1"]
#[rustc_unsafe_specialization_marker]
#[unstable(feature = "move_trait", issue = "none")]
pub unsafe auto trait Move {
// empty.
}
marker_impls! {
#[unstable(feature = "move_trait", issue = "none")]
unsafe Move for
{T: ?Sized} *const T,
{T: ?Sized} *mut T,
{T: ?Sized} &T,
{T: ?Sized} &mut T,
}
54 changes: 39 additions & 15 deletions library/core/src/ops/unsize.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::marker::{PointeeSized, Unsize};
use crate::marker::{Move, PointeeSized, Unsize};

/// Trait that indicates that this is a pointer or a wrapper for one,
/// where unsizing can be performed on the pointee.
Expand Down Expand Up @@ -39,34 +39,46 @@ pub trait CoerceUnsized<T: PointeeSized> {

// &mut T -> &mut U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {}
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U>
for &'a mut T
{
}
// &mut T -> &U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b mut T {}
impl<'a, 'b: 'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U>
for &'b mut T
{
}
// &mut T -> *mut U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for &'a mut T {}
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for &'a mut T {}
// &mut T -> *const U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a mut T {}
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U>
for &'a mut T
{
}

// &T -> &U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {}
impl<'a, 'b: 'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U>
for &'b T
{
}
// &T -> *const U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a T {}
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a T {}

// *mut T -> *mut U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {}
impl<T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {}
// *mut T -> *const U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *mut T {}
impl<T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *mut T {}

// *const T -> *const U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {}
impl<T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {}

/// `DispatchFromDyn` is used in the implementation of dyn-compatibility[^1] checks (specifically
/// allowing arbitrary self types), to guarantee that a method's receiver type can be dispatched on.
Expand Down Expand Up @@ -116,19 +128,31 @@ impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *
/// [^1]: Formerly known as *object safety*.
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
#[lang = "dispatch_from_dyn"]
pub trait DispatchFromDyn<T> {
pub trait DispatchFromDyn<T: ?Move> {
// Empty.
}

// &T -> &U
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {}
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized + ?Move> DispatchFromDyn<&'a U>
for &'a T
{
}
// &mut T -> &mut U
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {}
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized + ?Move> DispatchFromDyn<&'a mut U>
for &'a mut T
{
}
// *const T -> *const U
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {}
impl<T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized + ?Move> DispatchFromDyn<*const U>
for *const T
{
}
// *mut T -> *mut U
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {}
impl<T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized + ?Move> DispatchFromDyn<*mut U>
for *mut T
{
}
2 changes: 1 addition & 1 deletion library/core/src/panic/unwind_safe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ impl<T> UnwindSafe for AssertUnwindSafe<T> {}
// only thing which doesn't implement it (which then transitively applies to
// everything else).
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
impl<T: ?Sized + ?crate::marker::Move> !RefUnwindSafe for UnsafeCell<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}

Expand Down
4 changes: 2 additions & 2 deletions library/core/src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,7 @@ pub use self::unsafe_pinned::UnsafePinned;
#[repr(transparent)]
#[rustc_pub_transparent]
#[derive(Copy, Clone)]
pub struct Pin<Ptr> {
pub struct Pin<Ptr: ?crate::marker::Move> {
pointer: Ptr,
}

Expand Down Expand Up @@ -1727,7 +1727,7 @@ where
impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr>
where
Ptr: DispatchFromDyn<U> + PinCoerceUnsized,
U: PinCoerceUnsized,
U: PinCoerceUnsized + ?crate::marker::Move,
{
}

Expand Down
Loading
Loading