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 e27e68d36624e..528065400132d 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -73,16 +73,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() { @@ -138,8 +141,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() { @@ -161,13 +164,13 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { ty::Binder::dummy(trait_ref), ); if !self.infcx.next_trait_solver() && !self.infcx.predicate_may_hold(&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)) @@ -244,11 +247,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 e6a1f6d8d8bb7..797aec1ae6b93 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1734,7 +1734,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) @@ -1748,7 +1750,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, @@ -1770,7 +1772,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, } @@ -1828,7 +1830,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`. @@ -1882,7 +1886,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 a23910a2006c9..787104baf15a3 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; @@ -352,18 +353,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 ab584eb7c909e..0b36118e46ca1 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -373,6 +373,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } + #[instrument(level = "debug", skip(self, op))] pub(crate) fn probe_op( &'a self, span: Span, @@ -413,6 +414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, ), autoderefs: 0, + receiver_depth: 0, from_unsafe_deref: false, unsize: false, reachable_via_deref: true, @@ -553,12 +555,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } +#[instrument(level = "debug", skip(tcx))] pub(crate) fn method_autoderef_steps<'tcx>( tcx: TyCtxt<'tcx>, goal: CanonicalTyGoal<'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, value: self_ty } = goal; @@ -580,42 +581,44 @@ 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), - 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), - autoderefs: d, + autoderefs, + receiver_depth: 0, from_unsafe_deref: reached_raw_pointer, unsize: false, reachable_via_deref: true, @@ -643,6 +646,7 @@ pub(crate) fn method_autoderef_steps<'tcx>( Ty::new_slice(infcx.tcx, *elem_ty), ), 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, @@ -742,7 +746,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); } } @@ -1187,6 +1191,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>, @@ -1220,21 +1225,22 @@ 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, - 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, + mutbl, + track_unstable_candidates, + ) { + return Some(Err(e)); } } } + return Some(by_value_pick); } @@ -1247,20 +1253,21 @@ 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, - 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, + hir::Mutability::Mut, + track_unstable_candidates, + ) { + return Some(Err(e)); } } + return Some(autoref_pick); } @@ -1300,20 +1307,24 @@ 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`: /// ```ignore (illustrative) - /// fn foo(self) // note this is by value + /// impl A { + /// fn foo(self) // 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. fn check_for_shadowed_autorefd_method( &self, possible_shadower: &Pick<'tcx>, @@ -1336,7 +1347,7 @@ 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 }, + unstable_candidates: track_unstable_candidates.then(Vec::new), unsatisfied_predicates: &mut Vec::new(), }; // Set criteria for how we find methods possibly shadowed by 'possible_shadower' @@ -1389,7 +1400,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)) @@ -1562,8 +1573,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, &self.private_candidates, &mut PickDiagHints { @@ -1571,9 +1582,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 } @@ -1602,7 +1613,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 8ce70f75c6743..4bec9ff8f20e2 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 3f6faa1a572d9..3bb5035326d53 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -161,6 +161,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 9674c0356c21f..ed48571d78119 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2504,6 +2504,8 @@ pub fn provide(providers: &mut Providers) { mod ref_mut { use std::ops::Deref; + #[cfg(not(bootstrap))] + use std::ops::Receiver; /// A wrapper around a mutable reference that conditionally allows mutable access. pub(crate) struct RefOrMut<'a, T> { @@ -2518,6 +2520,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 98c9f6b51ab86..bd4b1c6d32d68 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}; @@ -1976,6 +1976,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 711092ae8eb25..9f25e97e06dd0 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -94,6 +94,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 529b583cdd2bc..2a6c03e55551e 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; @@ -2276,6 +2278,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 a21b6880674c6..45021d8e42e66 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -20,7 +20,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}; @@ -2253,6 +2255,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/ops/deref.rs b/library/core/src/ops/deref.rs index 5f68c1f55c254..0b17127dc3a20 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -376,14 +376,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

`. @@ -401,6 +393,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 14bf7ba90150e..369f8475f37c9 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}, @@ -1688,6 +1690,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 0d4642c6ad0ef..c9a3a1faf1213 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`.

AltStyle によって変換されたページ (->オリジナル) /