about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs9
-rw-r--r--tests/ui/tuple/missing-field-access.rs9
-rw-r--r--tests/ui/tuple/missing-field-access.stderr14
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