From 31e8e2ef944c3421c2b6492db59fe41adf4e27e2 Mon Sep 17 00:00:00 2001 From: Xiangfei Ding Date: Tue, 2 Sep 2025 10:44:21 +0200 Subject: [PATCH 1/2] arbitrary_self_types: split the Autoderef chain Receiver chain has been an extension of Deref chain, but the consequence has been questioned as this would admit method signatures that are deemed dubious. It is also debatable that Receiver trait which determines applicable `Self` type should have anything to do with dereference operation in general. This patch separate the two traits and isolate their use in the language. This means that in method probing, we will chase down a Deref chain for an applicable type for the variable `self`, from which we additionally chase down a Receiver chain for an applicable `Self` type from a list of methods that accepts one of these possible types of `self`. --- ...itrary_self_types_pointers_and_wrappers.rs | 8 +- ...itrary_self_types_pointers_and_wrappers.rs | 13 +- .../src/error_codes/E0307.md | 10 +- compiler/rustc_hir_analysis/src/autoderef.rs | 20 ++- .../rustc_hir_analysis/src/check/wfcheck.rs | 14 +- .../rustc_hir_typeck/src/method/confirm.rs | 32 +++- compiler/rustc_hir_typeck/src/method/probe.rs | 161 ++++++++++-------- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/traits/query.rs | 1 + compiler/rustc_resolve/src/lib.rs | 6 + library/alloc/src/boxed.rs | 6 +- library/alloc/src/lib.rs | 2 + library/alloc/src/rc.rs | 8 +- library/alloc/src/sync.rs | 8 +- library/core/src/marker.rs | 6 +- library/core/src/ops/deref.rs | 16 +- library/core/src/pin.rs | 8 +- src/tools/miri/src/shims/files.rs | 6 + .../miri/tests/pass/dyn-arbitrary-self.rs | 16 +- tests/crashes/138564.rs | 6 +- tests/ui/deriving/deriving-coerce-pointee.rs | 7 +- .../feature-gate-arbitrary-self-types.rs | 10 +- .../feature-gate-arbitrary-self-types.stderr | 32 ++-- ...ure-gate-dispatch-from-dyn-missing-impl.rs | 9 +- ...gate-dispatch-from-dyn-missing-impl.stderr | 4 +- ...-same-trait-object-with-separate-params.rs | 8 +- ...e-trait-object-with-separate-params.stderr | 16 +- ...y-self-from-method-substs-with-receiver.rs | 19 ++- ...lf-from-method-substs-with-receiver.stderr | 34 ++-- ...ary-self-from-method-substs.default.stderr | 78 ++++----- ...ary-self-from-method-substs.feature.stderr | 98 +++++++---- .../self/arbitrary-self-from-method-substs.rs | 78 +++++++-- ...ry_self_types_generic_over_receiver.stderr | 1 - ...itrary_self_types_pointers_and_wrappers.rs | 20 ++- tests/ui/self/arbitrary_self_types_silly.rs | 8 +- tests/ui/self/dispatch-from-dyn-layout-3.rs | 5 +- tests/ui/self/dispatch-from-dyn-layout.rs | 4 +- .../self/dispatch-from-dyn-zst-transmute.rs | 13 +- .../dispatch-from-dyn-zst-transmute.stderr | 8 +- .../dyn-dispatch-requires-supertrait-norm.rs | 5 +- .../self/dyn-dispatch-requires-supertrait.rs | 7 +- .../self/elision/multiple-ref-self-async.rs | 14 +- .../elision/multiple-ref-self-async.stderr | 10 +- tests/ui/self/elision/multiple-ref-self.rs | 13 +- .../ui/self/elision/multiple-ref-self.stderr | 10 +- tests/ui/self/elision/ref-self-async.rs | 13 +- tests/ui/self/elision/ref-self-async.stderr | 14 +- tests/ui/self/elision/ref-self-multi.rs | 13 +- tests/ui/self/elision/ref-self-multi.stderr | 4 +- tests/ui/self/elision/ref-self.fixed | 5 +- tests/ui/self/elision/ref-self.rs | 5 +- tests/ui/self/elision/ref-self.stderr | 16 +- tests/ui/self/invalid-self-dyn-receiver.rs | 11 +- .../ui/self/invalid-self-dyn-receiver.stderr | 24 ++- 54 files changed, 598 insertions(+), 367 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/example/arbitrary_self_types_pointers_and_wrappers.rs b/compiler/rustc_codegen_cranelift/example/arbitrary_self_types_pointers_and_wrappers.rs index f0d1f6e221572..d1835829e0726 100644 --- a/compiler/rustc_codegen_cranelift/example/arbitrary_self_types_pointers_and_wrappers.rs +++ b/compiler/rustc_codegen_cranelift/example/arbitrary_self_types_pointers_and_wrappers.rs @@ -3,7 +3,7 @@ #![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)] use std::marker::Unsize; -use std::ops::{CoerceUnsized, Deref, DispatchFromDyn}; +use std::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver}; struct Ptr(Box); @@ -14,6 +14,9 @@ impl Deref for Ptr { &*self.0 } } +impl Receiver for Ptr { + type Target = T; +} impl + ?Sized, U: ?Sized> CoerceUnsized> for Ptr {} impl + ?Sized, U: ?Sized> DispatchFromDyn> for Ptr {} @@ -27,6 +30,9 @@ impl Deref for Wrapper { &self.0 } } +impl Receiver for Wrapper { + type Target = T; +} impl, U> CoerceUnsized> for Wrapper {} impl, U> DispatchFromDyn> for Wrapper {} diff --git a/compiler/rustc_codegen_gcc/example/arbitrary_self_types_pointers_and_wrappers.rs b/compiler/rustc_codegen_gcc/example/arbitrary_self_types_pointers_and_wrappers.rs index c26606f0bdd5c..afae06b576aea 100644 --- a/compiler/rustc_codegen_gcc/example/arbitrary_self_types_pointers_and_wrappers.rs +++ b/compiler/rustc_codegen_gcc/example/arbitrary_self_types_pointers_and_wrappers.rs @@ -4,10 +4,8 @@ #![feature(rustc_attrs)] #![allow(internal_features)] -use std::{ - ops::{Deref, CoerceUnsized, DispatchFromDyn}, - marker::Unsize, -}; +use std::marker::Unsize; +use std::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver}; struct Ptr(Box); @@ -18,6 +16,9 @@ impl Deref for Ptr { &*self.0 } } +impl Receiver for Ptr { + type Target = T; +} impl + ?Sized, U: ?Sized> CoerceUnsized> for Ptr {} impl + ?Sized, U: ?Sized> DispatchFromDyn> for Ptr {} @@ -31,11 +32,13 @@ impl Deref for Wrapper { &self.0 } } +impl Receiver for Wrapper { + type Target = T; +} impl, U> CoerceUnsized> for Wrapper {} impl, U> DispatchFromDyn> for Wrapper {} - trait Trait { fn ptr_wrapper(self: Ptr>) -> i32; fn wrapper_ptr(self: Wrapper>) -> i32; diff --git a/compiler/rustc_error_codes/src/error_codes/E0307.md b/compiler/rustc_error_codes/src/error_codes/E0307.md index b9c0493e8d6e6..e997c3f7e3b44 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0307.md +++ b/compiler/rustc_error_codes/src/error_codes/E0307.md @@ -67,8 +67,6 @@ impl Trait for Foo { The nightly feature [Arbitrary self types][AST] extends the accepted set of receiver types to also include any type that implements the `Receiver` trait and can follow its chain of `Target` types to `Self`. -There's a blanket implementation of `Receiver` for `T: Deref`, so any -type which dereferences to `Self` can be used. ``` #![feature(arbitrary_self_types)] @@ -76,13 +74,9 @@ type which dereferences to `Self` can be used. struct Foo; struct Bar; -// Because you can dereference `Bar` into `Foo`... -impl std::ops::Deref for Bar { +// Because you can set `Bar` as method receiver for `Foo`... +impl std::ops::Receiver for Bar { type Target = Foo; - - fn deref(&self) -> &Foo { - &Foo - } } impl Foo { diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 88bd3339e4e18..93347f2378d98 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -80,16 +80,19 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> { } // Otherwise, deref if type is derefable: - // NOTE: in the case of self.use_receiver_trait = true, you might think it would - // be better to skip this clause and use the Overloaded case only, since &T - // and &mut T implement Receiver. But built-in derefs apply equally to Receiver - // and Deref, and this has benefits for const and the emitted MIR. + // NOTE: in the case of self.use_receiver_trait = true, + // Autoderef works only with Receiver trait. + // Caller is expecting us to expand the Receiver chain only. let (kind, new_ty) = if let Some(ty) = self.state.cur_ty.builtin_deref(self.include_raw_pointers) { debug_assert_eq!(ty, self.infcx.resolve_vars_if_possible(ty)); // NOTE: we may still need to normalize the built-in deref in case // we have some type like `&::Assoc`, since users of // autoderef expect this type to have been structurally normalized. + // NOTE: even when we follow Receiver chain we still unwrap + // references and pointers here, but this is only symbolic and + // we are not going to really dereferences any references or pointers. + // That happens when autoderef is chasing the Deref chain. if self.infcx.next_trait_solver() && let ty::Alias(..) = ty.kind() { @@ -145,8 +148,8 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { } } + #[instrument(level = "debug", skip(self), ret)] fn overloaded_deref_ty(&mut self, ty: Ty<'tcx>) -> Option> { - debug!("overloaded_deref_ty({:?})", ty); let tcx = self.infcx.tcx; if ty.references_error() { @@ -172,13 +175,13 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { // to support not-yet-defined opaque types. It will succeed for `impl Deref` // but fail for `impl OtherTrait`. if !self.infcx.predicate_may_hold_opaque_types_jank(&obligation) { - debug!("overloaded_deref_ty: cannot match obligation"); + debug!("cannot match obligation"); return None; } let (normalized_ty, obligations) = self.structurally_normalize_ty(Ty::new_projection(tcx, trait_target_def_id, [ty]))?; - debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations); + debug!(?ty, ?normalized_ty, ?obligations); self.state.obligations.extend(obligations); Some(self.infcx.resolve_vars_if_possible(normalized_ty)) @@ -255,11 +258,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { /// Use `core::ops::Receiver` and `core::ops::Receiver::Target` as /// the trait and associated type to iterate, instead of /// `core::ops::Deref` and `core::ops::Deref::Target` - pub fn use_receiver_trait(mut self) -> Self { + pub fn follow_receiver_chain(mut self) -> Self { self.use_receiver_trait = true; self } - pub fn silence_errors(mut self) -> Self { self.silence_errors = true; self diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 0a555c7f6e9df..5d5ec503ef124 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1722,7 +1722,9 @@ fn check_method_receiver<'tcx>( // Report error; would not have worked with `arbitrary_self_types[_pointers]`. { match receiver_validity_err { - ReceiverValidityError::DoesNotDeref if arbitrary_self_types_level.is_some() => { + ReceiverValidityError::DoesNotReceive + if arbitrary_self_types_level.is_some() => + { let hint = match receiver_ty .builtin_deref(false) .unwrap_or(receiver_ty) @@ -1736,7 +1738,7 @@ fn check_method_receiver<'tcx>( tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty, hint }) } - ReceiverValidityError::DoesNotDeref => { + ReceiverValidityError::DoesNotReceive => { tcx.dcx().emit_err(errors::InvalidReceiverTyNoArbitrarySelfTypes { span, receiver_ty, @@ -1758,7 +1760,7 @@ fn check_method_receiver<'tcx>( enum ReceiverValidityError { /// The self type does not get to the receiver type by following the /// autoderef chain. - DoesNotDeref, + DoesNotReceive, /// A type was found which is a method type parameter, and that's not allowed. MethodGenericParamUsed, } @@ -1816,7 +1818,9 @@ fn receiver_is_valid<'tcx>( // types to be method receivers, as identified by following the Receiver // chain. if arbitrary_self_types_enabled.is_some() { - autoderef = autoderef.use_receiver_trait(); + // We are in the wf check, so we would like to deref the references in the type head. + // However, we do not want to walk `Deref` chain. + autoderef = autoderef.follow_receiver_chain(); } // The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`. @@ -1870,7 +1874,7 @@ fn receiver_is_valid<'tcx>( } debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty); - Err(ReceiverValidityError::DoesNotDeref) + Err(ReceiverValidityError::DoesNotReceive) } fn legacy_receiver_is_implemented<'tcx>( diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index b23e7ae8e77bc..0e1a647350ba4 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -1,3 +1,4 @@ +use std::marker::PhantomData; use std::ops::Deref; use rustc_hir as hir; @@ -350,18 +351,37 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // yield an object-type (e.g., `&Object` or `Box` // etc). - let mut autoderef = self.fcx.autoderef(self.span, self_ty); + let fcx = self.fcx; + let span = self.span; + let autoderef = fcx.autoderef(span, self_ty); // We don't need to gate this behind arbitrary self types // per se, but it does make things a bit more gated. - if self.tcx.features().arbitrary_self_types() - || self.tcx.features().arbitrary_self_types_pointers() - { - autoderef = autoderef.use_receiver_trait(); - } + let follow_receiver_chain = self.tcx.features().arbitrary_self_types() + || self.tcx.features().arbitrary_self_types_pointers(); autoderef .include_raw_pointers() + .flat_map(|(ty, derefs)| { + enum EitherIter { + A(A, PhantomData C>), + B(B, PhantomData C>), + } + impl, B: Iterator, C> Iterator for EitherIter { + type Item = C; + fn next(&mut self) -> Option { + match self { + EitherIter::A(a, _) => a.next(), + EitherIter::B(b, _) => b.next(), + } + } + } + if follow_receiver_chain { + EitherIter::A(fcx.autoderef(span, ty).follow_receiver_chain(), PhantomData) + } else { + EitherIter::B([(ty, derefs)].into_iter(), PhantomData) + } + }) .find_map(|(ty, _)| match ty.kind() { ty::Dynamic(data, ..) => Some(closure( self, diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 12f80a197b1b8..a1129bb44f17c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -374,6 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } + #[instrument(level = "debug", skip(self, op))] pub(crate) fn probe_op( &'a self, span: Span, @@ -420,6 +421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .make_query_response_ignoring_pending_obligations(var_values, self_ty), self_ty_is_opaque: false, autoderefs: 0, + receiver_depth: 0, from_unsafe_deref: false, unsize: false, reachable_via_deref: true, @@ -562,12 +564,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } +#[instrument(level = "debug", skip(tcx))] pub(crate) fn method_autoderef_steps<'tcx>( tcx: TyCtxt<'tcx>, goal: CanonicalMethodAutoderefStepsGoal<'tcx>, ) -> MethodAutoderefStepsResult<'tcx> { - debug!("method_autoderef_steps({:?})", goal); - let (ref infcx, goal, inference_vars) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &goal); let ParamEnvAnd { param_env, @@ -621,44 +622,46 @@ pub(crate) fn method_autoderef_steps<'tcx>( let arbitrary_self_types_enabled = tcx.features().arbitrary_self_types() || tcx.features().arbitrary_self_types_pointers(); let (mut steps, reached_recursion_limit): (Vec<_>, bool) = if arbitrary_self_types_enabled { - let reachable_via_deref = - autoderef_via_deref.by_ref().map(|_| true).chain(std::iter::repeat(false)); - - let mut autoderef_via_receiver = - Autoderef::new(infcx, param_env, hir::def_id::CRATE_DEF_ID, DUMMY_SP, self_ty) - .include_raw_pointers() - .use_receiver_trait() - .silence_errors(); - let steps = autoderef_via_receiver - .by_ref() - .zip(reachable_via_deref) - .map(|((ty, d), reachable_via_deref)| { + let mut reached_recursion_limit = false; + let mut steps = vec![]; + + for (ty, autoderefs) in &mut autoderef_via_deref { + let mut recv_chain = + Autoderef::new(infcx, param_env, hir::def_id::CRATE_DEF_ID, DUMMY_SP, ty) + .include_raw_pointers() + .follow_receiver_chain() + .silence_errors(); + steps.extend(recv_chain.by_ref().map(|(ty, receiver_depth)| { let step = CandidateStep { self_ty: infcx .make_query_response_ignoring_pending_obligations(inference_vars, ty), self_ty_is_opaque: self_ty_is_opaque(ty), - autoderefs: d, + autoderefs, + receiver_depth, from_unsafe_deref: reached_raw_pointer, unsize: false, - reachable_via_deref, + reachable_via_deref: receiver_depth == 0, }; if ty.is_raw_ptr() { // all the subsequent steps will be from_unsafe_deref reached_raw_pointer = true; } + step - }) - .collect(); - (steps, autoderef_via_receiver.reached_recursion_limit()) + })); + reached_recursion_limit |= recv_chain.reached_recursion_limit(); + } + (steps, reached_recursion_limit || autoderef_via_deref.reached_recursion_limit()) } else { let steps = autoderef_via_deref .by_ref() - .map(|(ty, d)| { + .map(|(ty, autoderefs)| { let step = CandidateStep { self_ty: infcx .make_query_response_ignoring_pending_obligations(inference_vars, ty), self_ty_is_opaque: self_ty_is_opaque(ty), - autoderefs: d, + autoderefs, + receiver_depth: 0, from_unsafe_deref: reached_raw_pointer, unsize: false, reachable_via_deref: true, @@ -691,6 +694,7 @@ pub(crate) fn method_autoderef_steps<'tcx>( ), self_ty_is_opaque: false, autoderefs, + receiver_depth: 0, // this could be from an unsafe deref if we had // a *mut/const [T; N] from_unsafe_deref: reached_raw_pointer, @@ -791,7 +795,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn assemble_inherent_candidates(&mut self) { for step in self.steps.iter() { - self.assemble_probe(&step.self_ty, step.autoderefs); + self.assemble_probe(&step.self_ty, step.receiver_depth); } } @@ -1236,6 +1240,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }) } + #[instrument(level = "debug", skip(self))] fn pick_all_method<'b>( &self, pick_diag_hints: &mut PickDiagHints<'b, 'tcx>, @@ -1274,22 +1279,23 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Check for shadowing of a by-reference method by a by-value method (see comments on check_for_shadowing) if let Some(by_value_pick) = by_value_pick { - if let Ok(by_value_pick) = by_value_pick.as_ref() { - if by_value_pick.kind == PickKind::InherentImplPick { - for mutbl in [hir::Mutability::Not, hir::Mutability::Mut] { - if let Err(e) = self.check_for_shadowed_autorefd_method( - by_value_pick, - step, - self_ty, - &instantiate_self_ty_obligations, - mutbl, - track_unstable_candidates, - ) { - return Some(Err(e)); - } + if let Ok(by_value_pick) = &by_value_pick + && matches!(by_value_pick.kind, PickKind::InherentImplPick) + { + for mutbl in [hir::Mutability::Not, hir::Mutability::Mut] { + if let Err(e) = self.check_for_shadowed_autorefd_method( + by_value_pick, + step, + self_ty, + &instantiate_self_ty_obligations, + mutbl, + track_unstable_candidates, + ) { + return Some(Err(e)); } } } + return Some(by_value_pick); } @@ -1303,21 +1309,22 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ); // Check for shadowing of a by-mut-ref method by a by-reference method (see comments on check_for_shadowing) if let Some(autoref_pick) = autoref_pick { - if let Ok(autoref_pick) = autoref_pick.as_ref() { + if let Ok(autoref_pick) = &autoref_pick + && matches!(autoref_pick.kind, PickKind::InherentImplPick) + { // Check we're not shadowing others - if autoref_pick.kind == PickKind::InherentImplPick { - if let Err(e) = self.check_for_shadowed_autorefd_method( - autoref_pick, - step, - self_ty, - &instantiate_self_ty_obligations, - hir::Mutability::Mut, - track_unstable_candidates, - ) { - return Some(Err(e)); - } + if let Err(e) = self.check_for_shadowed_autorefd_method( + autoref_pick, + step, + self_ty, + &instantiate_self_ty_obligations, + hir::Mutability::Mut, + track_unstable_candidates, + ) { + return Some(Err(e)); } } + return Some(autoref_pick); } @@ -1372,20 +1379,26 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } /// Check for cases where arbitrary self types allows shadowing - /// of methods that might be a compatibility break. Specifically, - /// we have something like: + /// of methods that might be a compatibility break. + /// + /// As an example, first we examine this code. /// ```ignore (illustrative) /// struct A; /// impl A { - /// fn foo(self: &NonNull) {} - /// // note this is by reference + /// fn foo(self: &NonNull) { + /// // ^ note that the receiver is a reference + /// } /// } /// ``` - /// then we've come along and added this method to `NonNull`: + /// Then we've come along and added this method to `NonNull`: /// ```ignore (illustrative) - /// fn foo(self) // note this is by value + /// impl A { + /// fn foo(self: A) // note this is by value + /// } /// ``` - /// Report an error in this case. + /// Here we report an error on the ground of shadowing `foo` in this case. + /// Shadowing happens when an inherent method candidate appears deeper in + /// the Receiver sub-chain that is rooted from the same `self` value. fn check_for_shadowed_autorefd_method( &self, possible_shadower: &Pick<'tcx>, @@ -1409,19 +1422,20 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // unstable_candidates in order to reflect the behavior of the // main search. let mut pick_diag_hints = PickDiagHints { - unstable_candidates: if track_unstable_candidates { Some(Vec::new()) } else { None }, - unsatisfied_predicates: &mut Vec::new(), + unstable_candidates: track_unstable_candidates.then(Vec::new), + unsatisfied_predicates: &mut vec![], }; // Set criteria for how we find methods possibly shadowed by 'possible_shadower' let pick_constraints = PickConstraintsForShadowed { // It's the same `self` type... autoderefs: possible_shadower.autoderefs, // ... but the method was found in an impl block determined - // by searching further along the Receiver chain than the other, + // by searching further along the Receiver sub-chain than the other, // showing that it's a smart pointer type causing the problem... receiver_steps: possible_shadower.receiver_steps, // ... and they don't end up pointing to the same item in the - // first place (could happen with things like blanket impls for T) + // first place. + // This could happen with things like blanket impls for T. def_id: possible_shadower.item.def_id, }; // A note on the autoderefs above. Within pick_by_value_method, an extra @@ -1441,13 +1455,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // ``` // then we've come along and added this method to `NonNull`: // ``` - // fn foo(&self) // note this is by single reference + // impl NonNull { + // .. + // fn foo(&self) { .. } // note this is by single reference + // } // ``` // and the call is: // ``` - // let bar = NonNull; - // let bar = &foo; - // bar.foo(); + // let a: NonNull = ..; + // let ref_a = &a; + // ref_a.foo(); // ``` // In these circumstances, the logic is wrong, and we wouldn't spot // the shadowing, because the autoderef-based maths wouldn't line up. @@ -1463,7 +1480,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ); // Look for actual pairs of shadower/shadowed which are // the sort of shadowing case we want to avoid. Specifically... - if let Some(Ok(possible_shadowed)) = potentially_shadowed_pick.as_ref() { + if let Some(Ok(possible_shadowed)) = &potentially_shadowed_pick { let sources = [possible_shadower, possible_shadowed] .into_iter() .map(|p| self.candidate_source_from_pick(p)) @@ -1656,8 +1673,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - if self.private_candidate.get().is_none() { - if let Some(Ok(pick)) = self.consider_candidates( + if self.private_candidate.get().is_none() + && let Some(Ok(pick)) = self.consider_candidates( self_ty, instantiate_self_ty_obligations, &self.private_candidates, @@ -1666,9 +1683,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { unsatisfied_predicates: &mut vec![], }, None, - ) { - self.private_candidate.set(Some((pick.item.as_def_kind(), pick.item.def_id))); - } + ) + { + self.private_candidate.set(Some((pick.item.as_def_kind(), pick.item.def_id))); } None } @@ -1684,9 +1701,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let mut applicable_candidates: Vec<_> = candidates .iter() .filter(|candidate| { - pick_constraints - .map(|pick_constraints| pick_constraints.candidate_may_shadow(&candidate)) - .unwrap_or(true) + pick_constraints.map_or(true, |pick_constraints| { + pick_constraints.candidate_may_shadow(&candidate) + }) }) .map(|probe| { ( @@ -1699,7 +1716,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ), ) }) - .filter(|&(_, status)| status != ProbeResult::NoMatch) + .filter(|&(_, status)| !matches!(status, ProbeResult::NoMatch)) .collect(); debug!("applicable_candidates: {:?}", applicable_candidates); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 895c8c0295a04..393205d369652 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1130,7 +1130,7 @@ rustc_queries! { } query incoherent_impls(key: SimplifiedType) -> &'tcx [DefId] { - desc { |tcx| "collecting all inherent impls for `{:?}`", key } + desc { |tcx| "collecting all incoherent impls for `{:?}`", key } } /// Unsafety-check this `LocalDefId`. diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index c5cd7c54e4e86..e360215613bf7 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -172,6 +172,7 @@ pub struct CandidateStep<'tcx> { /// reachable via Deref when examining what the receiver type can /// be converted into by autodereffing. pub reachable_via_deref: bool, + pub receiver_depth: usize, } #[derive(Copy, Clone, Debug, HashStable)] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b44b1c966a431..ed51edb5c9c6a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2525,6 +2525,8 @@ mod ref_mut { use std::cell::{BorrowMutError, Cell, Ref, RefCell, RefMut}; use std::fmt; use std::ops::Deref; + #[cfg(not(bootstrap))] + use std::ops::Receiver; use crate::Resolver; @@ -2541,6 +2543,10 @@ mod ref_mut { self.p } } + #[cfg(not(bootstrap))] + impl<'a, T> Receiver for RefOrMut<'a, T> { + type Target = T; + } impl<'a, T> AsRef for RefOrMut<'a, T> { fn as_ref(&self) -> &T { diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 49ff768bed1b2..c6112010ea986 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -195,7 +195,7 @@ use core::marker::{Tuple, Unsize}; use core::mem::{self, SizedTypeProperties}; use core::ops::{ AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, - DerefPure, DispatchFromDyn, LegacyReceiver, + DerefPure, DispatchFromDyn, LegacyReceiver, Receiver, }; use core::pin::{Pin, PinCoerceUnsized}; use core::ptr::{self, NonNull, Unique}; @@ -1995,6 +1995,10 @@ unsafe impl DerefPure for Box {} #[unstable(feature = "legacy_receiver_trait", issue = "none")] impl LegacyReceiver for Box {} +#[unstable(feature = "arbitrary_self_types", issue = "44874")] +impl Receiver for Box { + type Target = T; +} #[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized, A: Allocator> FnOnce for Box { diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 87ad5b0ce30e6..eef2b792db05f 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -87,6 +87,8 @@ // tidy-alphabetical-start #![feature(alloc_layout_extra)] #![feature(allocator_api)] +#![feature(arbitrary_self_types)] +#![feature(arbitrary_self_types_pointers)] #![feature(array_into_iter_constructors)] #![feature(array_windows)] #![feature(ascii_char)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 2b62b92d43886..98bcd2f5ce3bb 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -254,7 +254,9 @@ use core::iter; use core::marker::{PhantomData, Unsize}; use core::mem::{self, ManuallyDrop, align_of_val_raw}; use core::num::NonZeroUsize; -use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; +use core::ops::{ + CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver, Receiver, +}; use core::panic::{RefUnwindSafe, UnwindSafe}; #[cfg(not(no_global_oom_handling))] use core::pin::Pin; @@ -2261,6 +2263,10 @@ unsafe impl DerefPure for UniqueRc {} #[unstable(feature = "legacy_receiver_trait", issue = "none")] impl LegacyReceiver for Rc {} +#[unstable(feature = "arbitrary_self_types", issue = "44874")] +impl Receiver for Rc { + type Target = T; +} #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Rc { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 5927d03646928..81c836e1cb143 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -21,7 +21,9 @@ use core::iter; use core::marker::{PhantomData, Unsize}; use core::mem::{self, ManuallyDrop, align_of_val_raw}; use core::num::NonZeroUsize; -use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; +use core::ops::{ + CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver, Receiver, +}; use core::panic::{RefUnwindSafe, UnwindSafe}; use core::pin::{Pin, PinCoerceUnsized}; use core::ptr::{self, NonNull}; @@ -2245,6 +2247,10 @@ unsafe impl DerefPure for Arc {} #[unstable(feature = "legacy_receiver_trait", issue = "none")] impl LegacyReceiver for Arc {} +#[unstable(feature = "arbitrary_self_types", issue = "44874")] +impl Receiver for Arc { + type Target = T; +} #[cfg(not(no_global_oom_handling))] impl Arc { diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 4b767d8d62218..7b91b9173a2f0 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1204,8 +1204,12 @@ pub trait FnPtr: Copy + Clone { /// &self.0 /// } /// } +/// impl Receiver for MySmartPointer { +/// type Target = T; +/// } /// -/// // You can always define this trait. (as long as you have #![feature(arbitrary_self_types)]) +/// // You can define this trait, +/// // given that you also enable `#![feature(arbitrary_self_types)]`. /// trait MyTrait { /// fn func(self: MySmartPointer); /// } diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index 305861ea7b698..39febee2bbe29 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -374,14 +374,6 @@ pub trait Receiver: PointeeSized { type Target: ?Sized; } -#[unstable(feature = "arbitrary_self_types", issue = "44874")] -impl Receiver for P -where - P: Deref, -{ - type Target = T; -} - /// Indicates that a struct can be used as a method receiver, without the /// `arbitrary_self_types` feature. This is implemented by stdlib pointer types like `Box`, /// `Rc`, `&T`, and `Pin

`. @@ -399,6 +391,14 @@ pub trait LegacyReceiver: PointeeSized { #[unstable(feature = "legacy_receiver_trait", issue = "none")] impl LegacyReceiver for &T {} +#[unstable(feature = "arbitrary_self_types", issue = "44874")] +impl Receiver for &T { + type Target = T; +} #[unstable(feature = "legacy_receiver_trait", issue = "none")] impl LegacyReceiver for &mut T {} +#[unstable(feature = "arbitrary_self_types", issue = "44874")] +impl Receiver for &mut T { + type Target = T; +} diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 535830f2e749f..c72ef1602891f 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -921,7 +921,9 @@ #![stable(feature = "pin", since = "1.33.0")] use crate::hash::{Hash, Hasher}; -use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; +use crate::ops::{ + CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver, Receiver, +}; #[allow(unused_imports)] use crate::{ cell::{RefCell, UnsafeCell}, @@ -1702,6 +1704,10 @@ unsafe impl DerefPure for Pin {} #[unstable(feature = "legacy_receiver_trait", issue = "none")] impl LegacyReceiver for Pin {} +#[unstable(feature = "arbitrary_self_types", issue = "44874")] +impl Receiver for Pin { + type Target = Ptr; +} #[stable(feature = "pin", since = "1.33.0")] impl fmt::Debug for Pin { diff --git a/src/tools/miri/src/shims/files.rs b/src/tools/miri/src/shims/files.rs index 8c29cb040b55a..833a56a9101ff 100644 --- a/src/tools/miri/src/shims/files.rs +++ b/src/tools/miri/src/shims/files.rs @@ -4,6 +4,8 @@ use std::fs::{File, Metadata}; use std::io::{ErrorKind, IsTerminal, Seek, SeekFrom, Write}; use std::marker::CoercePointee; use std::ops::Deref; +#[cfg(not(bootstrap))] +use std::ops::Receiver; use std::rc::{Rc, Weak}; use std::{fs, io}; @@ -43,6 +45,10 @@ impl Deref for FileDescriptionRef { &self.0.inner } } +#[cfg(not(bootstrap))] +impl Receiver for FileDescriptionRef { + type Target = T; +} impl FileDescriptionRef { pub fn id(&self) -> FdId { diff --git a/src/tools/miri/tests/pass/dyn-arbitrary-self.rs b/src/tools/miri/tests/pass/dyn-arbitrary-self.rs index d993e5ad68ccc..564cea3168199 100644 --- a/src/tools/miri/tests/pass/dyn-arbitrary-self.rs +++ b/src/tools/miri/tests/pass/dyn-arbitrary-self.rs @@ -1,6 +1,12 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows -#![feature(arbitrary_self_types_pointers, unsize, coerce_unsized, dispatch_from_dyn)] +#![feature( + arbitrary_self_types, + arbitrary_self_types_pointers, + unsize, + coerce_unsized, + dispatch_from_dyn +)] #![feature(rustc_attrs)] fn pin_box_dyn() { @@ -63,7 +69,7 @@ fn stdlib_pointers() { fn pointers_and_wrappers() { use std::marker::Unsize; - use std::ops::{CoerceUnsized, Deref, DispatchFromDyn}; + use std::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver}; struct Ptr(Box); @@ -74,6 +80,9 @@ fn pointers_and_wrappers() { &*self.0 } } + impl Receiver for Ptr { + type Target = T; + } impl + ?Sized, U: ?Sized> CoerceUnsized> for Ptr {} impl + ?Sized, U: ?Sized> DispatchFromDyn> for Ptr {} @@ -87,6 +96,9 @@ fn pointers_and_wrappers() { &self.0 } } + impl Receiver for Wrapper { + type Target = T; + } impl, U> CoerceUnsized> for Wrapper {} impl, U> DispatchFromDyn> for Wrapper {} diff --git a/tests/crashes/138564.rs b/tests/crashes/138564.rs index b10f75f8cdd0c..460917260be0e 100644 --- a/tests/crashes/138564.rs +++ b/tests/crashes/138564.rs @@ -3,7 +3,7 @@ #![feature(unsize, dispatch_from_dyn, arbitrary_self_types)] use std::marker::Unsize; -use std::ops::{Deref, DispatchFromDyn}; +use std::ops::{Deref, DispatchFromDyn, Receiver}; #[repr(align(16))] pub struct MyPointer(*const T); @@ -15,7 +15,9 @@ impl Deref for MyPointer { unimplemented!() } } - +impl Receiver for MyPointer { + type Target = T; +} pub trait Trait { fn foo(self: MyPointer) {} } diff --git a/tests/ui/deriving/deriving-coerce-pointee.rs b/tests/ui/deriving/deriving-coerce-pointee.rs index 26762e4d0face..0297119813a69 100644 --- a/tests/ui/deriving/deriving-coerce-pointee.rs +++ b/tests/ui/deriving/deriving-coerce-pointee.rs @@ -2,6 +2,7 @@ #![feature(derive_coerce_pointee, arbitrary_self_types)] use std::marker::CoercePointee; +use std::ops::{Deref, Receiver}; #[derive(CoercePointee)] #[repr(transparent)] @@ -16,13 +17,17 @@ impl Clone for MyPointer<'_, T> { } } -impl<'a, T: ?Sized> core::ops::Deref for MyPointer<'a, T> { +impl<'a, T: ?Sized> Deref for MyPointer<'a, T> { type Target = T; fn deref(&self) -> &'a T { self.ptr } } +impl<'a, T: ?Sized> Receiver for MyPointer<'a, T> { + type Target = T; +} + struct MyValue(u32); impl MyValue { fn through_pointer(self: MyPointer<'_, Self>) -> u32 { diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.rs b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.rs index 47ca7e3497578..f57316de5be67 100644 --- a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.rs +++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.rs @@ -1,6 +1,4 @@ -use std::{ - ops::Deref, -}; +use std::ops::Deref; struct Ptr(Box); @@ -13,17 +11,17 @@ impl Deref for Ptr { } trait Foo { - fn foo(self: Ptr); //~ ERROR `Ptr` cannot be used as the type of `self` without + fn foo(self: Ptr); //~ ERROR invalid `self` parameter type: `Ptr` } struct Bar; impl Foo for Bar { - fn foo(self: Ptr) {} //~ ERROR `Ptr` cannot be used as the type of `self` without + fn foo(self: Ptr) {} //~ ERROR invalid `self` parameter type: `Ptr` } impl Bar { - fn bar(self: Box>) {} //~ ERROR `Box>` cannot be used as the + fn bar(self: Box>) {} //~ ERROR invalid `self` parameter type: `Box>` } fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr index 3ffba533d63fc..5269ee18a3071 100644 --- a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr +++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr @@ -1,36 +1,30 @@ -error[E0658]: `Ptr` cannot be used as the type of `self` without the `arbitrary_self_types` feature - --> $DIR/feature-gate-arbitrary-self-types.rs:22:18 +error[E0307]: invalid `self` parameter type: `Ptr` + --> $DIR/feature-gate-arbitrary-self-types.rs:20:18 | LL | fn foo(self: Ptr) {} | ^^^^^^^^^ | - = 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` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0658]: `Box>` cannot be used as the type of `self` without the `arbitrary_self_types` feature - --> $DIR/feature-gate-arbitrary-self-types.rs:26:18 +error[E0307]: invalid `self` parameter type: `Box>` + --> $DIR/feature-gate-arbitrary-self-types.rs:24:18 | LL | fn bar(self: Box>) {} | ^^^^^^^^^^^^^^ | - = 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` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0658]: `Ptr` cannot be used as the type of `self` without the `arbitrary_self_types` feature - --> $DIR/feature-gate-arbitrary-self-types.rs:16:18 +error[E0307]: invalid `self` parameter type: `Ptr` + --> $DIR/feature-gate-arbitrary-self-types.rs:14:18 | LL | fn foo(self: Ptr); | ^^^^^^^^^ | - = 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` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0307`. diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.rs b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.rs index 8d7ccea9e6477..663a3eef535fa 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.rs +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.rs @@ -2,10 +2,8 @@ #![feature(arbitrary_self_types, unsize, coerce_unsized)] -use std::{ - marker::Unsize, - ops::{CoerceUnsized, Deref}, -}; +use std::marker::Unsize; +use std::ops::{CoerceUnsized, Deref, Receiver}; struct Ptr(Box); @@ -16,6 +14,9 @@ impl Deref for Ptr { &*self.0 } } +impl Receiver for Ptr { + type Target = T; +} impl + ?Sized, U: ?Sized> CoerceUnsized> for Ptr {} // Because this impl is missing the coercion below fails. diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr index c70ab65aa9056..8b99d64efe683 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:32:33 + --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:33:33 | LL | fn ptr(self: Ptr); | --------- help: consider changing method `ptr`'s `self` parameter to be `&self`: `&Self` @@ -9,7 +9,7 @@ LL | Ptr(Box::new(4)) as Ptr; | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:25:18 + --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:26:18 | LL | trait Trait { | ----- this trait is not dyn compatible... diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs index 6ceec11930833..358668dacf178 100644 --- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs +++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs @@ -10,7 +10,7 @@ use std::marker::PhantomData; mod internal { - use std::ops::{CoerceUnsized, Deref, DispatchFromDyn}; + use std::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver}; use std::marker::{PhantomData, Unsize}; pub struct Smaht(pub Box, pub PhantomData); @@ -22,6 +22,9 @@ mod internal { &self.0 } } + impl Receiver for Smaht { + type Target = T; + } impl, U: ?Sized, MISC> CoerceUnsized> for Smaht {} @@ -52,6 +55,9 @@ mod internal { type Target = (); fn deref(&self) -> &() { &() } } + impl Receiver for dyn Foo { + type Target = (); + } impl Foo for () {} } diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index aeecb82e9d910..a8707bcc24e68 100644 --- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:88:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:94:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` @@ -7,7 +7,7 @@ LL | let _seetype: () = z; | expected due to this error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:105:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:111:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u64` @@ -15,18 +15,18 @@ LL | let _seetype: () = z; | expected due to this error[E0034]: multiple applicable items in scope - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:123:15 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:129:15 | LL | let z = x.foo(); | ^^^ multiple `foo` found | note: candidate #1 is defined in an impl of the trait `NuisanceFoo` for the type `T` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:73:9 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:79:9 | LL | fn foo(self) {} | ^^^^^^^^^^^^ note: candidate #2 is defined in an impl of the trait `X` for the type `T` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:46:9 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:49:9 | LL | fn foo(self: Smaht) -> u64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL + let z = X::foo(x); | error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:140:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:146:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u8` @@ -50,7 +50,7 @@ LL | let _seetype: () = z; | expected due to this error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:158:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:164:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` @@ -58,7 +58,7 @@ LL | let _seetype: () = z; | expected due to this error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:175:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:181:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` diff --git a/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs index 495d261c549ca..a3308ae1bd0fa 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs +++ b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs @@ -1,6 +1,6 @@ #![feature(arbitrary_self_types)] -use std::ops::{Receiver, Deref}; +use std::ops::{Deref, Receiver}; struct SmartPtr<'a, T: ?Sized>(&'a T); @@ -11,31 +11,34 @@ impl<'a, T: ?Sized> Deref for SmartPtr<'a, T> { } } +impl<'a, T: ?Sized> Receiver for SmartPtr<'a, T> { + type Target = T; +} + impl<'a, T: ?Sized> Clone for SmartPtr<'a, T> { fn clone(&self) -> Self { Self(self.0) } } -impl<'a, T: ?Sized> Copy for SmartPtr<'a, T> { -} +impl<'a, T: ?Sized> Copy for SmartPtr<'a, T> {} struct Foo(u32); impl Foo { - fn a>(self: R) -> u32 { + fn a>(self: R) -> u32 { //~^ ERROR invalid generic `self` parameter type: `R` 2 } - fn b>(self: R) -> u32 { + fn b + Receiver>(self: R) -> u32 { //~^ ERROR invalid generic `self` parameter type: `R` self.0 } - fn c(self: impl Receiver) -> u32 { + fn c(self: impl Receiver) -> u32 { //~^ ERROR invalid generic `self` parameter type: `impl Receiver` 3 } - fn d(self: impl Deref) -> u32 { - //~^ ERROR invalid generic `self` parameter type: `impl Deref` + fn d(self: impl Deref + Receiver) -> u32 { + //~^ ERROR invalid generic `self` parameter type: `impl Deref + Receiver` self.0 } } diff --git a/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr index bafa290a3cfd0..14af53ed8b268 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr @@ -1,53 +1,53 @@ error[E0801]: invalid generic `self` parameter type: `R` - --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:25:42 + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:28:44 | -LL | fn a>(self: R) -> u32 { - | ^ +LL | fn a>(self: R) -> u32 { + | ^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `R` - --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:29:39 + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:32:67 | -LL | fn b>(self: R) -> u32 { - | ^ +LL | fn b + Receiver>(self: R) -> u32 { + | ^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `impl Receiver` - --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:33:16 + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:36:16 | -LL | fn c(self: impl Receiver) -> u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn c(self: impl Receiver) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0801]: invalid generic `self` parameter type: `impl Deref` - --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:37:16 +error[E0801]: invalid generic `self` parameter type: `impl Deref + Receiver` + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:40:16 | -LL | fn d(self: impl Deref) -> u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn d(self: impl Deref + Receiver) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0308]: mismatched types - --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:51:16 + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:54:16 | LL | assert_eq!(foo.a::<&Foo>(), 2); | ^^^ expected `&Foo`, found `Foo` error[E0308]: mismatched types - --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:53:16 + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:56:16 | LL | assert_eq!(foo.b::<&Foo>(), 1); | ^^^ expected `&Foo`, found `Foo` error[E0308]: mismatched types - --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:60:16 + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:63:16 | LL | assert_eq!(smart_ptr.a::<&Foo>(), 2); | ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>` @@ -56,7 +56,7 @@ LL | assert_eq!(smart_ptr.a::<&Foo>(), 2); found struct `SmartPtr<'_, Foo>` error[E0308]: mismatched types - --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:62:16 + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:65:16 | LL | assert_eq!(smart_ptr.b::<&Foo>(), 1); | ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>` diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr index 7cf9c9a3afd4d..d6b9778de0326 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr @@ -1,87 +1,83 @@ error[E0801]: invalid generic `self` parameter type: `R` - --> $DIR/arbitrary-self-from-method-substs.rs:9:43 + --> $DIR/arbitrary-self-from-method-substs.rs:12:43 | -LL | fn get>(self: R) -> u32 { +LL | fn get>(self: R) -> u32 | ^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `&R` - --> $DIR/arbitrary-self-from-method-substs.rs:13:44 + --> $DIR/arbitrary-self-from-method-substs.rs:20:44 | -LL | fn get1>(self: &R) -> u32 { +LL | fn get1>(self: &R) -> u32 | ^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `&mut R` - --> $DIR/arbitrary-self-from-method-substs.rs:17:44 + --> $DIR/arbitrary-self-from-method-substs.rs:28:44 | -LL | fn get2>(self: &mut R) -> u32 { +LL | fn get2>(self: &mut R) -> u32 | ^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `Rc` - --> $DIR/arbitrary-self-from-method-substs.rs:21:44 + --> $DIR/arbitrary-self-from-method-substs.rs:36:44 | -LL | fn get3>(self: std::rc::Rc) -> u32 { +LL | fn get3>(self: std::rc::Rc) -> u32 | ^^^^^^^^^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `&Rc` - --> $DIR/arbitrary-self-from-method-substs.rs:25:44 + --> $DIR/arbitrary-self-from-method-substs.rs:44:44 | -LL | fn get4>(self: &std::rc::Rc) -> u32 { +LL | fn get4>(self: &std::rc::Rc) -> u32 | ^^^^^^^^^^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `Rc<&R>` - --> $DIR/arbitrary-self-from-method-substs.rs:29:44 + --> $DIR/arbitrary-self-from-method-substs.rs:52:44 | -LL | fn get5>(self: std::rc::Rc<&R>) -> u32 { +LL | fn get5>(self: std::rc::Rc<&R>) -> u32 | ^^^^^^^^^^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0658]: `::Receiver` cannot be used as the type of `self` without the `arbitrary_self_types` feature - --> $DIR/arbitrary-self-from-method-substs.rs:33:37 +error[E0307]: invalid `self` parameter type: `::Receiver` + --> $DIR/arbitrary-self-from-method-substs.rs:63:37 | LL | fn get6(self: FR::Receiver, other: FR) -> u32 { | ^^^^^^^^^^^^ | - = 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` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature - --> $DIR/arbitrary-self-from-method-substs.rs:61:18 +error[E0307]: invalid `self` parameter type: `R` + --> $DIR/arbitrary-self-from-method-substs.rs:102:18 | LL | fn get(self: R) {} | ^ | - = 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` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0271]: type mismatch resolving `::Receiver == Foo` - --> $DIR/arbitrary-self-from-method-substs.rs:92:9 + --> $DIR/arbitrary-self-from-method-substs.rs:136:9 | LL | foo.get6(Silly); | ^^^^ type mismatch resolving `::Receiver == Foo` | note: expected this to be `Foo` - --> $DIR/arbitrary-self-from-method-substs.rs:71:21 + --> $DIR/arbitrary-self-from-method-substs.rs:115:21 | LL | type Receiver = std::rc::Rc; | ^^^^^^^^^^^^^^^^ @@ -89,13 +85,13 @@ LL | type Receiver = std::rc::Rc; found struct `Rc` error[E0271]: type mismatch resolving `::Receiver == &Foo` - --> $DIR/arbitrary-self-from-method-substs.rs:96:9 + --> $DIR/arbitrary-self-from-method-substs.rs:140:9 | LL | foo.get6(Silly); | ^^^^ type mismatch resolving `::Receiver == &Foo` | note: expected this to be `&Foo` - --> $DIR/arbitrary-self-from-method-substs.rs:71:21 + --> $DIR/arbitrary-self-from-method-substs.rs:115:21 | LL | type Receiver = std::rc::Rc; | ^^^^^^^^^^^^^^^^ @@ -103,7 +99,7 @@ LL | type Receiver = std::rc::Rc; found struct `Rc` error[E0599]: the method `get` exists for struct `Rc>`, but its trait bounds were not satisfied - --> $DIR/arbitrary-self-from-method-substs.rs:100:7 + --> $DIR/arbitrary-self-from-method-substs.rs:144:7 | LL | struct Bar(std::marker::PhantomData); | ------------- doesn't satisfy `Bar<_>: Deref` @@ -118,12 +114,12 @@ note: the following trait bounds were not satisfied: `<&mut Rc> as Deref>::Target = Bar<&mut Rc>>` `> as Deref>::Target = Bar>>` `Bar<_>: Deref` - --> $DIR/arbitrary-self-from-method-substs.rs:60:9 + --> $DIR/arbitrary-self-from-method-substs.rs:97:9 | -LL | impl> Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ - | | | - | | unsatisfied trait bound introduced here +LL | impl> Bar + | ^^^^^^^^^^^^^^^^^^^^ ------ + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here note: the trait `Deref` must be implemented --> $SRC_DIR/core/src/ops/deref.rs:LL:COL @@ -132,7 +128,7 @@ note: the trait `Deref` must be implemented candidate #1: `SliceIndex` error[E0599]: the method `get` exists for reference `&Rc>`, but its trait bounds were not satisfied - --> $DIR/arbitrary-self-from-method-substs.rs:108:7 + --> $DIR/arbitrary-self-from-method-substs.rs:152:7 | LL | struct Bar(std::marker::PhantomData); | ------------- doesn't satisfy `Bar<_>: Deref` @@ -149,12 +145,12 @@ note: the following trait bounds were not satisfied: `<&mut Rc> as Deref>::Target = Bar<&mut Rc>>` `> as Deref>::Target = Bar>>` `Bar<_>: Deref` - --> $DIR/arbitrary-self-from-method-substs.rs:60:9 + --> $DIR/arbitrary-self-from-method-substs.rs:97:9 | -LL | impl> Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ - | | | - | | unsatisfied trait bound introduced here +LL | impl> Bar + | ^^^^^^^^^^^^^^^^^^^^ ------ + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here note: the trait `Deref` must be implemented --> $SRC_DIR/core/src/ops/deref.rs:LL:COL @@ -164,5 +160,5 @@ note: the trait `Deref` must be implemented error: aborting due to 12 previous errors -Some errors have detailed explanations: E0271, E0599, E0658, E0801. +Some errors have detailed explanations: E0271, E0307, E0599, E0801. For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr b/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr index f67918a2577ac..217a7ee310a77 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr @@ -1,65 +1,65 @@ error[E0801]: invalid generic `self` parameter type: `R` - --> $DIR/arbitrary-self-from-method-substs.rs:9:43 + --> $DIR/arbitrary-self-from-method-substs.rs:12:43 | -LL | fn get>(self: R) -> u32 { +LL | fn get>(self: R) -> u32 | ^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `&R` - --> $DIR/arbitrary-self-from-method-substs.rs:13:44 + --> $DIR/arbitrary-self-from-method-substs.rs:20:44 | -LL | fn get1>(self: &R) -> u32 { +LL | fn get1>(self: &R) -> u32 | ^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `&mut R` - --> $DIR/arbitrary-self-from-method-substs.rs:17:44 + --> $DIR/arbitrary-self-from-method-substs.rs:28:44 | -LL | fn get2>(self: &mut R) -> u32 { +LL | fn get2>(self: &mut R) -> u32 | ^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `Rc` - --> $DIR/arbitrary-self-from-method-substs.rs:21:44 + --> $DIR/arbitrary-self-from-method-substs.rs:36:44 | -LL | fn get3>(self: std::rc::Rc) -> u32 { +LL | fn get3>(self: std::rc::Rc) -> u32 | ^^^^^^^^^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `&Rc` - --> $DIR/arbitrary-self-from-method-substs.rs:25:44 + --> $DIR/arbitrary-self-from-method-substs.rs:44:44 | -LL | fn get4>(self: &std::rc::Rc) -> u32 { +LL | fn get4>(self: &std::rc::Rc) -> u32 | ^^^^^^^^^^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0801]: invalid generic `self` parameter type: `Rc<&R>` - --> $DIR/arbitrary-self-from-method-substs.rs:29:44 + --> $DIR/arbitrary-self-from-method-substs.rs:52:44 | -LL | fn get5>(self: std::rc::Rc<&R>) -> u32 { +LL | fn get5>(self: std::rc::Rc<&R>) -> u32 | ^^^^^^^^^^^^^^^ | = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0308]: mismatched types - --> $DIR/arbitrary-self-from-method-substs.rs:76:5 + --> $DIR/arbitrary-self-from-method-substs.rs:120:5 | LL | foo.get::<&Foo>(); | ^^^ expected `&Foo`, found `Foo` error[E0308]: mismatched types - --> $DIR/arbitrary-self-from-method-substs.rs:78:5 + --> $DIR/arbitrary-self-from-method-substs.rs:122:5 | LL | foo.get::>(); | ^^^ expected `Rc`, found `Foo` @@ -68,7 +68,7 @@ LL | foo.get::>(); found struct `Foo` error[E0308]: mismatched types - --> $DIR/arbitrary-self-from-method-substs.rs:84:5 + --> $DIR/arbitrary-self-from-method-substs.rs:128:5 | LL | smart_ptr.get::>(); | ^^^^^^^^^ expected `SmartPtr2<'_, Foo>`, found `SmartPtr<'_, Foo>` @@ -77,7 +77,7 @@ LL | smart_ptr.get::>(); found struct `SmartPtr<'_, Foo>` error[E0308]: mismatched types - --> $DIR/arbitrary-self-from-method-substs.rs:86:5 + --> $DIR/arbitrary-self-from-method-substs.rs:130:5 | LL | smart_ptr.get::<&Foo>(); | ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>` @@ -86,13 +86,13 @@ LL | smart_ptr.get::<&Foo>(); found struct `SmartPtr<'_, Foo>` error[E0271]: type mismatch resolving `::Receiver == Foo` - --> $DIR/arbitrary-self-from-method-substs.rs:92:9 + --> $DIR/arbitrary-self-from-method-substs.rs:136:9 | LL | foo.get6(Silly); | ^^^^ type mismatch resolving `::Receiver == Foo` | note: expected this to be `Foo` - --> $DIR/arbitrary-self-from-method-substs.rs:71:21 + --> $DIR/arbitrary-self-from-method-substs.rs:115:21 | LL | type Receiver = std::rc::Rc; | ^^^^^^^^^^^^^^^^ @@ -100,13 +100,13 @@ LL | type Receiver = std::rc::Rc; found struct `Rc` error[E0271]: type mismatch resolving `::Receiver == &Foo` - --> $DIR/arbitrary-self-from-method-substs.rs:96:9 + --> $DIR/arbitrary-self-from-method-substs.rs:140:9 | LL | foo.get6(Silly); | ^^^^ type mismatch resolving `::Receiver == &Foo` | note: expected this to be `&Foo` - --> $DIR/arbitrary-self-from-method-substs.rs:71:21 + --> $DIR/arbitrary-self-from-method-substs.rs:115:21 | LL | type Receiver = std::rc::Rc; | ^^^^^^^^^^^^^^^^ @@ -114,60 +114,86 @@ LL | type Receiver = std::rc::Rc; found struct `Rc` error[E0599]: the method `get` exists for struct `Rc>`, but its trait bounds were not satisfied - --> $DIR/arbitrary-self-from-method-substs.rs:100:7 + --> $DIR/arbitrary-self-from-method-substs.rs:144:7 | LL | struct Bar(std::marker::PhantomData); - | ------------- doesn't satisfy `Bar<_>: Deref` + | ------------- doesn't satisfy `Bar<_>: Deref` or `Bar<_>: std::ops::Receiver` ... LL | t.get(); | ^^^ method cannot be called on `Rc>` due to unsatisfied trait bounds | note: the following trait bounds were not satisfied: `<&Bar<_> as Deref>::Target = Bar<&Bar<_>>` + `<&Bar<_> as std::ops::Receiver>::Target = Bar<&Bar<_>>` `<&Rc> as Deref>::Target = Bar<&Rc>>` + `<&Rc> as std::ops::Receiver>::Target = Bar<&Rc>>` `<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>` + `<&mut Bar<_> as std::ops::Receiver>::Target = Bar<&mut Bar<_>>` `<&mut Rc> as Deref>::Target = Bar<&mut Rc>>` + `<&mut Rc> as std::ops::Receiver>::Target = Bar<&mut Rc>>` `> as Deref>::Target = Bar>>` + `> as std::ops::Receiver>::Target = Bar>>` `Bar<_>: Deref` - --> $DIR/arbitrary-self-from-method-substs.rs:60:9 + `Bar<_>: std::ops::Receiver` + --> $DIR/arbitrary-self-from-method-substs.rs:97:9 | -LL | impl> Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ - | | | - | | unsatisfied trait bound introduced here +LL | impl> Bar + | ^^^^^^^^^^^^^^^^^^^^ ------ + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -note: the trait `Deref` must be implemented +... +LL | R: Receiver, + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | unsatisfied trait bound introduced here + | unsatisfied trait bound introduced here +note: the traits `Deref` and `std::ops::Receiver` must be implemented --> $SRC_DIR/core/src/ops/deref.rs:LL:COL = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `get`, perhaps you need to implement it: candidate #1: `SliceIndex` error[E0599]: the method `get` exists for reference `&Rc>`, but its trait bounds were not satisfied - --> $DIR/arbitrary-self-from-method-substs.rs:108:7 + --> $DIR/arbitrary-self-from-method-substs.rs:152:7 | LL | struct Bar(std::marker::PhantomData); - | ------------- doesn't satisfy `Bar<_>: Deref` + | ------------- doesn't satisfy `Bar<_>: Deref` or `Bar<_>: std::ops::Receiver` ... LL | t.get(); | ^^^ method cannot be called on `&Rc>` due to unsatisfied trait bounds | note: the following trait bounds were not satisfied: `<&&Rc> as Deref>::Target = Bar<&&Rc>>` + `<&&Rc> as std::ops::Receiver>::Target = Bar<&&Rc>>` `<&Bar<_> as Deref>::Target = Bar<&Bar<_>>` + `<&Bar<_> as std::ops::Receiver>::Target = Bar<&Bar<_>>` `<&Rc> as Deref>::Target = Bar<&Rc>>` + `<&Rc> as std::ops::Receiver>::Target = Bar<&Rc>>` `<&mut &Rc> as Deref>::Target = Bar<&mut &Rc>>` + `<&mut &Rc> as std::ops::Receiver>::Target = Bar<&mut &Rc>>` `<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>` + `<&mut Bar<_> as std::ops::Receiver>::Target = Bar<&mut Bar<_>>` `<&mut Rc> as Deref>::Target = Bar<&mut Rc>>` + `<&mut Rc> as std::ops::Receiver>::Target = Bar<&mut Rc>>` `> as Deref>::Target = Bar>>` + `> as std::ops::Receiver>::Target = Bar>>` `Bar<_>: Deref` - --> $DIR/arbitrary-self-from-method-substs.rs:60:9 + `Bar<_>: std::ops::Receiver` + --> $DIR/arbitrary-self-from-method-substs.rs:97:9 | -LL | impl> Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ - | | | - | | unsatisfied trait bound introduced here +LL | impl> Bar + | ^^^^^^^^^^^^^^^^^^^^ ------ + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -note: the trait `Deref` must be implemented +... +LL | R: Receiver, + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | unsatisfied trait bound introduced here + | unsatisfied trait bound introduced here +note: the traits `Deref` and `std::ops::Receiver` must be implemented --> $SRC_DIR/core/src/ops/deref.rs:LL:COL = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `get`, perhaps you need to implement it: diff --git a/tests/ui/self/arbitrary-self-from-method-substs.rs b/tests/ui/self/arbitrary-self-from-method-substs.rs index f2d6585961517..ff2f03dd8ff0c 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.rs +++ b/tests/ui/self/arbitrary-self-from-method-substs.rs @@ -1,42 +1,71 @@ //@ revisions: default feature +#![feature(where_clause_attrs)] #![cfg_attr(feature, feature(arbitrary_self_types))] -use std::ops::Deref; use std::marker::PhantomData; +use std::ops::Deref; +#[cfg(feature)] +use std::ops::Receiver; struct Foo(u32); impl Foo { - fn get>(self: R) -> u32 { - //~^ ERROR: invalid generic `self` parameter type + fn get>(self: R) -> u32 + //~^ ERROR: invalid generic `self` parameter type + where + #[cfg(feature)] + R: Receiver, + { self.0 } - fn get1>(self: &R) -> u32 { - //~^ ERROR: invalid generic `self` parameter type + fn get1>(self: &R) -> u32 + //~^ ERROR: invalid generic `self` parameter type + where + #[cfg(feature)] + R: Receiver, + { self.0 } - fn get2>(self: &mut R) -> u32 { - //~^ ERROR: invalid generic `self` parameter type + fn get2>(self: &mut R) -> u32 + //~^ ERROR: invalid generic `self` parameter type + where + #[cfg(feature)] + R: Receiver, + { self.0 } - fn get3>(self: std::rc::Rc) -> u32 { - //~^ ERROR: invalid generic `self` parameter type + fn get3>(self: std::rc::Rc) -> u32 + //~^ ERROR: invalid generic `self` parameter type + where + #[cfg(feature)] + R: Receiver, + { self.0 } - fn get4>(self: &std::rc::Rc) -> u32 { - //~^ ERROR: invalid generic `self` parameter type + fn get4>(self: &std::rc::Rc) -> u32 + //~^ ERROR: invalid generic `self` parameter type + where + #[cfg(feature)] + R: Receiver, + { self.0 } - fn get5>(self: std::rc::Rc<&R>) -> u32 { - //~^ ERROR: invalid generic `self` parameter type + fn get5>(self: std::rc::Rc<&R>) -> u32 + //~^ ERROR: invalid generic `self` parameter type + where + #[cfg(feature)] + R: Receiver, + { self.0 } +} + +impl Foo { fn get6(self: FR::Receiver, other: FR) -> u32 { - //[default]~^ ERROR: `::Receiver` cannot be used as the type of `self` + //[default]~^ ERROR: invalid `self` parameter type: `::Receiver` 42 } } - struct SmartPtr<'a, T: ?Sized>(&'a T); impl<'a, T: ?Sized> Deref for SmartPtr<'a, T> { @@ -45,6 +74,10 @@ impl<'a, T: ?Sized> Deref for SmartPtr<'a, T> { unimplemented!() } } +#[cfg(feature)] +impl<'a, T: ?Sized> Receiver for SmartPtr<'a, T> { + type Target = T; +} struct SmartPtr2<'a, T: ?Sized>(&'a T); @@ -54,16 +87,27 @@ impl<'a, T: ?Sized> Deref for SmartPtr2<'a, T> { unimplemented!() } } +#[cfg(feature)] +impl<'a, T: ?Sized> Receiver for SmartPtr2<'a, T> { + type Target = T; +} struct Bar(std::marker::PhantomData); -impl> Bar { +impl> Bar +where + #[cfg(feature)] + R: Receiver, +{ fn get(self: R) {} - //[default]~^ ERROR: `R` cannot be used as the type of `self` + //[default]~^ ERROR: invalid `self` parameter type: `R` } trait FindReceiver { + #[cfg(not(feature))] type Receiver: Deref; + #[cfg(feature)] + type Receiver: Deref + Receiver; } struct Silly; diff --git a/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr index 7a3d8b43c2e3a..75188787ece67 100644 --- a/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr +++ b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr @@ -22,7 +22,6 @@ error[E0277]: the trait bound `Foo: std::ops::Receiver` is not satisfied LL | foo.a(); | ^ the trait `std::ops::Receiver` is not implemented for `Foo` | - = note: required for `Foo` to implement `std::ops::Receiver` note: required by a bound in `Foo::a` --> $DIR/arbitrary_self_types_generic_over_receiver.rs:7:21 | diff --git a/tests/ui/self/arbitrary_self_types_pointers_and_wrappers.rs b/tests/ui/self/arbitrary_self_types_pointers_and_wrappers.rs index 4dc170c3a65a1..95377ff73d8a3 100644 --- a/tests/ui/self/arbitrary_self_types_pointers_and_wrappers.rs +++ b/tests/ui/self/arbitrary_self_types_pointers_and_wrappers.rs @@ -2,11 +2,9 @@ #![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)] #![feature(rustc_attrs)] -use std::{ - cell::Cell, - ops::{Deref, CoerceUnsized, DispatchFromDyn}, - marker::Unsize, -}; +use std::cell::Cell; +use std::marker::Unsize; +use std::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver}; struct Ptr(Box); @@ -17,11 +15,13 @@ impl Deref for Ptr { &*self.0 } } +impl Receiver for Ptr { + type Target = T; +} impl + ?Sized, U: ?Sized> CoerceUnsized> for Ptr {} impl + ?Sized, U: ?Sized> DispatchFromDyn> for Ptr {} - struct CellPtr<'a, T: ?Sized>(Cell<&'a T>); impl<'a, T: ?Sized> Deref for CellPtr<'a, T> { @@ -31,6 +31,9 @@ impl<'a, T: ?Sized> Deref for CellPtr<'a, T> { self.0.get() } } +impl<'a, T: ?Sized> Receiver for CellPtr<'a, T> { + type Target = T; +} impl<'a, T: Unsize + ?Sized, U: ?Sized> CoerceUnsized> for CellPtr<'a, T> {} impl<'a, T: Unsize + ?Sized, U: ?Sized> DispatchFromDyn> for CellPtr<'a, T> {} @@ -44,11 +47,12 @@ impl Deref for Wrapper { &self.0 } } - +impl Receiver for Wrapper { + type Target = T; +} impl, U> CoerceUnsized> for Wrapper {} impl, U> DispatchFromDyn> for Wrapper {} - trait Trait { fn ptr_wrapper(self: Ptr>) -> i32; fn wrapper_ptr(self: Wrapper>) -> i32; diff --git a/tests/ui/self/arbitrary_self_types_silly.rs b/tests/ui/self/arbitrary_self_types_silly.rs index 94726bd69cc57..d77698bd77488 100644 --- a/tests/ui/self/arbitrary_self_types_silly.rs +++ b/tests/ui/self/arbitrary_self_types_silly.rs @@ -12,8 +12,14 @@ impl std::ops::Deref for Bar { } } +impl std::ops::Receiver for Bar { + type Target = Foo; +} + impl Foo { - fn bar(self: Bar) -> i32 { 3 } + fn bar(self: Bar) -> i32 { + 3 + } } fn main() { diff --git a/tests/ui/self/dispatch-from-dyn-layout-3.rs b/tests/ui/self/dispatch-from-dyn-layout-3.rs index 6878a4f4ac271..340806574b2fe 100644 --- a/tests/ui/self/dispatch-from-dyn-layout-3.rs +++ b/tests/ui/self/dispatch-from-dyn-layout-3.rs @@ -6,10 +6,9 @@ #![feature(dispatch_from_dyn)] #![feature(arbitrary_self_types)] -use std::ops::Deref; -use std::ops::DispatchFromDyn; +use std::ops::{Deref, DispatchFromDyn, Receiver}; -trait Trait> +trait Trait + Receiver> where for<'a> &'a T: DispatchFromDyn<&'a T>, { diff --git a/tests/ui/self/dispatch-from-dyn-layout.rs b/tests/ui/self/dispatch-from-dyn-layout.rs index 468dc89a73e61..1b6d0c86ed97e 100644 --- a/tests/ui/self/dispatch-from-dyn-layout.rs +++ b/tests/ui/self/dispatch-from-dyn-layout.rs @@ -6,9 +6,9 @@ #![feature(arbitrary_self_types, dispatch_from_dyn)] -use std::ops::{Deref, DispatchFromDyn}; +use std::ops::{Deref, DispatchFromDyn, Receiver}; -trait Trait + DispatchFromDyn> { +trait Trait + Receiver + DispatchFromDyn> { fn foo(self: T) -> dyn Trait; } diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.rs b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs index 967958ab48695..637ec5362fe90 100644 --- a/tests/ui/self/dispatch-from-dyn-zst-transmute.rs +++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs @@ -2,10 +2,8 @@ #![feature(unsize)] #![feature(dispatch_from_dyn)] -use std::marker::PhantomData; -use std::marker::Unsize; -use std::ops::DispatchFromDyn; -use std::ops::Deref; +use std::marker::{PhantomData, Unsize}; +use std::ops::{Deref, DispatchFromDyn, Receiver}; struct IsSendToken(PhantomData T>); @@ -18,7 +16,9 @@ impl<'a, T, U> DispatchFromDyn> for Foo<'a, T> //~^ ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced where T: Unsize + ?Sized, - U: ?Sized {} + U: ?Sized, +{ +} trait Bar { fn f(self: Foo<'_, Self>); @@ -30,5 +30,8 @@ impl Deref for Foo<'_, U> { self.ptr } } +impl Receiver for Foo<'_, U> { + type Target = U; +} fn main() {} diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr index cc8be45e99d8a..9b35c11d1f03c 100644 --- a/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr +++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr @@ -1,15 +1,15 @@ error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced - --> $DIR/dispatch-from-dyn-zst-transmute.rs:17:1 + --> $DIR/dispatch-from-dyn-zst-transmute.rs:15:1 | LL | / impl<'a, T, U> DispatchFromDyn> for Foo<'a, T> LL | | LL | | where LL | | T: Unsize + ?Sized, -LL | | U: ?Sized {} - | |_____________^ +LL | | U: ?Sized, + | |______________^ | note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced - --> $DIR/dispatch-from-dyn-zst-transmute.rs:13:5 + --> $DIR/dispatch-from-dyn-zst-transmute.rs:11:5 | LL | token: IsSendToken, | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs b/tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs index 55c070eb03682..84b6577c4845e 100644 --- a/tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs +++ b/tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs @@ -3,8 +3,8 @@ #![feature(derive_coerce_pointee)] #![feature(arbitrary_self_types)] -use std::ops::Deref; use std::marker::CoercePointee; +use std::ops::{Deref, Receiver}; use std::sync::Arc; trait MyTrait {} @@ -19,6 +19,9 @@ impl> Deref for MyArc { &self.0 } } +impl> Receiver for MyArc { + type Target = T; +} trait Mirror { type Assoc; diff --git a/tests/ui/self/dyn-dispatch-requires-supertrait.rs b/tests/ui/self/dyn-dispatch-requires-supertrait.rs index f2661c406fef0..f1beb838839d1 100644 --- a/tests/ui/self/dyn-dispatch-requires-supertrait.rs +++ b/tests/ui/self/dyn-dispatch-requires-supertrait.rs @@ -3,8 +3,8 @@ #![feature(derive_coerce_pointee)] #![feature(arbitrary_self_types)] -use std::ops::Deref; use std::marker::CoercePointee; +use std::ops::{Deref, Receiver}; use std::sync::Arc; trait MyTrait {} @@ -15,7 +15,7 @@ struct MyArc where T: MyTrait + ?Sized, { - inner: Arc + inner: Arc, } impl Deref for MyArc { @@ -24,6 +24,9 @@ impl Deref for MyArc { &self.inner } } +impl Receiver for MyArc { + type Target = T; +} // Proving that `MyArc` is dyn-dispatchable requires proving `MyArc` implements // `DispatchFromDyn>`. The `DispatchFromDyn` impl that is generated from the diff --git a/tests/ui/self/elision/multiple-ref-self-async.rs b/tests/ui/self/elision/multiple-ref-self-async.rs index f63b455901ee0..cb3940c326f81 100644 --- a/tests/ui/self/elision/multiple-ref-self-async.rs +++ b/tests/ui/self/elision/multiple-ref-self-async.rs @@ -4,18 +4,22 @@ #![allow(non_snake_case)] use std::marker::PhantomData; -use std::ops::Deref; +use std::ops::{Deref, Receiver}; use std::pin::Pin; -struct Struct { } +struct Struct {} struct Wrap(T, PhantomData

); impl Deref for Wrap { type Target = T; - fn deref(&self) -> &T { &self.0 } + fn deref(&self) -> &T { + &self.0 + } +} +impl Receiver for Wrap { + type Target = T; } - impl Struct { // Test using multiple `&Self`: @@ -45,4 +49,4 @@ impl Struct { } } -fn main() { } +fn main() {} diff --git a/tests/ui/self/elision/multiple-ref-self-async.stderr b/tests/ui/self/elision/multiple-ref-self-async.stderr index e2abc7c1e7852..56cf60ab6e791 100644 --- a/tests/ui/self/elision/multiple-ref-self-async.stderr +++ b/tests/ui/self/elision/multiple-ref-self-async.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/multiple-ref-self-async.rs:22:74 + --> $DIR/multiple-ref-self-async.rs:26:74 | LL | async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 { | ------------------ --- ^ expected named lifetime parameter @@ -11,7 +11,7 @@ LL | async fn wrap_ref_Self_ref_Self<'a>(self: Wrap<&'a Self, &'a Self>, f: | ++++ ++ ++ ++ ++ error[E0106]: missing lifetime specifier - --> $DIR/multiple-ref-self-async.rs:27:84 + --> $DIR/multiple-ref-self-async.rs:31:84 | LL | async fn box_wrap_ref_Self_ref_Self(self: Box>, f: &u32) -> &u32 { | ----------------------- ---- ^ expected named lifetime parameter @@ -23,7 +23,7 @@ LL | async fn box_wrap_ref_Self_ref_Self<'a>(self: Box $DIR/multiple-ref-self-async.rs:32:84 + --> $DIR/multiple-ref-self-async.rs:36:84 | LL | async fn pin_wrap_ref_Self_ref_Self(self: Pin>, f: &u32) -> &u32 { | ----------------------- ---- ^ expected named lifetime parameter @@ -35,7 +35,7 @@ LL | async fn pin_wrap_ref_Self_ref_Self<'a>(self: Pin $DIR/multiple-ref-self-async.rs:37:93 + --> $DIR/multiple-ref-self-async.rs:41:93 | LL | async fn box_box_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { | ---------------------------- ---- ^ expected named lifetime parameter @@ -47,7 +47,7 @@ LL | async fn box_box_wrap_ref_Self_ref_Self<'a>(self: Box $DIR/multiple-ref-self-async.rs:42:93 + --> $DIR/multiple-ref-self-async.rs:46:93 | LL | async fn box_pin_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { | ---------------------------- ---- ^ expected named lifetime parameter diff --git a/tests/ui/self/elision/multiple-ref-self.rs b/tests/ui/self/elision/multiple-ref-self.rs index dd9b138051d0b..dc8487e36c7ba 100644 --- a/tests/ui/self/elision/multiple-ref-self.rs +++ b/tests/ui/self/elision/multiple-ref-self.rs @@ -2,16 +2,21 @@ #![allow(non_snake_case)] use std::marker::PhantomData; -use std::ops::Deref; +use std::ops::{Deref, Receiver}; use std::pin::Pin; -struct Struct { } +struct Struct {} struct Wrap(T, PhantomData

); impl Deref for Wrap { type Target = T; - fn deref(&self) -> &T { &self.0 } + fn deref(&self) -> &T { + &self.0 + } +} +impl Receiver for Wrap { + type Target = T; } impl Struct { @@ -43,4 +48,4 @@ impl Struct { } } -fn main() { } +fn main() {} diff --git a/tests/ui/self/elision/multiple-ref-self.stderr b/tests/ui/self/elision/multiple-ref-self.stderr index 24d74d352e482..9fcf1da9337c8 100644 --- a/tests/ui/self/elision/multiple-ref-self.stderr +++ b/tests/ui/self/elision/multiple-ref-self.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/multiple-ref-self.rs:20:68 + --> $DIR/multiple-ref-self.rs:25:68 | LL | fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 { | ------------------ --- ^ expected named lifetime parameter @@ -11,7 +11,7 @@ LL | fn wrap_ref_Self_ref_Self<'a>(self: Wrap<&'a Self, &'a Self>, f: &'a u8 | ++++ ++ ++ ++ ++ error[E0106]: missing lifetime specifier - --> $DIR/multiple-ref-self.rs:25:78 + --> $DIR/multiple-ref-self.rs:30:78 | LL | fn box_wrap_ref_Self_ref_Self(self: Box>, f: &u32) -> &u32 { | ----------------------- ---- ^ expected named lifetime parameter @@ -23,7 +23,7 @@ LL | fn box_wrap_ref_Self_ref_Self<'a>(self: Box>, | ++++ ++ ++ ++ ++ error[E0106]: missing lifetime specifier - --> $DIR/multiple-ref-self.rs:30:78 + --> $DIR/multiple-ref-self.rs:35:78 | LL | fn pin_wrap_ref_Self_ref_Self(self: Pin>, f: &u32) -> &u32 { | ----------------------- ---- ^ expected named lifetime parameter @@ -35,7 +35,7 @@ LL | fn pin_wrap_ref_Self_ref_Self<'a>(self: Pin>, | ++++ ++ ++ ++ ++ error[E0106]: missing lifetime specifier - --> $DIR/multiple-ref-self.rs:35:87 + --> $DIR/multiple-ref-self.rs:40:87 | LL | fn box_box_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { | ---------------------------- ---- ^ expected named lifetime parameter @@ -47,7 +47,7 @@ LL | fn box_box_wrap_ref_Self_ref_Self<'a>(self: Box $DIR/multiple-ref-self.rs:40:87 + --> $DIR/multiple-ref-self.rs:45:87 | LL | fn box_pin_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { | ---------------------------- ---- ^ expected named lifetime parameter diff --git a/tests/ui/self/elision/ref-self-async.rs b/tests/ui/self/elision/ref-self-async.rs index 1f3e670d3d1df..a0b5d75716ebd 100644 --- a/tests/ui/self/elision/ref-self-async.rs +++ b/tests/ui/self/elision/ref-self-async.rs @@ -4,16 +4,21 @@ #![feature(arbitrary_self_types)] use std::marker::PhantomData; -use std::ops::Deref; +use std::ops::{Deref, Receiver}; use std::pin::Pin; -struct Struct { } +struct Struct {} struct Wrap(T, PhantomData

); impl Deref for Wrap { type Target = T; - fn deref(&self) -> &T { &self.0 } + fn deref(&self) -> &T { + &self.0 + } +} +impl Receiver for Wrap { + type Target = T; } impl Struct { @@ -57,4 +62,4 @@ impl Struct { } } -fn main() { } +fn main() {} diff --git a/tests/ui/self/elision/ref-self-async.stderr b/tests/ui/self/elision/ref-self-async.stderr index a75ece5f2c768..6a782c2ee8c39 100644 --- a/tests/ui/self/elision/ref-self-async.stderr +++ b/tests/ui/self/elision/ref-self-async.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:23:9 + --> $DIR/ref-self-async.rs:28:9 | LL | async fn ref_self(&self, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -14,7 +14,7 @@ LL | async fn ref_self<'a>(&self, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:30:9 + --> $DIR/ref-self-async.rs:35:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -29,7 +29,7 @@ LL | async fn ref_Self<'a>(self: &Self, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:35:9 + --> $DIR/ref-self-async.rs:40:9 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -44,7 +44,7 @@ LL | async fn box_ref_Self<'a>(self: Box<&Self>, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:40:9 + --> $DIR/ref-self-async.rs:45:9 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -59,7 +59,7 @@ LL | async fn pin_ref_Self<'a>(self: Pin<&Self>, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:45:9 + --> $DIR/ref-self-async.rs:50:9 | LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -74,7 +74,7 @@ LL | async fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &'a | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:50:9 + --> $DIR/ref-self-async.rs:55:9 | LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -89,7 +89,7 @@ LL | async fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &'a | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:55:9 + --> $DIR/ref-self-async.rs:60:9 | LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | - - let's call the lifetime of this reference `'1` diff --git a/tests/ui/self/elision/ref-self-multi.rs b/tests/ui/self/elision/ref-self-multi.rs index ed431a9c852dd..b750541ca325a 100644 --- a/tests/ui/self/elision/ref-self-multi.rs +++ b/tests/ui/self/elision/ref-self-multi.rs @@ -3,15 +3,20 @@ #![allow(unused)] use std::marker::PhantomData; -use std::ops::Deref; +use std::ops::{Deref, Receiver}; -struct Struct { } +struct Struct {} struct Wrap(T, PhantomData

); impl Deref for Wrap { type Target = T; - fn deref(&self) -> &T { &self.0 } + fn deref(&self) -> &T { + &self.0 + } +} +impl Receiver for Wrap { + type Target = T; } impl Struct { @@ -26,4 +31,4 @@ impl Struct { } } -fn main() { } +fn main() {} diff --git a/tests/ui/self/elision/ref-self-multi.stderr b/tests/ui/self/elision/ref-self-multi.stderr index 7e0451aa0d5c3..976f539bea06a 100644 --- a/tests/ui/self/elision/ref-self-multi.stderr +++ b/tests/ui/self/elision/ref-self-multi.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/ref-self-multi.rs:18:56 + --> $DIR/ref-self-multi.rs:23:56 | LL | fn ref_box_ref_Self(self: &Box<&Self>, f: &u32) -> &u32 { | ----------- ---- ^ expected named lifetime parameter @@ -11,7 +11,7 @@ LL | fn ref_box_ref_Self<'a>(self: &'a Box<&'a Self>, f: &'a u32) -> &'a u32 | ++++ ++ ++ ++ ++ error[E0106]: missing lifetime specifier - --> $DIR/ref-self-multi.rs:23:63 + --> $DIR/ref-self-multi.rs:28:63 | LL | fn ref_wrap_ref_Self(self: &Wrap<&Self, u32>, f: &u32) -> &u32 { | ----------------- ---- ^ expected named lifetime parameter diff --git a/tests/ui/self/elision/ref-self.fixed b/tests/ui/self/elision/ref-self.fixed index 784ccb9efe2f6..64a23c9c5f56f 100644 --- a/tests/ui/self/elision/ref-self.fixed +++ b/tests/ui/self/elision/ref-self.fixed @@ -5,7 +5,7 @@ #![allow(non_snake_case, dead_code)] use std::marker::PhantomData; -use std::ops::Deref; +use std::ops::{Deref, Receiver}; use std::pin::Pin; struct Struct {} @@ -18,6 +18,9 @@ impl Deref for Wrap { &self.0 } } +impl Receiver for Wrap { + type Target = T; +} impl Struct { // Test using `&self` sugar: diff --git a/tests/ui/self/elision/ref-self.rs b/tests/ui/self/elision/ref-self.rs index dbe441879cc5d..df3bbca6d19f8 100644 --- a/tests/ui/self/elision/ref-self.rs +++ b/tests/ui/self/elision/ref-self.rs @@ -5,7 +5,7 @@ #![allow(non_snake_case, dead_code)] use std::marker::PhantomData; -use std::ops::Deref; +use std::ops::{Deref, Receiver}; use std::pin::Pin; struct Struct {} @@ -18,6 +18,9 @@ impl Deref for Wrap { &self.0 } } +impl Receiver for Wrap { + type Target = T; +} impl Struct { // Test using `&self` sugar: diff --git a/tests/ui/self/elision/ref-self.stderr b/tests/ui/self/elision/ref-self.stderr index 64e7bfc1bb06c..525ff061f32dc 100644 --- a/tests/ui/self/elision/ref-self.stderr +++ b/tests/ui/self/elision/ref-self.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/ref-self.rs:26:9 + --> $DIR/ref-self.rs:29:9 | LL | fn ref_self(&self, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -14,7 +14,7 @@ LL | fn ref_self<'a>(&self, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self.rs:33:9 + --> $DIR/ref-self.rs:36:9 | LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -29,7 +29,7 @@ LL | fn ref_Self<'a>(self: &Self, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self.rs:38:9 + --> $DIR/ref-self.rs:41:9 | LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -44,7 +44,7 @@ LL | fn box_ref_Self<'a>(self: Box<&Self>, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self.rs:43:9 + --> $DIR/ref-self.rs:46:9 | LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -59,7 +59,7 @@ LL | fn pin_ref_Self<'a>(self: Pin<&Self>, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self.rs:48:9 + --> $DIR/ref-self.rs:51:9 | LL | fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -74,7 +74,7 @@ LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self.rs:53:9 + --> $DIR/ref-self.rs:56:9 | LL | fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` @@ -89,7 +89,7 @@ LL | fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &'a u32 { | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self.rs:58:9 + --> $DIR/ref-self.rs:61:9 | LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | - - let's call the lifetime of this reference `'1` @@ -104,7 +104,7 @@ LL | fn wrap_ref_Self_Self<'a>(self: Wrap<&Self, Self>, f: &'a u8) -> &'a u8 | ++++ ++ ++ error: lifetime may not live long enough - --> $DIR/ref-self.rs:63:9 + --> $DIR/ref-self.rs:66:9 | LL | fn ref_box_Self(self: &Box, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` diff --git a/tests/ui/self/invalid-self-dyn-receiver.rs b/tests/ui/self/invalid-self-dyn-receiver.rs index a989b331b5e0b..f1867bda2167f 100644 --- a/tests/ui/self/invalid-self-dyn-receiver.rs +++ b/tests/ui/self/invalid-self-dyn-receiver.rs @@ -4,17 +4,18 @@ #![feature(arbitrary_self_types)] -use std::ops::Deref; +use std::ops::{Deref, Receiver}; -trait Foo: Deref { - fn method(self: &dyn Bar) {} - //~^ ERROR invalid `self` parameter type: `&dyn Bar` +trait Foo: Deref + Receiver { + fn method(self: &dyn Bar) {} + //~^ ERROR invalid `self` parameter type: `&dyn Bar` } trait Bar {} fn test(x: &dyn Foo) { - x.method(); + x.method(); + //~^ ERROR type annotations needed } fn main() {} diff --git a/tests/ui/self/invalid-self-dyn-receiver.stderr b/tests/ui/self/invalid-self-dyn-receiver.stderr index f77f5686ad282..0fed908037e04 100644 --- a/tests/ui/self/invalid-self-dyn-receiver.stderr +++ b/tests/ui/self/invalid-self-dyn-receiver.stderr @@ -1,12 +1,26 @@ error[E0307]: invalid `self` parameter type: `&dyn Bar` - --> $DIR/invalid-self-dyn-receiver.rs:10:22 + --> $DIR/invalid-self-dyn-receiver.rs:10:21 | -LL | fn method(self: &dyn Bar) {} - | ^^^^^^^^ +LL | fn method(self: &dyn Bar) {} + | ^^^^^^^^ | = note: type of `self` must be `Self` or some type implementing `Receiver` = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` -error: aborting due to 1 previous error +error[E0283]: type annotations needed + --> $DIR/invalid-self-dyn-receiver.rs:17:7 + | +LL | x.method(); + | ^^^^^^ + | + = note: cannot satisfy `_: Foo` +help: try using a fully qualified path to specify the expected types + | +LL - x.method(); +LL + <_ as Foo>::method(x); + | + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0307`. +Some errors have detailed explanations: E0283, E0307. +For more information about an error, try `rustc --explain E0283`. From 0bd9ecdf269a093d20d0af9bccf946411e76d5ee Mon Sep 17 00:00:00 2001 From: Xiangfei Ding Date: Sun, 5 Oct 2025 18:55:51 +0000 Subject: [PATCH 2/2] possible rewording of diagnostics --- compiler/rustc_hir_analysis/messages.ftl | 3 ++- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 +- tests/ui/abi/invalid-self-parameter-type-56806.stderr | 3 ++- tests/ui/async-await/inference_var_self_argument.stderr | 3 ++- tests/ui/async-await/issue-66312.stderr | 3 ++- .../feature-gate-arbitrary-self-types.stderr | 9 ++++++--- .../feature-gate-dispatch-from-dyn-cell.stderr | 3 ++- .../arbitrary-self-from-method-substs.default.stderr | 6 ++++-- tests/ui/self/arbitrary-self-opaque.stderr | 3 ++- .../dispatch-dyn-incompatible-that-does-not-deref.stderr | 3 ++- tests/ui/span/issue-27522.stderr | 3 ++- .../dyn-incompatible-trait-should-use-where-sized.stderr | 3 ++- tests/ui/traits/issue-78372.stderr | 3 ++- tests/ui/ufcs/ufcs-explicit-self-bad.stderr | 9 ++++++--- 14 files changed, 37 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 06f2ec512ab1f..c32f1c6c7b240 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -264,7 +264,8 @@ hir_analysis_invalid_receiver_ty_help = consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types = - consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable hir_analysis_invalid_receiver_ty_help_nonnull_note = `NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver` diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5d5ec503ef124..0dfb0fb619833 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1815,7 +1815,7 @@ fn receiver_is_valid<'tcx>( let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty); // The `arbitrary_self_types` feature allows custom smart pointer - // types to be method receivers, as identified by following the Receiver + // types to be method receivers, as identified by following the Receiver // chain. if arbitrary_self_types_enabled.is_some() { // We are in the wf check, so we would like to deref the references in the type head. diff --git a/tests/ui/abi/invalid-self-parameter-type-56806.stderr b/tests/ui/abi/invalid-self-parameter-type-56806.stderr index ac249b8f10880..5d4d147614b8e 100644 --- a/tests/ui/abi/invalid-self-parameter-type-56806.stderr +++ b/tests/ui/abi/invalid-self-parameter-type-56806.stderr @@ -5,7 +5,8 @@ LL | fn dyn_instead_of_self(self: Box); | ^^^^^^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error: aborting due to 1 previous error diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr index 1fccc32470ff6..600c567189f9f 100644 --- a/tests/ui/async-await/inference_var_self_argument.stderr +++ b/tests/ui/async-await/inference_var_self_argument.stderr @@ -5,7 +5,8 @@ LL | async fn foo(self: &dyn Foo) { | ^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0038]: the trait `Foo` is not dyn compatible --> $DIR/inference_var_self_argument.rs:5:5 diff --git a/tests/ui/async-await/issue-66312.stderr b/tests/ui/async-await/issue-66312.stderr index c95ae1147df36..3f889516fea8a 100644 --- a/tests/ui/async-await/issue-66312.stderr +++ b/tests/ui/async-await/issue-66312.stderr @@ -5,7 +5,8 @@ LL | fn is_some(self: T); | ^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0308]: mismatched types --> $DIR/issue-66312.rs:9:8 diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr index 5269ee18a3071..bdbc0d0ff12d6 100644 --- a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr +++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr @@ -5,7 +5,8 @@ LL | fn foo(self: Ptr) {} | ^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0307]: invalid `self` parameter type: `Box>` --> $DIR/feature-gate-arbitrary-self-types.rs:24:18 @@ -14,7 +15,8 @@ LL | fn bar(self: Box>) {} | ^^^^^^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0307]: invalid `self` parameter type: `Ptr` --> $DIR/feature-gate-arbitrary-self-types.rs:14:18 @@ -23,7 +25,8 @@ LL | fn foo(self: Ptr); | ^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error: aborting due to 3 previous errors diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr index 2150effc3b74d..029ac8fc9cec7 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr @@ -5,7 +5,8 @@ LL | fn cell(self: Cell<&Self>); | ^^^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error: aborting due to 1 previous error diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr index d6b9778de0326..70dbaf13a6fad 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr @@ -59,7 +59,8 @@ LL | fn get6(self: FR::Receiver, other: FR) -> u32 { | ^^^^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0307]: invalid `self` parameter type: `R` --> $DIR/arbitrary-self-from-method-substs.rs:102:18 @@ -68,7 +69,8 @@ LL | fn get(self: R) {} | ^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0271]: type mismatch resolving `::Receiver == Foo` --> $DIR/arbitrary-self-from-method-substs.rs:136:9 diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr index 36ae3d6fd02bb..ef96f08e26b42 100644 --- a/tests/ui/self/arbitrary-self-opaque.stderr +++ b/tests/ui/self/arbitrary-self-opaque.stderr @@ -5,7 +5,8 @@ LL | fn foo(self: Bar) {} | ^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error: item does not constrain `Bar::{opaque#0}` --> $DIR/arbitrary-self-opaque.rs:8:8 diff --git a/tests/ui/self/dispatch-dyn-incompatible-that-does-not-deref.stderr b/tests/ui/self/dispatch-dyn-incompatible-that-does-not-deref.stderr index 237bbc5671515..eb66875b3a95d 100644 --- a/tests/ui/self/dispatch-dyn-incompatible-that-does-not-deref.stderr +++ b/tests/ui/self/dispatch-dyn-incompatible-that-does-not-deref.stderr @@ -23,7 +23,8 @@ LL | fn method(self: &W) {} | ^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0038]: the trait `Foo` is not dyn compatible --> $DIR/dispatch-dyn-incompatible-that-does-not-deref.rs:14:5 diff --git a/tests/ui/span/issue-27522.stderr b/tests/ui/span/issue-27522.stderr index c57a100bbe227..4c524cfcb0a7b 100644 --- a/tests/ui/span/issue-27522.stderr +++ b/tests/ui/span/issue-27522.stderr @@ -5,7 +5,8 @@ LL | fn handler(self: &SomeType); | ^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr index c275cdccaa8c1..b113a771c704a 100644 --- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr +++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr @@ -35,7 +35,8 @@ LL | fn bar(self: ()) {} | ^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error: aborting due to 2 previous errors diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index a1c772f58e1f1..4fe3d6f01ad00 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -69,7 +69,8 @@ LL | fn foo(self: Smaht); | ^^^^^^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error: aborting due to 7 previous errors diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr index 7b5f7cd9f7033..f024fc52f3d43 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -24,7 +24,8 @@ LL | fn foo(self: isize, x: isize) -> isize { | ^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0307]: invalid `self` parameter type: `Bar` --> $DIR/ufcs-explicit-self-bad.rs:19:18 @@ -33,7 +34,8 @@ LL | fn foo(self: Bar, x: isize) -> isize { | ^^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0307]: invalid `self` parameter type: `&Bar` --> $DIR/ufcs-explicit-self-bad.rs:23:18 @@ -42,7 +44,8 @@ LL | fn bar(self: &Bar, x: isize) -> isize { | ^^^^^^^^^^^ | = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`); + alternatively, consider implement `Receiver` trait on the type of `self`, where applicable error[E0308]: mismatched `self` parameter type --> $DIR/ufcs-explicit-self-bad.rs:37:21