about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs29
-rw-r--r--src/test/ui/typeck/issue-96738.rs3
-rw-r--r--src/test/ui/typeck/issue-96738.stderr16
3 files changed, 38 insertions, 10 deletions
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 634ba2baf96..294a42a1148 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -368,16 +368,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if self.is_fn_ty(rcvr_ty, span) {
                     if let SelfSource::MethodCall(expr) = source {
                         let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() {
-                            let local_id = def_id.expect_local();
-                            let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
-                            let node = tcx.hir().get(hir_id);
-                            let fields = node.tuple_fields();
-
-                            if let Some(fields) = fields
-                                && let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
-                                    Some((fields, of))
+                            if let Some(local_id) = def_id.as_local() {
+                                let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
+                                let node = tcx.hir().get(hir_id);
+                                let fields = node.tuple_fields();
+                                if let Some(fields) = fields
+                                    && let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
+                                        Some((fields.len(), of))
+                                } else {
+                                    None
+                                }
                             } else {
-                                None
+                                // The logic here isn't smart but `associated_item_def_ids`
+                                // doesn't work nicely on local.
+                                if let DefKind::Ctor(of, _) = tcx.def_kind(def_id) {
+                                    let parent_def_id = tcx.parent(*def_id);
+                                    Some((tcx.associated_item_def_ids(parent_def_id).len(), of))
+                                } else {
+                                    None
+                                }
                             }
                         } else {
                             None
@@ -385,7 +394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                         // If the function is a tuple constructor, we recommend that they call it
                         if let Some((fields, kind)) = suggest {
-                            suggest_call_constructor(expr.span, kind, fields.len(), &mut err);
+                            suggest_call_constructor(expr.span, kind, fields, &mut err);
                         } else {
                             // General case
                             err.span_label(
diff --git a/src/test/ui/typeck/issue-96738.rs b/src/test/ui/typeck/issue-96738.rs
new file mode 100644
index 00000000000..7f1d1428eb9
--- /dev/null
+++ b/src/test/ui/typeck/issue-96738.rs
@@ -0,0 +1,3 @@
+fn main() {
+    Some.nonexistent_method(); //~ ERROR: no method named `nonexistent_method` found
+}
diff --git a/src/test/ui/typeck/issue-96738.stderr b/src/test/ui/typeck/issue-96738.stderr
new file mode 100644
index 00000000000..58c83a36a3b
--- /dev/null
+++ b/src/test/ui/typeck/issue-96738.stderr
@@ -0,0 +1,16 @@
+error[E0599]: no method named `nonexistent_method` found for fn item `fn(_) -> Option<_> {Option::<_>::Some}` in the current scope
+  --> $DIR/issue-96738.rs:2:10
+   |
+LL |     Some.nonexistent_method();
+   |     ---- ^^^^^^^^^^^^^^^^^^ method not found in `fn(_) -> Option<_> {Option::<_>::Some}`
+   |     |
+   |     this is the constructor of an enum variant
+   |
+help: call the constructor
+   |
+LL |     (Some)(_).nonexistent_method();
+   |     +    ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.