about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-08-22 22:01:03 -0400
committerGitHub <noreply@github.com>2025-08-22 22:01:03 -0400
commit418bbb283fca5e7ee5ebe30646a4dd7ae62698ea (patch)
tree569a45ecee9bfea0635d5a917e64ef40fba22899 /compiler
parent676d383c7a643606577b56fdbe9cdc4540d0f1ba (diff)
parent5a2b70b2027d00823659a85c2791d7611bcf1989 (diff)
downloadrust-418bbb283fca5e7ee5ebe30646a4dd7ae62698ea.tar.gz
rust-418bbb283fca5e7ee5ebe30646a4dd7ae62698ea.zip
Rollup merge of #145765 - lqd:revert-142034, r=fmease
Revert suggestions for missing methods in tuples

As requested by `@estebank` and as discussed with `@jackh726,` this reverts rust-lang/rust#142034 because of diagnostics ICEs like rust-lang/rust#142488 and its duplicates that have reached stable by now.

We will work on a proper fix to reland this cool work in the near future, but in the meantime, a revert is safer to validate and backport to beta and stable, so here it is.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs123
1 files changed, 2 insertions, 121 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 824d592fa6c..c8f6c06b720 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -13,9 +13,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::codes::*;
-use rustc_errors::{
-    Applicability, Diag, DiagStyledString, MultiSpan, StashKey, pluralize, struct_span_code_err,
-};
+use rustc_errors::{Applicability, Diag, MultiSpan, StashKey, pluralize, struct_span_code_err};
 use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -1560,11 +1558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
 
-        if rcvr_ty.is_numeric() && rcvr_ty.is_fresh()
-            || restrict_type_params
-            || suggested_derive
-            || self.lookup_alternative_tuple_impls(&mut err, &unsatisfied_predicates)
-        {
+        if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params || suggested_derive {
         } else {
             self.suggest_traits_to_import(
                 &mut err,
@@ -1741,119 +1735,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit()
     }
 
-    /// If the predicate failure is caused by an unmet bound on a tuple, recheck if the bound would
-    /// succeed if all the types on the tuple had no borrows. This is a common problem for libraries
-    /// like Bevy and ORMs, which rely heavily on traits being implemented on tuples.
-    fn lookup_alternative_tuple_impls(
-        &self,
-        err: &mut Diag<'_>,
-        unsatisfied_predicates: &[(
-            ty::Predicate<'tcx>,
-            Option<ty::Predicate<'tcx>>,
-            Option<ObligationCause<'tcx>>,
-        )],
-    ) -> bool {
-        let mut found_tuple = false;
-        for (pred, root, _ob) in unsatisfied_predicates {
-            let mut preds = vec![pred];
-            if let Some(root) = root {
-                // We will look at both the current predicate and the root predicate that caused it
-                // to be needed. If calling something like `<(A, &B)>::default()`, then `pred` is
-                // `&B: Default` and `root` is `(A, &B): Default`, which is the one we are checking
-                // for further down, so we check both.
-                preds.push(root);
-            }
-            for pred in preds {
-                if let Some(clause) = pred.as_clause()
-                    && let Some(clause) = clause.as_trait_clause()
-                    && let ty = clause.self_ty().skip_binder()
-                    && let ty::Tuple(types) = ty.kind()
-                {
-                    let path = clause.skip_binder().trait_ref.print_only_trait_path();
-                    let def_id = clause.def_id();
-                    let ty = Ty::new_tup(
-                        self.tcx,
-                        self.tcx.mk_type_list_from_iter(types.iter().map(|ty| ty.peel_refs())),
-                    );
-                    let args = ty::GenericArgs::for_item(self.tcx, def_id, |param, _| {
-                        if param.index == 0 {
-                            ty.into()
-                        } else {
-                            self.infcx.var_for_def(DUMMY_SP, param)
-                        }
-                    });
-                    if self
-                        .infcx
-                        .type_implements_trait(def_id, args, self.param_env)
-                        .must_apply_modulo_regions()
-                    {
-                        // "`Trait` is implemented for `(A, B)` but not for `(A, &B)`"
-                        let mut msg = DiagStyledString::normal(format!("`{path}` "));
-                        msg.push_highlighted("is");
-                        msg.push_normal(" implemented for `(");
-                        let len = types.len();
-                        for (i, t) in types.iter().enumerate() {
-                            msg.push(
-                                format!("{}", with_forced_trimmed_paths!(t.peel_refs())),
-                                t.peel_refs() != t,
-                            );
-                            if i < len - 1 {
-                                msg.push_normal(", ");
-                            }
-                        }
-                        msg.push_normal(")` but ");
-                        msg.push_highlighted("not");
-                        msg.push_normal(" for `(");
-                        for (i, t) in types.iter().enumerate() {
-                            msg.push(
-                                format!("{}", with_forced_trimmed_paths!(t)),
-                                t.peel_refs() != t,
-                            );
-                            if i < len - 1 {
-                                msg.push_normal(", ");
-                            }
-                        }
-                        msg.push_normal(")`");
-
-                        // Find the span corresponding to the impl that was found to point at it.
-                        if let Some(impl_span) = self
-                            .tcx
-                            .all_impls(def_id)
-                            .filter(|&impl_def_id| {
-                                let header = self.tcx.impl_trait_header(impl_def_id).unwrap();
-                                let trait_ref = header.trait_ref.instantiate(
-                                    self.tcx,
-                                    self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
-                                );
-
-                                let value = ty::fold_regions(self.tcx, ty, |_, _| {
-                                    self.tcx.lifetimes.re_erased
-                                });
-                                // FIXME: Don't bother dealing with non-lifetime binders here...
-                                if value.has_escaping_bound_vars() {
-                                    return false;
-                                }
-                                self.infcx.can_eq(ty::ParamEnv::empty(), trait_ref.self_ty(), value)
-                                    && header.polarity == ty::ImplPolarity::Positive
-                            })
-                            .map(|impl_def_id| self.tcx.def_span(impl_def_id))
-                            .next()
-                        {
-                            err.highlighted_span_note(impl_span, msg.0);
-                        } else {
-                            err.highlighted_note(msg.0);
-                        }
-                        found_tuple = true;
-                    }
-                    // If `pred` was already on the tuple, we don't need to look at the root
-                    // obligation too.
-                    break;
-                }
-            }
-        }
-        found_tuple
-    }
-
     /// If an appropriate error source is not found, check method chain for possible candidates
     fn lookup_segments_chain_for_no_match_method(
         &self,