Do not suggest pinning missing .get_ref()

When suggesting field access which would encounter a method not found, do not suggest pinning when those methods are on `impl Pin` itself.

```
error[E0599]: no method named `get_ref` found for tuple `(BufReader<File>,)` in the current scope
  --> $DIR/missing-field-access.rs:11:15
   |
LL |     let x = f.get_ref();
   |               ^^^^^^^ method not found in `(BufReader<File>,)`
   |
help: one of the expressions' fields has a method of the same name
   |
LL |     let x = f.0.get_ref();
   |               ++
```
instead of
```
error[E0599]: no method named `get_ref` found for tuple `(BufReader<File>,)` in the current scope
  --> $DIR/missing-field-access.rs:11:15
   |
LL |     let x = f.get_ref();
   |               ^^^^^^^ method not found in `(BufReader<File>,)`
   |
help: one of the expressions' fields has a method of the same name
   |
LL |     let x = f.0.get_ref();
   |               ++
help: consider pinning the expression
   |
LL ~     let mut pinned = std::pin::pin!(f);
LL ~     let x = pinned.as_ref().get_ref();
   |
```
This commit is contained in:
Esteban Küber
2025-07-29 20:14:02 +00:00
parent 26c12c7462
commit dd3b8255ca
3 changed files with 14 additions and 18 deletions
@@ -3585,6 +3585,7 @@ fn suggest_traits_to_import(
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.
@@ -3670,7 +3671,7 @@ fn suggest_traits_to_import(
)
{
debug!("try_alt_rcvr: pick candidate {:?}", pick);
let did = Some(pick.item.container_id(self.tcx));
let did = pick.item.trait_container(self.tcx);
// We don't want to suggest a container type when the missing
// method is `.clone()` or `.deref()` otherwise we'd suggest
// `Arc::new(foo).clone()`, which is far from what the user wants.
@@ -3734,6 +3735,12 @@ fn suggest_traits_to_import(
// 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,
}
}))
// 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>`
+4 -5
View File
@@ -1,3 +1,7 @@
// Ensure that suggestions to search for missing intermediary field accesses are available for both
// tuple structs *and* regular tuples.
// Ensure that we do not suggest pinning the expression just because `Pin::get_ref` exists.
// https://github.com/rust-lang/rust/issues/144602
use std::{fs::File, io::BufReader};
struct F(BufReader<File>);
@@ -6,12 +10,7 @@ fn main() {
let f = F(BufReader::new(File::open("x").unwrap()));
let x = f.get_ref(); //~ ERROR E0599
//~^ HELP one of the expressions' fields has a method of the same name
//~| HELP consider pinning the expression
let f = (BufReader::new(File::open("x").unwrap()), );
let x = f.get_ref(); //~ ERROR E0599
//~^ HELP one of the expressions' fields has a method of the same name
//~| HELP consider pinning the expression
// FIXME(estebank): the pinning suggestion should not be included in either case.
// https://github.com/rust-lang/rust/issues/144602
}
+2 -12
View File
@@ -1,5 +1,5 @@
error[E0599]: no method named `get_ref` found for struct `F` in the current scope
--> $DIR/missing-field-access.rs:7:15
--> $DIR/missing-field-access.rs:11:15
|
LL | struct F(BufReader<File>);
| -------- method `get_ref` not found for this struct
@@ -11,14 +11,9 @@ help: one of the expressions' fields has a method of the same name
|
LL | let x = f.0.get_ref();
| ++
help: consider pinning the expression
|
LL ~ let mut pinned = std::pin::pin!(f);
LL ~ let x = pinned.as_ref().get_ref();
|
error[E0599]: no method named `get_ref` found for tuple `(BufReader<File>,)` in the current scope
--> $DIR/missing-field-access.rs:11:15
--> $DIR/missing-field-access.rs:14:15
|
LL | let x = f.get_ref();
| ^^^^^^^ method not found in `(BufReader<File>,)`
@@ -27,11 +22,6 @@ help: one of the expressions' fields has a method of the same name
|
LL | let x = f.0.get_ref();
| ++
help: consider pinning the expression
|
LL ~ let mut pinned = std::pin::pin!(f);
LL ~ let x = pinned.as_ref().get_ref();
|
error: aborting due to 2 previous errors