Skip to content

Commit 1a0c49b

Browse files
Auto merge of #146201 - lcnr:move-trait, r=<try>
[DO NOT MERGE] `Move` trait perf test
2 parents 45b9d13 + cd0a507 commit 1a0c49b

File tree

26 files changed

+311
-389
lines changed

26 files changed

+311
-389
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,24 +2101,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21012101
{
21022102
return;
21032103
}
2104-
if self.tcx.features().more_maybe_bounds() {
2105-
return;
2106-
}
21072104
}
21082105
RelaxedBoundPolicy::Forbidden(reason) => {
2109-
if self.tcx.features().more_maybe_bounds() {
2110-
return;
2111-
}
2112-
21132106
match reason {
21142107
RelaxedBoundForbiddenReason::TraitObjectTy => {
2108+
if self.tcx.features().more_maybe_bounds() {
2109+
return;
2110+
}
2111+
21152112
self.dcx().span_err(
21162113
span,
21172114
"relaxed bounds are not permitted in trait object types",
21182115
);
21192116
return;
21202117
}
21212118
RelaxedBoundForbiddenReason::SuperTrait => {
2119+
if self.tcx.features().more_maybe_bounds() {
2120+
return;
2121+
}
2122+
21222123
let mut diag = self.dcx().struct_span_err(
21232124
span,
21242125
"relaxed bounds are not permitted in supertrait bounds",

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
174174
}
175175
};
176176

177-
if let Node::TraitItem(item) = node {
178-
let mut bounds = Vec::new();
179-
icx.lowerer().add_default_trait_item_bounds(item, &mut bounds);
180-
predicates.extend(bounds);
181-
}
182-
183177
let generics = tcx.generics_of(def_id);
184178

185179
// Below we'll consider the bounds on the type parameters (including `Self`)

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 13 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
use std::assert_matches::assert_matches;
12
use std::ops::ControlFlow;
23

34
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
45
use rustc_errors::codes::*;
56
use rustc_errors::struct_span_code_err;
67
use rustc_hir as hir;
8+
use rustc_hir::PolyTraitRef;
79
use rustc_hir::def::{DefKind, Res};
810
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
9-
use rustc_hir::{AmbigArg, PolyTraitRef};
1011
use rustc_middle::bug;
1112
use rustc_middle::ty::{
1213
self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@@ -230,122 +231,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
230231
}
231232
}
232233

233-
/// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds
234-
/// or associated items.
235-
///
236-
/// To keep backward compatibility with existing code, `experimental_default_bounds` bounds
237-
/// should be added everywhere, including super bounds. However this causes a huge performance
238-
/// costs. For optimization purposes instead of adding default supertraits, bounds
239-
/// are added to the associated items:
240-
///
241-
/// ```ignore(illustrative)
242-
/// // Default bounds are generated in the following way:
243-
/// trait Trait {
244-
/// fn foo(&self) where Self: Leak {}
245-
/// }
246-
///
247-
/// // instead of this:
248-
/// trait Trait: Leak {
249-
/// fn foo(&self) {}
250-
/// }
251-
/// ```
252-
/// It is not always possible to do this because of backward compatibility:
253-
///
254-
/// ```ignore(illustrative)
255-
/// pub trait Trait<Rhs = Self> {}
256-
/// pub trait Trait1 : Trait {}
257-
/// //~^ ERROR: `Rhs` requires `DefaultAutoTrait`, but `Self` is not `DefaultAutoTrait`
258-
/// ```
259-
///
260-
/// or:
261-
///
262-
/// ```ignore(illustrative)
263-
/// trait Trait {
264-
/// type Type where Self: Sized;
265-
/// }
266-
/// trait Trait2<T> : Trait<Type = T> {}
267-
/// //~^ ERROR: `DefaultAutoTrait` required for `Trait2`, by implicit `Self: DefaultAutoTrait` in `Trait::Type`
268-
/// ```
269-
///
270-
/// Therefore, `experimental_default_bounds` are still being added to supertraits if
271-
/// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header.
272-
fn requires_default_supertraits(
273-
&self,
274-
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
275-
hir_generics: &'tcx hir::Generics<'tcx>,
276-
) -> bool {
277-
struct TraitInfoCollector;
278-
279-
impl<'tcx> hir::intravisit::Visitor<'tcx> for TraitInfoCollector {
280-
type Result = ControlFlow<()>;
281-
282-
fn visit_assoc_item_constraint(
283-
&mut self,
284-
_constraint: &'tcx hir::AssocItemConstraint<'tcx>,
285-
) -> Self::Result {
286-
ControlFlow::Break(())
287-
}
288-
289-
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
290-
if matches!(
291-
&t.kind,
292-
hir::TyKind::Path(hir::QPath::Resolved(
293-
_,
294-
hir::Path { res: hir::def::Res::SelfTyParam { .. }, .. },
295-
))
296-
) {
297-
return ControlFlow::Break(());
298-
}
299-
hir::intravisit::walk_ty(self, t)
300-
}
301-
}
302-
303-
let mut found = false;
304-
for bound in hir_bounds {
305-
found |= hir::intravisit::walk_param_bound(&mut TraitInfoCollector, bound).is_break();
306-
}
307-
found |= hir::intravisit::walk_generics(&mut TraitInfoCollector, hir_generics).is_break();
308-
found
309-
}
310-
311-
/// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
312-
/// they are not added as super trait bounds to the trait itself. See
313-
/// `requires_default_supertraits` for more information.
314-
pub(crate) fn add_default_trait_item_bounds(
315-
&self,
316-
trait_item: &hir::TraitItem<'tcx>,
317-
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
318-
) {
319-
let tcx = self.tcx();
320-
if !tcx.sess.opts.unstable_opts.experimental_default_bounds {
321-
return;
322-
}
323-
324-
let parent = tcx.local_parent(trait_item.hir_id().owner.def_id);
325-
let hir::Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
326-
unreachable!();
327-
};
328-
329-
let (trait_generics, trait_bounds) = match parent_trait.kind {
330-
hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => (generics, supertraits),
331-
hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
332-
_ => unreachable!(),
333-
};
334-
335-
if !self.requires_default_supertraits(trait_bounds, trait_generics) {
336-
let self_ty_where_predicates = (parent, trait_item.generics.predicates);
337-
self.add_default_traits(
338-
bounds,
339-
tcx.types.self_param,
340-
&[],
341-
Some(self_ty_where_predicates),
342-
trait_item.span,
343-
);
344-
}
345-
}
346-
347-
/// Lazily sets `experimental_default_bounds` to true on trait super bounds.
348-
/// See `requires_default_supertraits` for more information.
234+
/// Sets `experimental_default_bounds` to true on trait super bounds.
349235
pub(crate) fn add_default_super_traits(
350236
&self,
351237
trait_def_id: LocalDefId,
@@ -354,21 +240,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
354240
hir_generics: &'tcx hir::Generics<'tcx>,
355241
span: Span,
356242
) {
357-
if !self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
243+
assert_matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias);
244+
245+
if self.tcx().trait_is_auto(trait_def_id.to_def_id()) {
358246
return;
359247
}
360248

361-
assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias));
362-
if self.requires_default_supertraits(hir_bounds, hir_generics) {
363-
let self_ty_where_predicates = (trait_def_id, hir_generics.predicates);
364-
self.add_default_traits(
365-
bounds,
366-
self.tcx().types.self_param,
367-
hir_bounds,
368-
Some(self_ty_where_predicates),
369-
span,
370-
);
371-
}
249+
self.add_default_traits(
250+
bounds,
251+
self.tcx().types.self_param,
252+
hir_bounds,
253+
Some((trait_def_id, hir_generics.predicates)),
254+
span,
255+
);
372256
}
373257

374258
pub(crate) fn add_default_traits(

compiler/rustc_lint/src/multiple_supertrait_upcastable.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
4747
.explicit_super_predicates_of(def_id)
4848
.iter_identity_copied()
4949
.filter_map(|(pred, _)| pred.as_trait_clause())
50-
.filter(|pred| !cx.tcx.is_lang_item(pred.def_id(), hir::LangItem::MetaSized));
50+
.filter(|pred| !cx.tcx.is_lang_item(pred.def_id(), hir::LangItem::MetaSized))
51+
.filter(|pred| !cx.tcx.is_default_trait(pred.def_id()));
5152
if direct_super_traits_iter.count() > 1 {
5253
cx.emit_span_lint(
5354
MULTIPLE_SUPERTRAIT_UPCASTABLE,

compiler/rustc_session/src/options.rs

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

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>, U: ?Sized + ?core::marker::Move> DispatchFromDyn<Box<U>>
2043+
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/collections/vec_deque/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3099,6 +3099,7 @@ impl<T, A: Allocator> IndexMut<usize> for VecDeque<T, A> {
30993099
}
31003100
}
31013101

3102+
31023103
#[stable(feature = "rust1", since = "1.0.0")]
31033104
impl<T> FromIterator<T> for VecDeque<T> {
31043105
#[track_caller]

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: 9 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>, 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>, 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,7 @@ 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>, U: ?Move> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
25672567

25682568
#[allow(unused)]
25692569
fn assert_coerce_unsized(

0 commit comments

Comments
 (0)