Skip to content
5 changes: 4 additions & 1 deletion 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::{Tuple, Move, Unsize};
use core::mem::{self, SizedTypeProperties};
use core::ops::{
AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut,
Expand Down Expand Up @@ -2132,3 +2132,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::{PhantomData, Move, 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::{PhantomData, Unsize, Move};
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::{PhantomData, Move};
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
16 changes: 16 additions & 0 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1366,3 +1366,19 @@ 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.
#[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} PhantomData<T>,
{T: ?Sized} *const T,
{T: ?Sized} *mut T,
{T: ?Sized} &T,
{T: ?Sized} &mut T,
}
9 changes: 9 additions & 0 deletions library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,15 @@ where
}
}

#[unstable(feature = "move_trait", issue = "none")]
unsafe impl<K, V, S> core::marker::Move for HashMap<K, V, S>
where
K: Eq + Hash,
V: Eq,
S: BuildHasher,
{
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<K, V, S> Eq for HashMap<K, V, S>
where
Expand Down
8 changes: 8 additions & 0 deletions library/std/src/collections/hash/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,14 @@ where
{
}

#[unstable(feature = "move_trait", issue = "none")]
unsafe impl<T, S> core::marker::Move for HashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, S> fmt::Debug for HashSet<T, S>
where
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@
#![feature(lazy_get)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_write_slice)]
#![feature(move_trait)]
#![feature(panic_can_unwind)]
#![feature(panic_internals)]
#![feature(pin_coerce_unsized_trait)]
Expand Down
Loading