Skip to content

Commit 57b058a

Browse files
Auto merge of #146201 - lcnr:move-trait, r=<try>
[DO NOT MERGE] `Move` trait perf test
2 parents 8e2ed71 + 319f0b2 commit 57b058a

File tree

16 files changed

+120
-50
lines changed

16 files changed

+120
-50
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
231231
}
232232
}
233233

234-
/// Adds `experimental_default_bounds` bounds to the supertrait bounds.
234+
/// Sets `experimental_default_bounds` to true on trait super bounds.
235235
pub(crate) fn add_default_super_traits(
236236
&self,
237237
trait_def_id: LocalDefId,
@@ -242,8 +242,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
242242
) {
243243
assert_matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias);
244244

245-
// Supertraits for auto trait are unsound according to the unstable book:
246-
// https://doc.rust-lang.org/beta/unstable-book/language-features/auto-traits.html#supertraits
247245
if self.tcx().trait_is_auto(trait_def_id.to_def_id()) {
248246
return;
249247
}

compiler/rustc_session/src/options.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2307,7 +2307,7 @@ options! {
23072307
"Use WebAssembly error handling for wasm32-unknown-emscripten"),
23082308
enforce_type_length_limit: bool = (false, parse_bool, [TRACKED],
23092309
"enforce the type length limit when monomorphizing instances in codegen"),
2310-
experimental_default_bounds: bool = (false, parse_bool, [TRACKED],
2310+
experimental_default_bounds: bool = (true, parse_bool, [TRACKED],
23112311
"enable default bounds for experimental group of auto traits"),
23122312
export_executable_symbols: bool = (false, parse_bool, [TRACKED],
23132313
"export symbols from executables, as if they were dynamic libraries"),

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
474474
}
475475
} else {
476476
let has_non_region_infer = stack.obligation.predicate.has_non_region_infer();
477-
if let Some(candidate) = self.winnow_candidates(has_non_region_infer, candidates) {
477+
let is_default_auto_trait = self
478+
.tcx()
479+
.as_lang_item(stack.obligation.predicate.def_id())
480+
.is_some_and(|lang_item| matches!(lang_item, LangItem::DefaultTrait1));
481+
if let Some(candidate) =
482+
self.winnow_candidates(has_non_region_infer, is_default_auto_trait, candidates)
483+
{
478484
self.filter_reservation_impls(candidate)
479485
} else {
480486
Ok(None)
@@ -1821,15 +1827,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18211827
fn winnow_candidates(
18221828
&mut self,
18231829
has_non_region_infer: bool,
1830+
is_default_auto_trait: bool,
18241831
mut candidates: Vec<EvaluatedCandidate<'tcx>>,
18251832
) -> Option<SelectionCandidate<'tcx>> {
18261833
if candidates.len() == 1 {
18271834
return Some(candidates.pop().unwrap().candidate);
18281835
}
18291836

18301837
// We prefer `Sized` candidates over everything.
1831-
let mut sized_candidates =
1832-
candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate));
1838+
let mut sized_candidates = candidates.iter().filter(|c| {
1839+
matches!(c.candidate, SizedCandidate)
1840+
|| (is_default_auto_trait
1841+
&& matches!(c.candidate, AutoImplCandidate | ImplCandidate(..)))
1842+
});
18331843
if let Some(sized_candidate) = sized_candidates.next() {
18341844
// There should only ever be a single sized candidate
18351845
// as they would otherwise overlap.

library/alloc/src/boxed.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2039,7 +2039,10 @@ unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Box<T, A> {}
20392039
// Handling arbitrary custom allocators (which can affect the `Box` layout heavily!)
20402040
// would need a lot of codegen and interpreter adjustments.
20412041
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
2042-
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T, Global> {}
2042+
impl<T: ?Sized + Unsize<U> + ?core::marker::Move, U: ?Sized + ?core::marker::Move>
2043+
DispatchFromDyn<Box<U>> for Box<T, Global>
2044+
{
2045+
}
20432046

20442047
#[stable(feature = "box_borrow", since = "1.1.0")]
20452048
impl<T: ?Sized, A: Allocator> Borrow<T> for Box<T, A> {
@@ -2141,3 +2144,6 @@ impl<E: Error> Error for Box<E> {
21412144
Error::provide(&**self, request);
21422145
}
21432146
}
2147+
2148+
#[unstable(feature = "move_trait", issue = "none")]
2149+
unsafe impl<T: ?Sized + ?core::marker::Move, A: Allocator> core::marker::Move for Box<T, A> {}

library/alloc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
#![feature(local_waker)]
134134
#![feature(maybe_uninit_slice)]
135135
#![feature(maybe_uninit_uninit_array_transpose)]
136+
#![feature(move_trait)]
136137
#![feature(panic_internals)]
137138
#![feature(pattern)]
138139
#![feature(pin_coerce_unsized_trait)]

library/alloctests/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#![feature(int_format_into)]
1414
#![feature(linked_list_cursors)]
1515
#![feature(map_try_insert)]
16+
#![feature(move_trait)]
1617
#![feature(pattern)]
1718
#![feature(trusted_len)]
1819
#![feature(try_reserve_kind)]

library/core/src/cell.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@
252252

253253
use crate::cmp::Ordering;
254254
use crate::fmt::{self, Debug, Display};
255-
use crate::marker::{PhantomData, Unsize};
255+
use crate::marker::{Move, PhantomData, Unsize};
256256
use crate::mem;
257257
use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
258258
use crate::panic::const_panic;
@@ -309,7 +309,7 @@ pub use once::OnceCell;
309309
#[stable(feature = "rust1", since = "1.0.0")]
310310
#[repr(transparent)]
311311
#[rustc_pub_transparent]
312-
pub struct Cell<T: ?Sized> {
312+
pub struct Cell<T: ?Sized + ?Move> {
313313
value: UnsafeCell<T>,
314314
}
315315

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

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

674674
impl<T> Cell<[T]> {
675675
/// Returns a `&[Cell<T>]` from a `&Cell<[T]>`
@@ -2185,12 +2185,12 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
21852185
#[stable(feature = "rust1", since = "1.0.0")]
21862186
#[repr(transparent)]
21872187
#[rustc_pub_transparent]
2188-
pub struct UnsafeCell<T: ?Sized> {
2188+
pub struct UnsafeCell<T: ?Sized + ?Move> {
21892189
value: T,
21902190
}
21912191

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

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

24602460
/// [`UnsafeCell`], but [`Sync`].
24612461
///
@@ -2473,7 +2473,7 @@ impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T>
24732473
#[repr(transparent)]
24742474
#[rustc_diagnostic_item = "SyncUnsafeCell"]
24752475
#[rustc_pub_transparent]
2476-
pub struct SyncUnsafeCell<T: ?Sized> {
2476+
pub struct SyncUnsafeCell<T: ?Sized + ?Move> {
24772477
value: UnsafeCell<T>,
24782478
}
24792479

@@ -2563,7 +2563,10 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell
25632563
// `self: SyncUnsafeCellWrapper<Self>` becomes possible
25642564
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
25652565
//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
2566-
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
2566+
impl<T: DispatchFromDyn<U> + ?Move, U: ?Move> DispatchFromDyn<SyncUnsafeCell<U>>
2567+
for SyncUnsafeCell<T>
2568+
{
2569+
}
25672570

25682571
#[allow(unused)]
25692572
fn assert_coerce_unsized(

library/core/src/marker.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ pub trait PointeeSized {
236236
#[lang = "unsize"]
237237
#[rustc_deny_explicit_impl]
238238
#[rustc_do_not_implement_via_object]
239-
pub trait Unsize<T: PointeeSized>: PointeeSized {
239+
pub trait Unsize<T: PointeeSized + ?crate::marker::Move>: PointeeSized {
240240
// Empty.
241241
}
242242

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

824824
#[stable(feature = "rust1", since = "1.0.0")]
825825
impl<T: PointeeSized> Hash for PhantomData<T> {
@@ -913,7 +913,7 @@ pub trait DiscriminantKind {
913913
pub unsafe auto trait Freeze {}
914914

915915
#[unstable(feature = "freeze", issue = "121675")]
916-
impl<T: PointeeSized> !Freeze for UnsafeCell<T> {}
916+
impl<T: PointeeSized + ?crate::marker::Move> !Freeze for UnsafeCell<T> {}
917917
marker_impls! {
918918
#[unstable(feature = "freeze", issue = "121675")]
919919
unsafe Freeze for
@@ -933,7 +933,7 @@ marker_impls! {
933933
#[lang = "unsafe_unpin"]
934934
pub(crate) unsafe auto trait UnsafeUnpin {}
935935

936-
impl<T: ?Sized> !UnsafeUnpin for UnsafePinned<T> {}
936+
impl<T: ?Sized + ?crate::marker::Move> !UnsafeUnpin for UnsafePinned<T> {}
937937
unsafe impl<T: ?Sized> UnsafeUnpin for PhantomData<T> {}
938938
unsafe impl<T: ?Sized> UnsafeUnpin for *const T {}
939939
unsafe impl<T: ?Sized> UnsafeUnpin for *mut T {}
@@ -1372,3 +1372,20 @@ pub trait CoercePointeeValidated {
13721372
pub trait Reborrow {
13731373
// Empty.
13741374
}
1375+
1376+
/// Types that do not require a stable memory address, and so can be freely
1377+
/// `move`d.
1378+
#[lang = "default_trait1"]
1379+
#[rustc_unsafe_specialization_marker]
1380+
#[unstable(feature = "move_trait", issue = "none")]
1381+
pub unsafe auto trait Move {
1382+
// empty.
1383+
}
1384+
marker_impls! {
1385+
#[unstable(feature = "move_trait", issue = "none")]
1386+
unsafe Move for
1387+
{T: ?Sized + PointeeSized} *const T,
1388+
{T: ?Sized + PointeeSized} *mut T,
1389+
{T: ?Sized + PointeeSized} &T,
1390+
{T: ?Sized + PointeeSized} &mut T,
1391+
}

library/core/src/ops/unsize.rs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::marker::{PointeeSized, Unsize};
1+
use crate::marker::{Move, PointeeSized, Unsize};
22

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

4040
// &mut T -> &mut U
4141
#[unstable(feature = "coerce_unsized", issue = "18598")]
42-
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {}
42+
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U>
43+
for &'a mut T
44+
{
45+
}
4346
// &mut T -> &U
4447
#[unstable(feature = "coerce_unsized", issue = "18598")]
45-
impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b mut T {}
48+
impl<'a, 'b: 'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U>
49+
for &'b mut T
50+
{
51+
}
4652
// &mut T -> *mut U
4753
#[unstable(feature = "coerce_unsized", issue = "18598")]
48-
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for &'a mut T {}
54+
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for &'a mut T {}
4955
// &mut T -> *const U
5056
#[unstable(feature = "coerce_unsized", issue = "18598")]
51-
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a mut T {}
57+
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U>
58+
for &'a mut T
59+
{
60+
}
5261

5362
// &T -> &U
5463
#[unstable(feature = "coerce_unsized", issue = "18598")]
55-
impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {}
64+
impl<'a, 'b: 'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U>
65+
for &'b T
66+
{
67+
}
5668
// &T -> *const U
5769
#[unstable(feature = "coerce_unsized", issue = "18598")]
58-
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a T {}
70+
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a T {}
5971

6072
// *mut T -> *mut U
6173
#[unstable(feature = "coerce_unsized", issue = "18598")]
62-
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {}
74+
impl<T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {}
6375
// *mut T -> *const U
6476
#[unstable(feature = "coerce_unsized", issue = "18598")]
65-
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *mut T {}
77+
impl<T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *mut T {}
6678

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

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

123135
// &T -> &U
124136
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
125-
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {}
137+
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized + ?Move> DispatchFromDyn<&'a U>
138+
for &'a T
139+
{
140+
}
126141
// &mut T -> &mut U
127142
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
128-
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {}
143+
impl<'a, T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized + ?Move> DispatchFromDyn<&'a mut U>
144+
for &'a mut T
145+
{
146+
}
129147
// *const T -> *const U
130148
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
131-
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {}
149+
impl<T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized + ?Move> DispatchFromDyn<*const U>
150+
for *const T
151+
{
152+
}
132153
// *mut T -> *mut U
133154
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
134-
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {}
155+
impl<T: PointeeSized + ?Move + Unsize<U>, U: PointeeSized + ?Move> DispatchFromDyn<*mut U>
156+
for *mut T
157+
{
158+
}

library/core/src/panic/unwind_safe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ impl<T> UnwindSafe for AssertUnwindSafe<T> {}
197197
// only thing which doesn't implement it (which then transitively applies to
198198
// everything else).
199199
#[stable(feature = "catch_unwind", since = "1.9.0")]
200-
impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
200+
impl<T: ?Sized + ?crate::marker::Move> !RefUnwindSafe for UnsafeCell<T> {}
201201
#[stable(feature = "catch_unwind", since = "1.9.0")]
202202
impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
203203

0 commit comments

Comments
 (0)