@@ -13,9 +13,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
1313use rustc_data_structures:: sorted_map:: SortedMap ;
1414use rustc_data_structures:: unord:: UnordSet ;
1515use rustc_errors:: codes:: * ;
16- use rustc_errors:: {
17- Applicability , Diag , DiagStyledString , MultiSpan , StashKey , pluralize, struct_span_code_err,
18- } ;
16+ use rustc_errors:: { Applicability , Diag , MultiSpan , StashKey , pluralize, struct_span_code_err} ;
1917use rustc_hir:: attrs:: AttributeKind ;
2018use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
2119use rustc_hir:: def_id:: DefId ;
@@ -1560,11 +1558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15601558 ) ;
15611559 }
15621560
1563- if rcvr_ty. is_numeric ( ) && rcvr_ty. is_fresh ( )
1564- || restrict_type_params
1565- || suggested_derive
1566- || self . lookup_alternative_tuple_impls ( & mut err, & unsatisfied_predicates)
1567- {
1561+ if rcvr_ty. is_numeric ( ) && rcvr_ty. is_fresh ( ) || restrict_type_params || suggested_derive {
15681562 } else {
15691563 self . suggest_traits_to_import (
15701564 & mut err,
@@ -1741,119 +1735,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17411735 err. emit ( )
17421736 }
17431737
1744- /// If the predicate failure is caused by an unmet bound on a tuple, recheck if the bound would
1745- /// succeed if all the types on the tuple had no borrows. This is a common problem for libraries
1746- /// like Bevy and ORMs, which rely heavily on traits being implemented on tuples.
1747- fn lookup_alternative_tuple_impls (
1748- & self ,
1749- err : & mut Diag < ' _ > ,
1750- unsatisfied_predicates : & [ (
1751- ty:: Predicate < ' tcx > ,
1752- Option < ty:: Predicate < ' tcx > > ,
1753- Option < ObligationCause < ' tcx > > ,
1754- ) ] ,
1755- ) -> bool {
1756- let mut found_tuple = false ;
1757- for ( pred, root, _ob) in unsatisfied_predicates {
1758- let mut preds = vec ! [ pred] ;
1759- if let Some ( root) = root {
1760- // We will look at both the current predicate and the root predicate that caused it
1761- // to be needed. If calling something like `<(A, &B)>::default()`, then `pred` is
1762- // `&B: Default` and `root` is `(A, &B): Default`, which is the one we are checking
1763- // for further down, so we check both.
1764- preds. push ( root) ;
1765- }
1766- for pred in preds {
1767- if let Some ( clause) = pred. as_clause ( )
1768- && let Some ( clause) = clause. as_trait_clause ( )
1769- && let ty = clause. self_ty ( ) . skip_binder ( )
1770- && let ty:: Tuple ( types) = ty. kind ( )
1771- {
1772- let path = clause. skip_binder ( ) . trait_ref . print_only_trait_path ( ) ;
1773- let def_id = clause. def_id ( ) ;
1774- let ty = Ty :: new_tup (
1775- self . tcx ,
1776- self . tcx . mk_type_list_from_iter ( types. iter ( ) . map ( |ty| ty. peel_refs ( ) ) ) ,
1777- ) ;
1778- let args = ty:: GenericArgs :: for_item ( self . tcx , def_id, |param, _| {
1779- if param. index == 0 {
1780- ty. into ( )
1781- } else {
1782- self . infcx . var_for_def ( DUMMY_SP , param)
1783- }
1784- } ) ;
1785- if self
1786- . infcx
1787- . type_implements_trait ( def_id, args, self . param_env )
1788- . must_apply_modulo_regions ( )
1789- {
1790- // "`Trait` is implemented for `(A, B)` but not for `(A, &B)`"
1791- let mut msg = DiagStyledString :: normal ( format ! ( "`{path}` " ) ) ;
1792- msg. push_highlighted ( "is" ) ;
1793- msg. push_normal ( " implemented for `(" ) ;
1794- let len = types. len ( ) ;
1795- for ( i, t) in types. iter ( ) . enumerate ( ) {
1796- msg. push (
1797- format ! ( "{}" , with_forced_trimmed_paths!( t. peel_refs( ) ) ) ,
1798- t. peel_refs ( ) != t,
1799- ) ;
1800- if i < len - 1 {
1801- msg. push_normal ( ", " ) ;
1802- }
1803- }
1804- msg. push_normal ( ")` but " ) ;
1805- msg. push_highlighted ( "not" ) ;
1806- msg. push_normal ( " for `(" ) ;
1807- for ( i, t) in types. iter ( ) . enumerate ( ) {
1808- msg. push (
1809- format ! ( "{}" , with_forced_trimmed_paths!( t) ) ,
1810- t. peel_refs ( ) != t,
1811- ) ;
1812- if i < len - 1 {
1813- msg. push_normal ( ", " ) ;
1814- }
1815- }
1816- msg. push_normal ( ")`" ) ;
1817-
1818- // Find the span corresponding to the impl that was found to point at it.
1819- if let Some ( impl_span) = self
1820- . tcx
1821- . all_impls ( def_id)
1822- . filter ( |& impl_def_id| {
1823- let header = self . tcx . impl_trait_header ( impl_def_id) . unwrap ( ) ;
1824- let trait_ref = header. trait_ref . instantiate (
1825- self . tcx ,
1826- self . infcx . fresh_args_for_item ( DUMMY_SP , impl_def_id) ,
1827- ) ;
1828-
1829- let value = ty:: fold_regions ( self . tcx , ty, |_, _| {
1830- self . tcx . lifetimes . re_erased
1831- } ) ;
1832- // FIXME: Don't bother dealing with non-lifetime binders here...
1833- if value. has_escaping_bound_vars ( ) {
1834- return false ;
1835- }
1836- self . infcx . can_eq ( ty:: ParamEnv :: empty ( ) , trait_ref. self_ty ( ) , value)
1837- && header. polarity == ty:: ImplPolarity :: Positive
1838- } )
1839- . map ( |impl_def_id| self . tcx . def_span ( impl_def_id) )
1840- . next ( )
1841- {
1842- err. highlighted_span_note ( impl_span, msg. 0 ) ;
1843- } else {
1844- err. highlighted_note ( msg. 0 ) ;
1845- }
1846- found_tuple = true ;
1847- }
1848- // If `pred` was already on the tuple, we don't need to look at the root
1849- // obligation too.
1850- break ;
1851- }
1852- }
1853- }
1854- found_tuple
1855- }
1856-
18571738 /// If an appropriate error source is not found, check method chain for possible candidates
18581739 fn lookup_segments_chain_for_no_match_method (
18591740 & self ,
0 commit comments