@@ -904,7 +904,6 @@ fn check_impl_item<'tcx>(
904
904
hir:: ImplItemKind :: Type ( ty) if ty. span != DUMMY_SP => ( None , ty. span ) ,
905
905
_ => ( None , impl_item. span ) ,
906
906
} ;
907
-
908
907
check_associated_item ( tcx, impl_item. owner_id . def_id , span, method_sig)
909
908
}
910
909
@@ -1725,8 +1724,11 @@ fn check_method_receiver<'tcx>(
1725
1724
} else {
1726
1725
None
1727
1726
} ;
1727
+ let generics = tcx. generics_of ( method. def_id ) ;
1728
1728
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 {
1730
1732
return Err ( match arbitrary_self_types_level {
1731
1733
// Wherever possible, emit a message advising folks that the features
1732
1734
// `arbitrary_self_types` or `arbitrary_self_types_pointers` might
@@ -1737,7 +1739,9 @@ fn check_method_receiver<'tcx>(
1737
1739
receiver_ty,
1738
1740
self_ty,
1739
1741
Some ( ArbitrarySelfTypesLevel :: Basic ) ,
1740
- ) =>
1742
+ generics,
1743
+ )
1744
+ . is_ok ( ) =>
1741
1745
{
1742
1746
// Report error; would have worked with `arbitrary_self_types`.
1743
1747
feature_err (
@@ -1759,7 +1763,9 @@ fn check_method_receiver<'tcx>(
1759
1763
receiver_ty,
1760
1764
self_ty,
1761
1765
Some ( ArbitrarySelfTypesLevel :: WithPointers ) ,
1762
- ) =>
1766
+ generics,
1767
+ )
1768
+ . is_ok ( ) =>
1763
1769
{
1764
1770
// Report error; would have worked with `arbitrary_self_types_pointers`.
1765
1771
feature_err (
@@ -1777,13 +1783,45 @@ fn check_method_receiver<'tcx>(
1777
1783
_ =>
1778
1784
// Report error; would not have worked with `arbitrary_self_types[_pointers]`.
1779
1785
{
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
+ }
1781
1794
}
1782
1795
} ) ;
1783
1796
}
1784
1797
Ok ( ( ) )
1785
1798
}
1786
1799
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
+
1787
1825
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
1788
1826
/// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
1789
1827
/// through a `*const/mut T` raw pointer if `arbitrary_self_types_pointers` is also enabled.
@@ -1799,7 +1837,8 @@ fn receiver_is_valid<'tcx>(
1799
1837
receiver_ty : Ty < ' tcx > ,
1800
1838
self_ty : Ty < ' tcx > ,
1801
1839
arbitrary_self_types_enabled : Option < ArbitrarySelfTypesLevel > ,
1802
- ) -> bool {
1840
+ method_generics : & ty:: Generics ,
1841
+ ) -> Result < ( ) , ReceiverValidityError > {
1803
1842
let infcx = wfcx. infcx ;
1804
1843
let tcx = wfcx. tcx ( ) ;
1805
1844
let cause =
@@ -1811,9 +1850,11 @@ fn receiver_is_valid<'tcx>(
1811
1850
ocx. eq ( & cause, wfcx. param_env , self_ty, receiver_ty) ?;
1812
1851
if ocx. select_all_or_error ( ) . is_empty ( ) { Ok ( ( ) ) } else { Err ( NoSolution ) }
1813
1852
} ) {
1814
- return true ;
1853
+ return Ok ( ( ) ) ;
1815
1854
}
1816
1855
1856
+ confirm_type_is_not_a_method_generic_param ( receiver_ty, method_generics) ?;
1857
+
1817
1858
let mut autoderef = Autoderef :: new ( infcx, wfcx. param_env , wfcx. body_def_id , span, receiver_ty) ;
1818
1859
1819
1860
// The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`.
@@ -1830,6 +1871,8 @@ fn receiver_is_valid<'tcx>(
1830
1871
potential_self_ty, self_ty
1831
1872
) ;
1832
1873
1874
+ confirm_type_is_not_a_method_generic_param ( potential_self_ty, method_generics) ?;
1875
+
1833
1876
// Check if the self type unifies. If it does, then commit the result
1834
1877
// since it may have region side-effects.
1835
1878
if let Ok ( ( ) ) = wfcx. infcx . commit_if_ok ( |_| {
@@ -1838,7 +1881,7 @@ fn receiver_is_valid<'tcx>(
1838
1881
if ocx. select_all_or_error ( ) . is_empty ( ) { Ok ( ( ) ) } else { Err ( NoSolution ) }
1839
1882
} ) {
1840
1883
wfcx. register_obligations ( autoderef. into_obligations ( ) ) ;
1841
- return true ;
1884
+ return Ok ( ( ) ) ;
1842
1885
}
1843
1886
1844
1887
// Without `feature(arbitrary_self_types)`, we require that each step in the
@@ -1865,7 +1908,7 @@ fn receiver_is_valid<'tcx>(
1865
1908
}
1866
1909
1867
1910
debug ! ( "receiver_is_valid: type `{:?}` does not deref to `{:?}`" , receiver_ty, self_ty) ;
1868
- false
1911
+ Err ( ReceiverValidityError :: DoesNotDeref )
1869
1912
}
1870
1913
1871
1914
fn receiver_is_implemented < ' tcx > (
0 commit comments