From 8ae6fcaeceda5706442b758a1392de92eaad3cf4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 4 Sep 2025 17:52:39 +0200 Subject: [PATCH] rarw --- compiler/rustc_ast_lowering/src/lib.rs | 15 +- .../src/collect/predicates_of.rs | 6 - .../src/hir_ty_lowering/bounds.rs | 142 ++---------------- .../src/multiple_supertrait_upcastable.rs | 3 +- compiler/rustc_session/src/options.rs | 2 +- library/alloc/src/boxed.rs | 8 +- library/alloc/src/lib.rs | 1 + library/alloctests/tests/lib.rs | 1 + library/core/src/cell.rs | 21 +-- library/core/src/marker.rs | 25 ++- library/core/src/ops/unsize.rs | 54 +++++-- library/core/src/panic/unwind_safe.rs | 2 +- library/core/src/pin.rs | 4 +- library/core/src/pin/unsafe_pinned.rs | 8 +- library/core/src/ptr/non_null.rs | 13 +- library/core/src/ptr/unique.rs | 9 +- library/coretests/tests/lib.rs | 1 + library/std/src/lib.rs | 1 + tests/ui/trait-bounds/more_maybe_bounds.rs | 14 ++ .../ui/trait-bounds/more_maybe_bounds.stderr | 32 +++- .../backward-compatible-lazy-bounds-pass.rs | 31 ---- .../maybe-bounds-in-dyn-traits.rs | 80 +++++++--- .../maybe-bounds-in-dyn-traits.stderr | 66 ++++---- .../maybe-bounds-in-traits.rs | 83 +++------- .../maybe-bounds-in-traits.stderr | 80 +++------- 25 files changed, 313 insertions(+), 389 deletions(-) delete mode 100644 tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 72f20a95ff02d..4e2243e87873c 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2101,17 +2101,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { { return; } - if self.tcx.features().more_maybe_bounds() { - return; - } } RelaxedBoundPolicy::Forbidden(reason) => { - if self.tcx.features().more_maybe_bounds() { - return; - } - match reason { RelaxedBoundForbiddenReason::TraitObjectTy => { + if self.tcx.features().more_maybe_bounds() { + return; + } + self.dcx().span_err( span, "relaxed bounds are not permitted in trait object types", @@ -2119,6 +2116,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return; } RelaxedBoundForbiddenReason::SuperTrait => { + if self.tcx.features().more_maybe_bounds() { + return; + } + let mut diag = self.dcx().struct_span_err( span, "relaxed bounds are not permitted in supertrait bounds", diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index b59dc4bd132f9..126ffabd448c7 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -174,12 +174,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } }; - if let Node::TraitItem(item) = node { - let mut bounds = Vec::new(); - icx.lowerer().add_default_trait_item_bounds(item, &mut bounds); - predicates.extend(bounds); - } - let generics = tcx.generics_of(def_id); // Below we'll consider the bounds on the type parameters (including `Self`) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index d14aef8ace46e..3da8d8c7236ca 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -1,12 +1,13 @@ +use std::assert_matches::assert_matches; use std::ops::ControlFlow; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; +use rustc_hir::PolyTraitRef; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; -use rustc_hir::{AmbigArg, PolyTraitRef}; use rustc_middle::bug; use rustc_middle::ty::{ self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, @@ -230,122 +231,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - /// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds - /// or associated items. - /// - /// To keep backward compatibility with existing code, `experimental_default_bounds` bounds - /// should be added everywhere, including super bounds. However this causes a huge performance - /// costs. For optimization purposes instead of adding default supertraits, bounds - /// are added to the associated items: - /// - /// ```ignore(illustrative) - /// // Default bounds are generated in the following way: - /// trait Trait { - /// fn foo(&self) where Self: Leak {} - /// } - /// - /// // instead of this: - /// trait Trait: Leak { - /// fn foo(&self) {} - /// } - /// ``` - /// It is not always possible to do this because of backward compatibility: - /// - /// ```ignore(illustrative) - /// pub trait Trait {} - /// pub trait Trait1 : Trait {} - /// //~^ ERROR: `Rhs` requires `DefaultAutoTrait`, but `Self` is not `DefaultAutoTrait` - /// ``` - /// - /// or: - /// - /// ```ignore(illustrative) - /// trait Trait { - /// type Type where Self: Sized; - /// } - /// trait Trait2 : Trait {} - /// //~^ ERROR: `DefaultAutoTrait` required for `Trait2`, by implicit `Self: DefaultAutoTrait` in `Trait::Type` - /// ``` - /// - /// Therefore, `experimental_default_bounds` are still being added to supertraits if - /// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header. - fn requires_default_supertraits( - &self, - hir_bounds: &'tcx [hir::GenericBound<'tcx>], - hir_generics: &'tcx hir::Generics<'tcx>, - ) -> bool { - struct TraitInfoCollector; - - impl<'tcx> hir::intravisit::Visitor<'tcx> for TraitInfoCollector { - type Result = ControlFlow<()>; - - fn visit_assoc_item_constraint( - &mut self, - _constraint: &'tcx hir::AssocItemConstraint<'tcx>, - ) -> Self::Result { - ControlFlow::Break(()) - } - - fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result { - if matches!( - &t.kind, - hir::TyKind::Path(hir::QPath::Resolved( - _, - hir::Path { res: hir::def::Res::SelfTyParam { .. }, .. }, - )) - ) { - return ControlFlow::Break(()); - } - hir::intravisit::walk_ty(self, t) - } - } - - let mut found = false; - for bound in hir_bounds { - found |= hir::intravisit::walk_param_bound(&mut TraitInfoCollector, bound).is_break(); - } - found |= hir::intravisit::walk_generics(&mut TraitInfoCollector, hir_generics).is_break(); - found - } - - /// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if - /// they are not added as super trait bounds to the trait itself. See - /// `requires_default_supertraits` for more information. - pub(crate) fn add_default_trait_item_bounds( - &self, - trait_item: &hir::TraitItem<'tcx>, - bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, - ) { - let tcx = self.tcx(); - if !tcx.sess.opts.unstable_opts.experimental_default_bounds { - return; - } - - let parent = tcx.local_parent(trait_item.hir_id().owner.def_id); - let hir::Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else { - unreachable!(); - }; - - let (trait_generics, trait_bounds) = match parent_trait.kind { - hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => (generics, supertraits), - hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits), - _ => unreachable!(), - }; - - if !self.requires_default_supertraits(trait_bounds, trait_generics) { - let self_ty_where_predicates = (parent, trait_item.generics.predicates); - self.add_default_traits( - bounds, - tcx.types.self_param, - &[], - Some(self_ty_where_predicates), - trait_item.span, - ); - } - } - - /// Lazily sets `experimental_default_bounds` to true on trait super bounds. - /// See `requires_default_supertraits` for more information. + /// Sets `experimental_default_bounds` to true on trait super bounds. pub(crate) fn add_default_super_traits( &self, trait_def_id: LocalDefId, @@ -354,21 +240,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_generics: &'tcx hir::Generics<'tcx>, span: Span, ) { - if !self.tcx().sess.opts.unstable_opts.experimental_default_bounds { + assert_matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias); + + if self.tcx().trait_is_auto(trait_def_id.to_def_id()) { return; } - assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias)); - if self.requires_default_supertraits(hir_bounds, hir_generics) { - let self_ty_where_predicates = (trait_def_id, hir_generics.predicates); - self.add_default_traits( - bounds, - self.tcx().types.self_param, - hir_bounds, - Some(self_ty_where_predicates), - span, - ); - } + self.add_default_traits( + bounds, + self.tcx().types.self_param, + hir_bounds, + Some((trait_def_id, hir_generics.predicates)), + span, + ); } pub(crate) fn add_default_traits( diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index 5513c703f1d54..93f067d09833a 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -47,7 +47,8 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { .explicit_super_predicates_of(def_id) .iter_identity_copied() .filter_map(|(pred, _)| pred.as_trait_clause()) - .filter(|pred| !cx.tcx.is_lang_item(pred.def_id(), hir::LangItem::MetaSized)); + .filter(|pred| !cx.tcx.is_lang_item(pred.def_id(), hir::LangItem::MetaSized)) + .filter(|pred| !cx.tcx.is_default_trait(pred.def_id())); if direct_super_traits_iter.count() > 1 { cx.emit_span_lint( MULTIPLE_SUPERTRAIT_UPCASTABLE, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 6d5be2d92cd2a..54889f504a657 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2240,7 +2240,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"), diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 98c9f6b51ab86..28826913a877f 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2039,7 +2039,10 @@ unsafe impl PinCoerceUnsized for Box {} // 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, U: ?Sized> DispatchFromDyn> for Box {} +impl + ?core::marker::Move, U: ?Sized + ?core::marker::Move> + DispatchFromDyn> for Box +{ +} #[stable(feature = "box_borrow", since = "1.1.0")] impl Borrow for Box { @@ -2141,3 +2144,6 @@ impl Error for Box { Error::provide(&**self, request); } } + +#[unstable(feature = "move_trait", issue = "none")] +unsafe impl core::marker::Move for Box {} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index cba1ce40f75d5..f03492069cc86 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -133,6 +133,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)] diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index bf446ae1ba42b..ae16d70e5443f 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -13,6 +13,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)] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 9b53b75ebee80..9562b6523f7e7 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -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; @@ -309,7 +309,7 @@ pub use once::OnceCell; #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] #[rustc_pub_transparent] -pub struct Cell { +pub struct Cell { value: UnsafeCell, } @@ -322,7 +322,7 @@ unsafe impl Send for Cell 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 !Sync for Cell {} +impl !Sync for Cell {} #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Cell { @@ -669,7 +669,7 @@ impl, U> CoerceUnsized> for Cell {} // `self: Cell<&Self>` won't work // `self: CellWrapper` becomes possible #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl, U> DispatchFromDyn> for Cell {} +impl + ?Move, U: ?Move> DispatchFromDyn> for Cell {} impl Cell<[T]> { /// Returns a `&[Cell]` from a `&Cell<[T]>` @@ -2185,12 +2185,12 @@ impl fmt::Display for RefMut<'_, T> { #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] #[rustc_pub_transparent] -pub struct UnsafeCell { +pub struct UnsafeCell { value: T, } #[stable(feature = "rust1", since = "1.0.0")] -impl !Sync for UnsafeCell {} +impl !Sync for UnsafeCell {} impl UnsafeCell { /// Constructs a new instance of `UnsafeCell` which will wrap the specified @@ -2455,7 +2455,7 @@ impl, U> CoerceUnsized> for UnsafeCell {} // `self: UnsafeCell<&Self>` won't work // `self: UnsafeCellWrapper` becomes possible #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl, U> DispatchFromDyn> for UnsafeCell {} +impl + ?Move, U: ?Move> DispatchFromDyn> for UnsafeCell {} /// [`UnsafeCell`], but [`Sync`]. /// @@ -2473,7 +2473,7 @@ impl, U> DispatchFromDyn> for UnsafeCell #[repr(transparent)] #[rustc_diagnostic_item = "SyncUnsafeCell"] #[rustc_pub_transparent] -pub struct SyncUnsafeCell { +pub struct SyncUnsafeCell { value: UnsafeCell, } @@ -2563,7 +2563,10 @@ impl, U> CoerceUnsized> for SyncUnsafeCell // `self: SyncUnsafeCellWrapper` becomes possible #[unstable(feature = "dispatch_from_dyn", issue = "none")] //#[unstable(feature = "sync_unsafe_cell", issue = "95439")] -impl, U> DispatchFromDyn> for SyncUnsafeCell {} +impl + ?Move, U: ?Move> DispatchFromDyn> + for SyncUnsafeCell +{ +} #[allow(unused)] fn assert_coerce_unsized( diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 73aad27afef6f..3d1991a9a9184 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -236,7 +236,7 @@ pub trait PointeeSized { #[lang = "unsize"] #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] -pub trait Unsize: PointeeSized { +pub trait Unsize: PointeeSized { // Empty. } @@ -819,7 +819,7 @@ impl !Sync for *mut T {} /// [drop check]: Drop#drop-check #[lang = "phantom_data"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct PhantomData; +pub struct PhantomData; #[stable(feature = "rust1", since = "1.0.0")] impl Hash for PhantomData { @@ -913,7 +913,7 @@ pub trait DiscriminantKind { pub unsafe auto trait Freeze {} #[unstable(feature = "freeze", issue = "121675")] -impl !Freeze for UnsafeCell {} +impl !Freeze for UnsafeCell {} marker_impls! { #[unstable(feature = "freeze", issue = "121675")] unsafe Freeze for @@ -933,7 +933,7 @@ marker_impls! { #[lang = "unsafe_unpin"] pub(crate) unsafe auto trait UnsafeUnpin {} -impl !UnsafeUnpin for UnsafePinned {} +impl !UnsafeUnpin for UnsafePinned {} unsafe impl UnsafeUnpin for PhantomData {} unsafe impl UnsafeUnpin for *const T {} unsafe impl UnsafeUnpin for *mut T {} @@ -1373,3 +1373,20 @@ pub trait CoercePointeeValidated { pub trait Reborrow { // Empty. } + +/// 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 + PointeeSized} *const T, + {T: ?Sized + PointeeSized} *mut T, + {T: ?Sized + PointeeSized} &T, + {T: ?Sized + PointeeSized} &mut T, +} diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs index f0781ee01fd53..6ba0bd7fdd320 100644 --- a/library/core/src/ops/unsize.rs +++ b/library/core/src/ops/unsize.rs @@ -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. @@ -39,34 +39,46 @@ pub trait CoerceUnsized { // &mut T -> &mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: PointeeSized + Unsize, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + ?Move + Unsize, 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: PointeeSized> CoerceUnsized<&'a U> for &'b mut T {} +impl<'a, 'b: 'a, T: PointeeSized + ?Move + Unsize, 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: PointeeSized> CoerceUnsized<*mut U> for &'a mut T {} +impl<'a, T: PointeeSized + ?Move + Unsize, 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: PointeeSized> CoerceUnsized<*const U> for &'a mut T {} +impl<'a, T: PointeeSized + ?Move + Unsize, 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: PointeeSized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: PointeeSized + ?Move + Unsize, U: PointeeSized> CoerceUnsized<&'a U> + for &'b T +{ +} // &T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: PointeeSized + Unsize, U: PointeeSized> CoerceUnsized<*const U> for &'a T {} +impl<'a, T: PointeeSized + ?Move + Unsize, U: PointeeSized> CoerceUnsized<*const U> for &'a T {} // *mut T -> *mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {} +impl, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {} // *mut T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl, U: PointeeSized> CoerceUnsized<*const U> for *mut T {} +impl, U: PointeeSized> CoerceUnsized<*const U> for *mut T {} // *const T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl, U: PointeeSized> CoerceUnsized<*const U> for *const T {} +impl, 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. @@ -116,19 +128,31 @@ impl, 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 { +pub trait DispatchFromDyn { // Empty. } // &T -> &U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<'a, T: PointeeSized + Unsize, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + ?Move + Unsize, 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: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + ?Move + Unsize, U: PointeeSized + ?Move> DispatchFromDyn<&'a mut U> + for &'a mut T +{ +} // *const T -> *const U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl, U: PointeeSized> DispatchFromDyn<*const U> for *const T {} +impl, U: PointeeSized + ?Move> DispatchFromDyn<*const U> + for *const T +{ +} // *mut T -> *mut U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {} +impl, U: PointeeSized + ?Move> DispatchFromDyn<*mut U> + for *mut T +{ +} diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs index 722af55103839..72047f5c55d34 100644 --- a/library/core/src/panic/unwind_safe.rs +++ b/library/core/src/panic/unwind_safe.rs @@ -197,7 +197,7 @@ impl UnwindSafe for AssertUnwindSafe {} // only thing which doesn't implement it (which then transitively applies to // everything else). #[stable(feature = "catch_unwind", since = "1.9.0")] -impl !RefUnwindSafe for UnsafeCell {} +impl !RefUnwindSafe for UnsafeCell {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl RefUnwindSafe for AssertUnwindSafe {} diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 535830f2e749f..d021f921f8182 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1091,7 +1091,7 @@ pub use self::unsafe_pinned::UnsafePinned; #[repr(transparent)] #[rustc_pub_transparent] #[derive(Copy, Clone)] -pub struct Pin { +pub struct Pin { pointer: Ptr, } @@ -1741,7 +1741,7 @@ where impl DispatchFromDyn> for Pin where Ptr: DispatchFromDyn + PinCoerceUnsized, - U: PinCoerceUnsized, + U: PinCoerceUnsized + ?crate::marker::Move, { } diff --git a/library/core/src/pin/unsafe_pinned.rs b/library/core/src/pin/unsafe_pinned.rs index ae03809b4581f..9fd419b7aa01f 100644 --- a/library/core/src/pin/unsafe_pinned.rs +++ b/library/core/src/pin/unsafe_pinned.rs @@ -1,5 +1,5 @@ use crate::cell::UnsafeCell; -use crate::marker::Unpin; +use crate::marker::{Move, Unpin}; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::pin::Pin; use crate::{fmt, ptr}; @@ -24,7 +24,7 @@ use crate::{fmt, ptr}; #[lang = "unsafe_pinned"] #[repr(transparent)] #[unstable(feature = "unsafe_pinned", issue = "125735")] -pub struct UnsafePinned { +pub struct UnsafePinned { value: UnsafeCell, } @@ -36,7 +36,7 @@ unsafe impl Sync for UnsafePinned {} /// aliases from becoming invalidated. Therefore let's mark this as `!Unpin`. You can always opt /// back in to `Unpin` with an `impl` block, provided your API is still sound while unpinned. #[unstable(feature = "unsafe_pinned", issue = "125735")] -impl !Unpin for UnsafePinned {} +impl !Unpin for UnsafePinned {} // `Send` and `Sync` are inherited from `T`. This is similar to `SyncUnsafeCell`, since // we eventually concluded that `UnsafeCell` implicitly making things `!Sync` is sometimes @@ -177,6 +177,6 @@ impl, U> CoerceUnsized> for UnsafePinned // FIXME(unsafe_pinned) this logic is copied from UnsafeCell, is it still sound? #[unstable(feature = "dispatch_from_dyn", issue = "none")] // #[unstable(feature = "unsafe_pinned", issue = "125735")] -impl, U> DispatchFromDyn> for UnsafePinned {} +impl, U: ?Move> DispatchFromDyn> for UnsafePinned {} // FIXME(unsafe_pinned): impl PinCoerceUnsized for UnsafePinned? diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 10f83120428b9..94e4b1ac45a00 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1,3 +1,5 @@ +use core::marker::Move; + use crate::cmp::Ordering; use crate::marker::{PointeeSized, Unsize}; use crate::mem::{MaybeUninit, SizedTypeProperties}; @@ -72,7 +74,7 @@ use crate::{fmt, hash, intrinsics, mem, ptr}; #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] #[rustc_diagnostic_item = "NonNull"] -pub struct NonNull { +pub struct NonNull { // Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to // this is banned by . pointer: *const T, @@ -81,12 +83,12 @@ pub struct NonNull { /// `NonNull` pointers are not `Send` because the data they reference may be aliased. // N.B., this impl is unnecessary, but should provide better error messages. #[stable(feature = "nonnull", since = "1.25.0")] -impl !Send for NonNull {} +impl !Send for NonNull {} /// `NonNull` pointers are not `Sync` because the data they reference may be aliased. // N.B., this impl is unnecessary, but should provide better error messages. #[stable(feature = "nonnull", since = "1.25.0")] -impl !Sync for NonNull {} +impl !Sync for NonNull {} impl NonNull { /// Creates a pointer with the given address and no [provenance][crate::ptr#provenance]. @@ -1653,7 +1655,10 @@ impl Copy for NonNull {} impl CoerceUnsized> for NonNull where T: Unsize {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl DispatchFromDyn> for NonNull where T: Unsize {} +impl DispatchFromDyn> for NonNull where + T: Unsize +{ +} #[stable(feature = "pin", since = "1.33.0")] unsafe impl PinCoerceUnsized for NonNull {} diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index cdc8b6cc936df..554810540c0ac 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -1,5 +1,5 @@ use crate::fmt; -use crate::marker::{PhantomData, PointeeSized, Unsize}; +use crate::marker::{Move, PhantomData, PointeeSized, Unsize}; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::pin::PinCoerceUnsized; use crate::ptr::NonNull; @@ -32,7 +32,7 @@ use crate::ptr::NonNull; )] #[doc(hidden)] #[repr(transparent)] -pub struct Unique { +pub struct Unique { pointer: NonNull, // NOTE: this marker has no consequences for variance, but is necessary // for dropck to understand that we logically own a `T`. @@ -169,7 +169,10 @@ impl Copy for Unique {} impl CoerceUnsized> for Unique where T: Unsize {} #[unstable(feature = "ptr_internals", issue = "none")] -impl DispatchFromDyn> for Unique where T: Unsize {} +impl DispatchFromDyn> for Unique where + T: Unsize +{ +} #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] unsafe impl PinCoerceUnsized for Unique {} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index b5658a9970fee..12806f209c642 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -77,6 +77,7 @@ #![feature(maybe_uninit_uninit_array_transpose)] #![feature(maybe_uninit_write_slice)] #![feature(min_specialization)] +#![feature(move_trait)] #![feature(never_type)] #![feature(next_index)] #![feature(non_exhaustive_omitted_patterns_lint)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 99b380c47936b..a0f1a625f614f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -358,6 +358,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)] diff --git a/tests/ui/trait-bounds/more_maybe_bounds.rs b/tests/ui/trait-bounds/more_maybe_bounds.rs index d367dd5b299dd..ddd4313bd5e15 100644 --- a/tests/ui/trait-bounds/more_maybe_bounds.rs +++ b/tests/ui/trait-bounds/more_maybe_bounds.rs @@ -21,6 +21,20 @@ fn bar(_: &T) {} // FIXME: `?Trait1` should be rejected, `Trait1` isn't marked `#[lang = "default_traitN"]`. fn baz() where T: Iterator {} +//~^ ERROR this relaxed bound is not permitted here + +struct S1(T); + +impl S1 { + fn f() where T: ?Trait1 {} + //~^ ERROR this relaxed bound is not permitted here +} + +trait Trait5<'a> {} + +struct S2(T) where for<'a> T: ?Trait5<'a>; +//~^ ERROR this relaxed bound is not permitted here +//~| ERROR bound modifier `?` can only be applied to default traits like `Sized` struct S; impl !Trait2 for S {} diff --git a/tests/ui/trait-bounds/more_maybe_bounds.stderr b/tests/ui/trait-bounds/more_maybe_bounds.stderr index 8dd83fc7728a9..0d78cfd582047 100644 --- a/tests/ui/trait-bounds/more_maybe_bounds.stderr +++ b/tests/ui/trait-bounds/more_maybe_bounds.stderr @@ -1,3 +1,27 @@ +error: this relaxed bound is not permitted here + --> $DIR/more_maybe_bounds.rs:23:37 + | +LL | fn baz() where T: Iterator {} + | ^^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + +error: this relaxed bound is not permitted here + --> $DIR/more_maybe_bounds.rs:29:21 + | +LL | fn f() where T: ?Trait1 {} + | ^^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + +error: this relaxed bound is not permitted here + --> $DIR/more_maybe_bounds.rs:35:34 + | +LL | struct S2(T) where for<'a> T: ?Trait5<'a>; + | ^^^^^^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + error: bound modifier `?` can only be applied to default traits like `Sized` --> $DIR/more_maybe_bounds.rs:17:20 | @@ -16,5 +40,11 @@ error: bound modifier `?` can only be applied to default traits like `Sized` LL | fn bar(_: &T) {} | ^^^^^^^ -error: aborting due to 3 previous errors +error: bound modifier `?` can only be applied to default traits like `Sized` + --> $DIR/more_maybe_bounds.rs:35:34 + | +LL | struct S2(T) where for<'a> T: ?Trait5<'a>; + | ^^^^^^^^^^^ + +error: aborting due to 7 previous errors diff --git a/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs deleted file mode 100644 index 745b6ee9bc5cc..0000000000000 --- a/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs +++ /dev/null @@ -1,31 +0,0 @@ -//@ check-pass -//@ compile-flags: -Zexperimental-default-bounds - -#![feature(auto_traits, lang_items, no_core, rustc_attrs, trait_alias)] -#![no_std] -#![no_core] - -#[lang = "pointee_sized"] -trait PointeeSized {} - -#[lang = "meta_sized"] -trait MetaSized: PointeeSized {} - -#[lang = "sized"] -trait Sized: MetaSized {} - -#[lang = "default_trait1"] -auto trait DefaultTrait1 {} - -#[lang = "default_trait2"] -auto trait DefaultTrait2 {} - -trait Trait {} -trait Trait1 : Trait {} - -trait Trait2 { - type Type; -} -trait Trait3 = Trait2; - -fn main() {} diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs index e7cca41a47eab..2e1a5d2424bfa 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs @@ -13,32 +13,37 @@ #![no_core] #[lang = "pointee_sized"] -trait PointeeSized {} +trait PointeeSized: ?Leak {} #[lang = "meta_sized"] -trait MetaSized: PointeeSized {} +trait MetaSized: PointeeSized + ?Leak {} #[lang = "sized"] -trait Sized: MetaSized {} +trait Sized: MetaSized + ?Leak {} #[lang = "copy"] -pub trait Copy {} +pub trait Copy: ?Leak {} impl<'a, T: ?Sized> Copy for &'a T {} #[lang = "legacy_receiver"] -trait Receiver {} +trait Receiver: ?Leak {} impl Receiver for &T {} +impl Receiver for &mut T {} #[lang = "unsize"] -trait Unsize {} +trait Unsize: ?Leak {} #[lang = "coerce_unsized"] -trait CoerceUnsized {} +trait CoerceUnsized: ?Leak {} impl<'a, 'b: 'a, T: ?Sized + ?Leak + Unsize, U: ?Sized + ?Leak> CoerceUnsized<&'a U> for &'b T {} +// Omit `T: ?Leak` and `U: ?Leak`. +impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'b mut T {} #[lang = "dispatch_from_dyn"] -trait DispatchFromDyn {} +trait DispatchFromDyn: ?Leak {} impl<'a, T: ?Sized + ?Leak + Unsize, U: ?Sized + ?Leak> DispatchFromDyn<&'a U> for &'a T {} +// Omit `T: ?Leak` and `U: ?Leak`. +impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} #[lang = "default_trait1"] auto trait Leak {} @@ -47,25 +52,52 @@ struct NonLeakS; impl !Leak for NonLeakS {} struct LeakS; -trait Trait { - fn leak_foo(&self) {} - fn maybe_leak_foo(&self) where Self: ?Leak {} +fn bounds_check() { + trait LeakTr {} + + trait MaybeLeakTr: ?Leak {} + + impl MaybeLeakTr for NonLeakS {} + + impl LeakTr for LeakS {} + impl MaybeLeakTr for LeakS {} + + let _: &dyn LeakTr = &NonLeakS; + //~^ ERROR the trait bound `NonLeakS: bounds_check::LeakTr` is not satisfied + let _: &dyn LeakTr = &LeakS; + + let _: &(dyn LeakTr + ?Leak) = &NonLeakS; + let _: &(dyn LeakTr + ?Leak) = &LeakS; + + let _: &dyn MaybeLeakTr = &NonLeakS; + let _: &dyn MaybeLeakTr = &LeakS; } -impl Trait for NonLeakS {} -impl Trait for LeakS {} - -fn main() { - let _: &dyn Trait = &NonLeakS; - //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied - let _: &dyn Trait = &LeakS; - let _: &(dyn Trait + ?Leak) = &LeakS; - let x: &(dyn Trait + ?Leak) = &NonLeakS; - x.leak_foo(); - //~^ ERROR the trait bound `dyn Trait: Leak` is not satisfied - x.maybe_leak_foo(); +fn dyn_compat_check() { + trait DynCompatCheck1: ?Leak { + fn foo(&self) {} + } + + trait DynCompatCheck2: ?Leak { + fn mut_foo(&mut self) {} + } + + impl DynCompatCheck1 for NonLeakS {} + impl DynCompatCheck2 for NonLeakS {} + + let _: &(dyn DynCompatCheck1 + ?Leak) = &NonLeakS; + // There is no `?Leak` bound on corresponding `DispatchFromDyn` impl. + let _: &dyn DynCompatCheck2 = &NonLeakS; + //~^ ERROR the trait `DynCompatCheck2` is not dyn compatible +} + +fn args_check() { + trait LeakTr {} + // Ensure that we validate the generic args of relaxed bounds in trait object types. - let _: dyn Trait + ?Leak<(), Undefined = ()>; + let _: dyn LeakTr + ?Leak<(), Undefined = ()>; //~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied //~| ERROR associated type `Undefined` not found for `Leak` } + +fn main() {} diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr index b19c082a1b8fd..b96a2915c3330 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr @@ -1,49 +1,57 @@ -error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied - --> $DIR/maybe-bounds-in-dyn-traits.rs:59:25 +error[E0277]: the trait bound `NonLeakS: bounds_check::LeakTr` is not satisfied + --> $DIR/maybe-bounds-in-dyn-traits.rs:65:26 | -LL | let _: &dyn Trait = &NonLeakS; - | ^^^^^^^^^ unsatisfied trait bound +LL | let _: &dyn LeakTr = &NonLeakS; + | ^^^^^^^^^ unsatisfied trait bound | -help: the trait `Leak` is not implemented for `NonLeakS` - --> $DIR/maybe-bounds-in-dyn-traits.rs:46:1 +help: the trait `bounds_check::LeakTr` is not implemented for `NonLeakS` + --> $DIR/maybe-bounds-in-dyn-traits.rs:51:1 | LL | struct NonLeakS; | ^^^^^^^^^^^^^^^ - = note: required for the cast from `&NonLeakS` to `&dyn Trait + Leak` + = help: the trait `bounds_check::LeakTr` is implemented for `LeakS` + = note: required for the cast from `&NonLeakS` to `&dyn bounds_check::LeakTr + Leak` -error[E0277]: the trait bound `dyn Trait: Leak` is not satisfied - --> $DIR/maybe-bounds-in-dyn-traits.rs:64:7 - | -LL | x.leak_foo(); - | ^^^^^^^^ the trait `Leak` is not implemented for `dyn Trait` - | -note: required by a bound in `Trait::leak_foo` - --> $DIR/maybe-bounds-in-dyn-traits.rs:51:5 - | -LL | fn leak_foo(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo` +error[E0038]: the trait `DynCompatCheck2` is not dyn compatible + --> $DIR/maybe-bounds-in-dyn-traits.rs:90:17 + | +LL | fn mut_foo(&mut self) {} + | --------- help: consider changing method `mut_foo`'s `self` parameter to be `&self`: `&Self` +... +LL | let _: &dyn DynCompatCheck2 = &NonLeakS; + | ^^^^^^^^^^^^^^^ `DynCompatCheck2` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/maybe-bounds-in-dyn-traits.rs:82:20 + | +LL | trait DynCompatCheck2: ?Leak { + | --------------- this trait is not dyn compatible... +LL | fn mut_foo(&mut self) {} + | ^^^^^^^^^ ...because method `mut_foo`'s `self` parameter cannot be dispatched on + = help: only type `NonLeakS` implements `DynCompatCheck2`; consider using it directly instead. error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/maybe-bounds-in-dyn-traits.rs:68:25 + --> $DIR/maybe-bounds-in-dyn-traits.rs:98:26 | -LL | let _: dyn Trait + ?Leak<(), Undefined = ()>; - | ^^^^-------------------- help: remove the unnecessary generics - | | - | expected 0 generic arguments +LL | let _: dyn LeakTr + ?Leak<(), Undefined = ()>; + | ^^^^-------------------- help: remove the unnecessary generics + | | + | expected 0 generic arguments | note: trait defined here, with 0 generic parameters - --> $DIR/maybe-bounds-in-dyn-traits.rs:44:12 + --> $DIR/maybe-bounds-in-dyn-traits.rs:49:12 | LL | auto trait Leak {} | ^^^^ error[E0220]: associated type `Undefined` not found for `Leak` - --> $DIR/maybe-bounds-in-dyn-traits.rs:68:34 + --> $DIR/maybe-bounds-in-dyn-traits.rs:98:35 | -LL | let _: dyn Trait + ?Leak<(), Undefined = ()>; - | ^^^^^^^^^ associated type `Undefined` not found +LL | let _: dyn LeakTr + ?Leak<(), Undefined = ()>; + | ^^^^^^^^^ associated type `Undefined` not found error: aborting due to 4 previous errors -Some errors have detailed explanations: E0107, E0220, E0277. -For more information about an error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0038, E0107, E0220, E0277. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs index b3801baaf7047..ac4c4aca2efe3 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs @@ -14,18 +14,22 @@ #![no_std] #![no_core] +#[lang = "copy"] +pub trait Copy: ?Leak {} + #[lang = "pointee_sized"] -trait PointeeSized {} +trait PointeeSized: ?Leak {} #[lang = "meta_sized"] -trait MetaSized: PointeeSized {} +trait MetaSized: PointeeSized + ?Leak {} #[lang = "sized"] -trait Sized: MetaSized {} +trait Sized: MetaSized + ?Leak {} #[lang = "legacy_receiver"] -trait LegacyReceiver {} +trait LegacyReceiver: ?Leak {} impl LegacyReceiver for &T {} +// Omit `T: ?Leak`. impl LegacyReceiver for &mut T {} #[lang = "default_trait1"] @@ -38,83 +42,40 @@ struct LeakS; mod supertraits { use crate::*; - trait MaybeLeakT1: ?Leak {} - trait MaybeLeakT2 where Self: ?Leak {} + trait MaybeLeak: ?Leak {} + impl MaybeLeak for NonLeakS {} - impl MaybeLeakT1 for NonLeakS {} - impl MaybeLeakT2 for NonLeakS {} + trait LeakT {} + impl LeakT for NonLeakS {} + //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied } -mod maybe_self_assoc_type { +mod assoc_type_maybe_bounds { use crate::*; - trait TestBase1 {} - trait TestBase2 {} - - trait Test1 { - type MaybeLeakSelf: TestBase1 where Self: ?Leak; - //~^ ERROR the trait bound `Self: Leak` is not satisfied - type LeakSelf: TestBase1; - } - - trait Test2 { - type MaybeLeakSelf: TestBase2 where Self: ?Leak; - type LeakSelf: TestBase2; - } - - trait Test3 { + trait Test1 { type Leak1 = LeakS; type Leak2 = NonLeakS; //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied } - trait Test4 { + trait Test2 { type MaybeLeak1: ?Leak = LeakS; type MaybeLeak2: ?Leak = NonLeakS; } - - trait Test5: ?Leak { - // ok, because assoc types have implicit where Self: Leak - type MaybeLeakSelf1: TestBase1; - type MaybeLeakSelf2: TestBase2; - } -} - -mod maybe_self_assoc_const { - use crate::*; - - const fn size_of() -> usize { - 0 - } - - trait Trait { - const CLeak: usize = size_of::(); - const CNonLeak: usize = size_of::() where Self: ?Leak; - //~^ ERROR the trait bound `Self: Leak` is not satisfied - } } mod methods { use crate::*; - trait Trait { - fn leak_foo(&self) {} - fn maybe_leak_foo(&self) where Self: ?Leak {} - fn mut_leak_foo(&mut self) {} - // there is no relax bound on corresponding Receiver impl - fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {} - //~^ ERROR `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types` + trait ReceiveCheck1: ?Leak { + fn foo(&self) {} } - impl Trait for NonLeakS {} - impl Trait for LeakS {} - - fn foo() { - LeakS.leak_foo(); - LeakS.maybe_leak_foo(); - NonLeakS.leak_foo(); - //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied - NonLeakS.maybe_leak_foo(); + trait ReceiveCheck2: ?Leak { + // There is no `?Leak` bound on corresponding `LegacyReceiver` impl. + fn mut_foo(&mut self) {} + //~^ ERROR `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types` } } diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr index 372bf81760093..ab62ab81b213b 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr @@ -1,81 +1,49 @@ error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:67:22 + --> $DIR/maybe-bounds-in-traits.rs:49:20 | -LL | type Leak2 = NonLeakS; - | ^^^^^^^^ unsatisfied trait bound +LL | impl LeakT for NonLeakS {} + | ^^^^^^^^ unsatisfied trait bound | help: the trait `Leak` is not implemented for `NonLeakS` - --> $DIR/maybe-bounds-in-traits.rs:34:1 + --> $DIR/maybe-bounds-in-traits.rs:38:1 | LL | struct NonLeakS; | ^^^^^^^^^^^^^^^ -note: required by a bound in `Test3::Leak2` - --> $DIR/maybe-bounds-in-traits.rs:67:9 +note: required by a bound in `LeakT` + --> $DIR/maybe-bounds-in-traits.rs:48:5 | -LL | type Leak2 = NonLeakS; - | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Test3::Leak2` +LL | trait LeakT {} + | ^^^^^^^^^^^^^^ required by this bound in `LeakT` -error[E0277]: the trait bound `Self: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:55:29 +error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied + --> $DIR/maybe-bounds-in-traits.rs:58:22 | -LL | type MaybeLeakSelf: TestBase1 where Self: ?Leak; - | ^^^^^^^^^^^^^^^ the trait `Leak` is not implemented for `Self` +LL | type Leak2 = NonLeakS; + | ^^^^^^^^ unsatisfied trait bound | -note: required by a bound in `TestBase1` - --> $DIR/maybe-bounds-in-traits.rs:51:21 +help: the trait `Leak` is not implemented for `NonLeakS` + --> $DIR/maybe-bounds-in-traits.rs:38:1 | -LL | trait TestBase1 {} - | ^ required by this bound in `TestBase1` -help: consider further restricting `Self` +LL | struct NonLeakS; + | ^^^^^^^^^^^^^^^ +note: required by a bound in `Test1::Leak2` + --> $DIR/maybe-bounds-in-traits.rs:58:9 | -LL | trait Test1: Leak { - | ++++++ +LL | type Leak2 = NonLeakS; + | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Test1::Leak2` error[E0658]: `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature - --> $DIR/maybe-bounds-in-traits.rs:105:31 + --> $DIR/maybe-bounds-in-traits.rs:77:20 | -LL | fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {} - | ^^^^^^^^^ +LL | fn mut_foo(&mut self) {} + | ^^^^^^^^^ | = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` -error[E0277]: the trait bound `Self: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:92:43 - | -LL | const CNonLeak: usize = size_of::() where Self: ?Leak; - | ^^^^ the trait `Leak` is not implemented for `Self` - | -note: required by a bound in `size_of` - --> $DIR/maybe-bounds-in-traits.rs:86:22 - | -LL | const fn size_of() -> usize { - | ^ required by this bound in `size_of` -help: consider further restricting `Self` - | -LL | trait Trait: Leak { - | ++++++ - -error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:115:18 - | -LL | NonLeakS.leak_foo(); - | ^^^^^^^^ unsatisfied trait bound - | -help: the trait `Leak` is not implemented for `NonLeakS` - --> $DIR/maybe-bounds-in-traits.rs:34:1 - | -LL | struct NonLeakS; - | ^^^^^^^^^^^^^^^ -note: required by a bound in `methods::Trait::leak_foo` - --> $DIR/maybe-bounds-in-traits.rs:101:9 - | -LL | fn leak_foo(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo` - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0658. For more information about an error, try `rustc --explain E0277`.