Skip to content

Commit 35d77c1

Browse files
committed
Also suggest calling constructors for external DefIds
1 parent 436c0e1 commit 35d77c1

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

compiler/rustc_typeck/src/check/method/suggest.rs

+20-10
Original file line numberDiff line numberDiff line change
@@ -367,24 +367,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
367367

368368
if self.is_fn_ty(rcvr_ty, span) {
369369
if let SelfSource::MethodCall(expr) = source {
370-
let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() && let Some(local_id) = def_id.as_local() {
371-
let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
372-
let node = tcx.hir().get(hir_id);
373-
let fields = node.tuple_fields();
374-
375-
if let Some(fields) = fields
376-
&& let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
377-
Some((fields, of))
370+
let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() {
371+
if let Some(local_id) = def_id.as_local() {
372+
let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
373+
let node = tcx.hir().get(hir_id);
374+
let fields = node.tuple_fields();
375+
if let Some(fields) = fields
376+
&& let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
377+
Some((fields.len(), of))
378+
} else {
379+
None
380+
}
378381
} else {
379-
None
382+
// The logic here isn't smart but `associated_item_def_ids`
383+
// doesn't work nicely on local.
384+
if let DefKind::Ctor(of, _) = tcx.def_kind(def_id) {
385+
let parent_def_id = tcx.parent(*def_id);
386+
Some((tcx.associated_item_def_ids(parent_def_id).len(), of))
387+
} else {
388+
None
389+
}
380390
}
381391
} else {
382392
None
383393
};
384394

385395
// If the function is a tuple constructor, we recommend that they call it
386396
if let Some((fields, kind)) = suggest {
387-
suggest_call_constructor(expr.span, kind, fields.len(), &mut err);
397+
suggest_call_constructor(expr.span, kind, fields, &mut err);
388398
} else {
389399
// General case
390400
err.span_label(

src/test/ui/typeck/issue-96738.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ error[E0599]: no method named `nonexistent_method` found for fn item `fn(_) -> O
44
LL | Some.nonexistent_method();
55
| ---- ^^^^^^^^^^^^^^^^^^ method not found in `fn(_) -> Option<_> {Option::<_>::Some}`
66
| |
7-
| this is a function, perhaps you wish to call it
7+
| this is the constructor of an enum variant
8+
|
9+
help: call the constructor
10+
|
11+
LL | (Some)(_).nonexistent_method();
12+
| + ++++
813

914
error: aborting due to previous error
1015

0 commit comments

Comments
 (0)