diff options
| -rw-r--r-- | compiler/rustc_hir_typeck/src/method/suggest.rs | 9 | ||||
| -rw-r--r-- | tests/ui/tuple/missing-field-access.rs | 9 | ||||
| -rw-r--r-- | tests/ui/tuple/missing-field-access.stderr | 14 |
3 files changed, 14 insertions, 18 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 74bfdb5ba01..b368d54865c 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3585,6 +3585,7 @@ 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. @@ -3670,7 +3671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { 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 @@ 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, + } + })) // 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>` diff --git a/tests/ui/tuple/missing-field-access.rs b/tests/ui/tuple/missing-field-access.rs index 4ccd759ccd2..b94b7cf977c 100644 --- a/tests/ui/tuple/missing-field-access.rs +++ b/tests/ui/tuple/missing-field-access.rs @@ -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 } diff --git a/tests/ui/tuple/missing-field-access.stderr b/tests/ui/tuple/missing-field-access.stderr index 711a8906d62..fd9f01f8ff6 100644 --- a/tests/ui/tuple/missing-field-access.stderr +++ b/tests/ui/tuple/missing-field-access.stderr @@ -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 |
