diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 634ba2baf9667..294a42a114804 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 0000000000000..7f1d1428eb9b4 --- /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 0000000000000..58c83a36a3bdc --- /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`.