diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2025-07-30 16:32:15 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2025-08-07 21:39:00 +0000 |
| commit | eace82ca42ddffbbda8e2f34444e564ea375580d (patch) | |
| tree | 0101513900b1eaa7cf61ce5021bd897ae4fdcdf9 | |
| parent | a17e8cfe8f64ed8c14ffa44081f518b617bfbe35 (diff) | |
| download | rust-eace82ca42ddffbbda8e2f34444e564ea375580d.tar.gz rust-eace82ca42ddffbbda8e2f34444e564ea375580d.zip | |
review comment
| -rw-r--r-- | compiler/rustc_hir_typeck/src/expr.rs | 56 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/method/suggest.rs | 14 |
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>` |
