about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2025-07-30 16:32:15 +0000
committerEsteban Küber <esteban@kuber.com.ar>2025-08-07 21:39:00 +0000
commiteace82ca42ddffbbda8e2f34444e564ea375580d (patch)
tree0101513900b1eaa7cf61ce5021bd897ae4fdcdf9
parenta17e8cfe8f64ed8c14ffa44081f518b617bfbe35 (diff)
downloadrust-eace82ca42ddffbbda8e2f34444e564ea375580d.tar.gz
rust-eace82ca42ddffbbda8e2f34444e564ea375580d.zip
review comment
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs56
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs14
2 files changed, 31 insertions, 39 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index edb497b763a..0498a938366 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3462,52 +3462,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// This method is called after we have encountered a missing field error to recursively
     /// search for the field
+    #[instrument(skip(self, matches, mod_id, hir_id), level = "debug")]
     pub(crate) fn check_for_nested_field_satisfying_condition_for_diag(
         &self,
         span: Span,
         matches: &impl Fn(Ident, Ty<'tcx>) -> bool,
-        candidate_field: (Ident, Ty<'tcx>),
+        (candidate_name, candidate_ty): (Ident, Ty<'tcx>),
         mut field_path: Vec<Ident>,
         mod_id: DefId,
         hir_id: HirId,
     ) -> Option<Vec<Ident>> {
-        debug!(
-            "check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}",
-            span, candidate_field, field_path
-        );
-
         if field_path.len() > 3 {
             // For compile-time reasons and to avoid infinite recursion we only check for fields
             // up to a depth of three
-            None
-        } else {
-            field_path.push(candidate_field.0);
-            let field_ty = candidate_field.1;
-            if matches(candidate_field.0, field_ty) {
-                return Some(field_path);
-            } else {
-                for nested_fields in self.get_field_candidates_considering_privacy_for_diag(
-                    span, field_ty, mod_id, hir_id,
+            return None;
+        }
+        field_path.push(candidate_name);
+        if matches(candidate_name, candidate_ty) {
+            return Some(field_path);
+        }
+        for nested_fields in self.get_field_candidates_considering_privacy_for_diag(
+            span,
+            candidate_ty,
+            mod_id,
+            hir_id,
+        ) {
+            // recursively search fields of `candidate_field` if it's a ty::Adt
+            for field in nested_fields {
+                if let Some(field_path) = self.check_for_nested_field_satisfying_condition_for_diag(
+                    span,
+                    matches,
+                    field,
+                    field_path.clone(),
+                    mod_id,
+                    hir_id,
                 ) {
-                    // recursively search fields of `candidate_field` if it's a ty::Adt
-                    for field in nested_fields {
-                        if let Some(field_path) = self
-                            .check_for_nested_field_satisfying_condition_for_diag(
-                                span,
-                                matches,
-                                field,
-                                field_path.clone(),
-                                mod_id,
-                                hir_id,
-                            )
-                        {
-                            return Some(field_path);
-                        }
-                    }
+                    return Some(field_path);
                 }
             }
-            None
         }
+        None
     }
 
     fn check_expr_index(
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index b368d54865c..9c5c2ae5b0a 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3585,7 +3585,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.tcx.lang_items().deref_trait(),
                 self.tcx.lang_items().deref_mut_trait(),
                 self.tcx.lang_items().drop_trait(),
-                self.tcx.lang_items().pin_type(),
                 self.tcx.get_diagnostic_item(sym::AsRef),
             ];
             // Try alternative arbitrary self types that could fulfill this call.
@@ -3720,8 +3719,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     && !alt_rcvr_sugg
                     // `T: !Unpin`
                     && !unpin
-                    // The method isn't `as_ref`, as it would provide a wrong suggestion for `Pin`.
-                    && sym::as_ref != item_name.name
                     // Either `Pin::as_ref` or `Pin::as_mut`.
                     && let Some(pin_call) = pin_call
                     // Search for `item_name` as a method accessible on `Pin<T>`.
@@ -3735,12 +3732,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // We skip some common traits that we don't want to consider because autoderefs
                     // would take care of them.
                     && !skippable.contains(&Some(pick.item.container_id(self.tcx)))
-                    && !skippable.contains(&pick.item.impl_container(self.tcx).and_then(|did| {
-                        match self.tcx.type_of(did).instantiate_identity().kind() {
-                            ty::Adt(def, _) => Some(def.did()),
-                            _ => None,
+                    // Do not suggest pinning when the method is directly on `Pin`.
+                    && pick.item.impl_container(self.tcx).map_or(true, |did| {
+                        match self.tcx.type_of(did).skip_binder().kind() {
+                            ty::Adt(def, _) => Some(def.did()) != self.tcx.lang_items().pin_type(),
+                            _ => true,
                         }
-                    }))
+                    })
                     // We don't want to go through derefs.
                     && pick.autoderefs == 0
                     // Check that the method of the same name that was found on the new `Pin<T>`