@@ -904,7 +904,6 @@ fn check_impl_item<'tcx>(
904904 hir:: ImplItemKind :: Type ( ty) if ty. span != DUMMY_SP => ( None , ty. span ) ,
905905 _ => ( None , impl_item. span ) ,
906906 } ;
907-
908907 check_associated_item ( tcx, impl_item. owner_id . def_id , span, method_sig)
909908}
910909
@@ -1725,8 +1724,11 @@ fn check_method_receiver<'tcx>(
17251724 } else {
17261725 None
17271726 } ;
1727+ let generics = tcx. generics_of ( method. def_id ) ;
17281728
1729- if !receiver_is_valid ( wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level) {
1729+ let receiver_validity =
1730+ receiver_is_valid ( wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level, generics) ;
1731+ if let Err ( receiver_validity_err) = receiver_validity {
17301732 return Err ( match arbitrary_self_types_level {
17311733 // Wherever possible, emit a message advising folks that the features
17321734 // `arbitrary_self_types` or `arbitrary_self_types_pointers` might
@@ -1737,7 +1739,9 @@ fn check_method_receiver<'tcx>(
17371739 receiver_ty,
17381740 self_ty,
17391741 Some ( ArbitrarySelfTypesLevel :: Basic ) ,
1740- ) =>
1742+ generics,
1743+ )
1744+ . is_ok ( ) =>
17411745 {
17421746 // Report error; would have worked with `arbitrary_self_types`.
17431747 feature_err (
@@ -1759,7 +1763,9 @@ fn check_method_receiver<'tcx>(
17591763 receiver_ty,
17601764 self_ty,
17611765 Some ( ArbitrarySelfTypesLevel :: WithPointers ) ,
1762- ) =>
1766+ generics,
1767+ )
1768+ . is_ok ( ) =>
17631769 {
17641770 // Report error; would have worked with `arbitrary_self_types_pointers`.
17651771 feature_err (
@@ -1777,13 +1783,45 @@ fn check_method_receiver<'tcx>(
17771783 _ =>
17781784 // Report error; would not have worked with `arbitrary_self_types[_pointers]`.
17791785 {
1780- tcx. dcx ( ) . emit_err ( errors:: InvalidReceiverTy { span, receiver_ty } )
1786+ match receiver_validity_err {
1787+ ReceiverValidityError :: DoesNotDeref => {
1788+ tcx. dcx ( ) . emit_err ( errors:: InvalidReceiverTy { span, receiver_ty } )
1789+ }
1790+ ReceiverValidityError :: MethodGenericParamUsed => {
1791+ tcx. dcx ( ) . emit_err ( errors:: InvalidGenericReceiverTy { span, receiver_ty } )
1792+ }
1793+ }
17811794 }
17821795 } ) ;
17831796 }
17841797 Ok ( ( ) )
17851798}
17861799
1800+ /// Error cases which may be returned from `receiver_is_valid`. These error
1801+ /// cases are generated in this function as they may be unearthed as we explore
1802+ /// the `autoderef` chain, but they're converted to diagnostics in the caller.
1803+ enum ReceiverValidityError {
1804+ /// The self type does not get to the receiver type by following the
1805+ /// autoderef chain.
1806+ DoesNotDeref ,
1807+ /// A type was found which is a method type parameter, and that's not allowed.
1808+ MethodGenericParamUsed ,
1809+ }
1810+
1811+ /// Confirms that a type is not a type parameter referring to one of the
1812+ /// method's type params.
1813+ fn confirm_type_is_not_a_method_generic_param (
1814+ ty : Ty < ' _ > ,
1815+ method_generics : & ty:: Generics ,
1816+ ) -> Result < ( ) , ReceiverValidityError > {
1817+ if let ty:: Param ( param) = ty. kind ( ) {
1818+ if ( param. index as usize ) >= method_generics. parent_count {
1819+ return Err ( ReceiverValidityError :: MethodGenericParamUsed ) ;
1820+ }
1821+ }
1822+ Ok ( ( ) )
1823+ }
1824+
17871825/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
17881826/// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
17891827/// through a `*const/mut T` raw pointer if `arbitrary_self_types_pointers` is also enabled.
@@ -1799,7 +1837,8 @@ fn receiver_is_valid<'tcx>(
17991837 receiver_ty : Ty < ' tcx > ,
18001838 self_ty : Ty < ' tcx > ,
18011839 arbitrary_self_types_enabled : Option < ArbitrarySelfTypesLevel > ,
1802- ) -> bool {
1840+ method_generics : & ty:: Generics ,
1841+ ) -> Result < ( ) , ReceiverValidityError > {
18031842 let infcx = wfcx. infcx ;
18041843 let tcx = wfcx. tcx ( ) ;
18051844 let cause =
@@ -1811,9 +1850,11 @@ fn receiver_is_valid<'tcx>(
18111850 ocx. eq ( & cause, wfcx. param_env , self_ty, receiver_ty) ?;
18121851 if ocx. select_all_or_error ( ) . is_empty ( ) { Ok ( ( ) ) } else { Err ( NoSolution ) }
18131852 } ) {
1814- return true ;
1853+ return Ok ( ( ) ) ;
18151854 }
18161855
1856+ confirm_type_is_not_a_method_generic_param ( receiver_ty, method_generics) ?;
1857+
18171858 let mut autoderef = Autoderef :: new ( infcx, wfcx. param_env , wfcx. body_def_id , span, receiver_ty) ;
18181859
18191860 // The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`.
@@ -1830,6 +1871,8 @@ fn receiver_is_valid<'tcx>(
18301871 potential_self_ty, self_ty
18311872 ) ;
18321873
1874+ confirm_type_is_not_a_method_generic_param ( potential_self_ty, method_generics) ?;
1875+
18331876 // Check if the self type unifies. If it does, then commit the result
18341877 // since it may have region side-effects.
18351878 if let Ok ( ( ) ) = wfcx. infcx . commit_if_ok ( |_| {
@@ -1838,7 +1881,7 @@ fn receiver_is_valid<'tcx>(
18381881 if ocx. select_all_or_error ( ) . is_empty ( ) { Ok ( ( ) ) } else { Err ( NoSolution ) }
18391882 } ) {
18401883 wfcx. register_obligations ( autoderef. into_obligations ( ) ) ;
1841- return true ;
1884+ return Ok ( ( ) ) ;
18421885 }
18431886
18441887 // Without `feature(arbitrary_self_types)`, we require that each step in the
@@ -1865,7 +1908,7 @@ fn receiver_is_valid<'tcx>(
18651908 }
18661909
18671910 debug ! ( "receiver_is_valid: type `{:?}` does not deref to `{:?}`" , receiver_ty, self_ty) ;
1868- false
1911+ Err ( ReceiverValidityError :: DoesNotDeref )
18691912}
18701913
18711914fn receiver_is_implemented < ' tcx > (
0 commit comments