Also suggest calling constructors for external DefIds

This commit is contained in:
Yuki Okushi 2022-05-07 00:43:50 +09:00
parent 436c0e129c
commit 35d77c1710
No known key found for this signature in database
GPG Key ID: 379CEEFDD63E5DD7
2 changed files with 26 additions and 11 deletions

View File

@ -367,16 +367,26 @@ pub fn report_method_error(
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 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, of))
let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() {
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
@ -384,7 +394,7 @@ pub fn report_method_error(
// 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(

View File

@ -4,7 +4,12 @@ error[E0599]: no method named `nonexistent_method` found for fn item `fn(_) -> O
LL | Some.nonexistent_method();
| ---- ^^^^^^^^^^^^^^^^^^ method not found in `fn(_) -> Option<_> {Option::<_>::Some}`
| |
| this is a function, perhaps you wish to call it
| this is the constructor of an enum variant
|
help: call the constructor
|
LL | (Some)(_).nonexistent_method();
| + ++++
error: aborting due to previous error