From f4c76b193d54eeb88b2c966612679d733536efaf Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Mon, 5 Dec 2022 08:15:30 -0800
Subject: [PATCH] Be more careful about unresolved exprs in suggestion

---
 .../rustc_hir_typeck/src/method/suggest.rs    | 23 +++++++++++--------
 .../path-to-method-sugg-unresolved-expr.rs    |  4 ++++
 ...path-to-method-sugg-unresolved-expr.stderr |  9 ++++++++
 3 files changed, 26 insertions(+), 10 deletions(-)
 create mode 100644 src/test/ui/typeck/path-to-method-sugg-unresolved-expr.rs
 create mode 100644 src/test/ui/typeck/path-to-method-sugg-unresolved-expr.stderr

diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 9ba4ddfd5cf7f..db93cfab2c0db 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1482,15 +1482,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ident_name: Symbol,
         }
 
+        // FIXME: This really should be taking scoping, etc into account.
         impl<'v> Visitor<'v> for LetVisitor<'v> {
             fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
-                if let hir::StmtKind::Local(hir::Local { pat, init, .. }) = &ex.kind {
-                    if let Binding(_, _, ident, ..) = pat.kind &&
-                        ident.name == self.ident_name {
-                        self.result = *init;
-                    }
+                if let hir::StmtKind::Local(hir::Local { pat, init, .. }) = &ex.kind
+                    && let Binding(_, _, ident, ..) = pat.kind
+                    && ident.name == self.ident_name
+                {
+                    self.result = *init;
+                } else {
+                    hir::intravisit::walk_stmt(self, ex);
                 }
-                hir::intravisit::walk_stmt(self, ex);
             }
         }
 
@@ -1498,9 +1500,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         visitor.visit_body(&body);
 
         let parent = self.tcx.hir().get_parent_node(seg1.hir_id);
-        if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) &&
-            let Some(expr) = visitor.result {
-            let self_ty = self.node_ty(expr.hir_id);
+        if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent)
+            && let Some(expr) = visitor.result
+            && let Some(self_ty) = self.node_ty_opt(expr.hir_id)
+        {
             let probe = self.lookup_probe(
                 seg2.ident,
                 self_ty,
@@ -1513,7 +1516,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     sm.span_extend_while(seg1.ident.span.shrink_to_hi(), |c| c == ':').unwrap(),
                     "you may have meant to call an instance method",
                     ".".to_string(),
-                    Applicability::MaybeIncorrect
+                    Applicability::MaybeIncorrect,
                 );
             }
         }
diff --git a/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.rs b/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.rs
new file mode 100644
index 0000000000000..fb56b394493dc
--- /dev/null
+++ b/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let page_size = page_size::get();
+    //~^ ERROR failed to resolve: use of undeclared crate or module `page_size`
+}
diff --git a/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.stderr b/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.stderr
new file mode 100644
index 0000000000000..b01e30be54de0
--- /dev/null
+++ b/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.stderr
@@ -0,0 +1,9 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `page_size`
+  --> $DIR/path-to-method-sugg-unresolved-expr.rs:2:21
+   |
+LL |     let page_size = page_size::get();
+   |                     ^^^^^^^^^ use of undeclared crate or module `page_size`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.