1
Fork 0

When encountering method on Self that we can't suggest, mention it

This commit is contained in:
Esteban Küber 2023-09-23 01:47:06 +00:00
parent c4a4926083
commit 0e98682576
2 changed files with 31 additions and 30 deletions

View file

@ -214,6 +214,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
module: None, module: None,
} }
} else { } else {
let mut span_label = None;
let item_span = path.last().unwrap().ident.span; let item_span = path.last().unwrap().ident.span;
let (mod_prefix, mod_str, module, suggestion) = if path.len() == 1 { let (mod_prefix, mod_str, module, suggestion) = if path.len() == 1 {
debug!(?self.diagnostic_metadata.current_impl_items); debug!(?self.diagnostic_metadata.current_impl_items);
@ -224,39 +225,36 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
&& let FnKind::Fn(_, _, sig, ..) = fn_kind && let FnKind::Fn(_, _, sig, ..) = fn_kind
&& let Some(items) = self.diagnostic_metadata.current_impl_items && let Some(items) = self.diagnostic_metadata.current_impl_items
&& let Some(item) = items.iter().find(|i| { && let Some(item) = items.iter().find(|i| {
if i.ident.name == item_str.name i.ident.name == item_str.name
// Don't suggest if the item is in Fn signature arguments (#112590). // Don't suggest if the item is in Fn signature arguments (#112590).
&& !sig.span.contains(item_span) && !sig.span.contains(item_span)
{
debug!(?item_str.name);
return match &i.kind {
AssocItemKind::Fn(fn_)
if !sig.decl.has_self() && fn_.sig.decl.has_self() => {
// Ensure that we only suggest `self.` if `self` is available,
// you can't call `fn foo(&self)` from `fn bar()` (#115992).
false
}
AssocItemKind::Fn(_) | AssocItemKind::Const(..) => true,
_ => false
}
}
false
}) })
{ {
let self_sugg = match &item.kind { let sp = item_span.shrink_to_lo();
AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => "self.", match &item.kind {
_ => "Self::", AssocItemKind::Fn(fn_)
}; if !sig.decl.has_self() && fn_.sig.decl.has_self() => {
// Ensure that we only suggest `self.` if `self` is available,
Some(( // you can't call `fn foo(&self)` from `fn bar()` (#115992).
item_span.shrink_to_lo(), // We also want to mention that the method exists.
match &item.kind { span_label = Some((
AssocItemKind::Fn(..) => "consider using the associated function", item.ident.span,
AssocItemKind::Const(..) => "consider using the associated constant", "a method by that name is available on `Self` here",
_ => unreachable!("item kind was filtered above"), ));
}, None
self_sugg.to_string() }
)) AssocItemKind::Fn(fn_) => Some((
sp,
"consider using the associated function",
if fn_.sig.decl.has_self() { "self." } else { "Self::" },
)),
AssocItemKind::Const(..) => Some((
sp,
"consider using the associated constant",
"Self::",
)),
_ => None
}
} else { } else {
None None
}; };
@ -321,7 +319,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"), msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"),
fallback_label, fallback_label,
span: item_span, span: item_span,
span_label: None, span_label,
could_be_expr: false, could_be_expr: false,
suggestion, suggestion,
module, module,

View file

@ -12,6 +12,9 @@ LL | Self::foo();
error[E0425]: cannot find function `bar` in this scope error[E0425]: cannot find function `bar` in this scope
--> $DIR/assoc_fn_without_self.rs:17:9 --> $DIR/assoc_fn_without_self.rs:17:9
| |
LL | fn bar(&self) {}
| --- a method by that name is available on `Self` here
...
LL | bar(); LL | bar();
| ^^^ not found in this scope | ^^^ not found in this scope