From 0e986825762edd031bc6bf4a78d9162ac2ed6268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Sep 2023 01:47:06 +0000 Subject: [PATCH] When encountering method on `Self` that we can't suggest, mention it --- .../rustc_resolve/src/late/diagnostics.rs | 58 +++++++++---------- .../suggestions/assoc_fn_without_self.stderr | 3 + 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 44dba9b7be7..c690ac6c043 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -214,6 +214,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { module: None, } } else { + let mut span_label = None; let item_span = path.last().unwrap().ident.span; let (mod_prefix, mod_str, module, suggestion) = if path.len() == 1 { 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 Some(items) = self.diagnostic_metadata.current_impl_items && 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). && !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 { - AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => "self.", - _ => "Self::", - }; - - Some(( - item_span.shrink_to_lo(), - match &item.kind { - AssocItemKind::Fn(..) => "consider using the associated function", - AssocItemKind::Const(..) => "consider using the associated constant", - _ => unreachable!("item kind was filtered above"), - }, - self_sugg.to_string() - )) + let sp = item_span.shrink_to_lo(); + match &item.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). + // We also want to mention that the method exists. + span_label = Some(( + item.ident.span, + "a method by that name is available on `Self` here", + )); + None + } + 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 { 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}"), fallback_label, span: item_span, - span_label: None, + span_label, could_be_expr: false, suggestion, module, diff --git a/tests/ui/suggestions/assoc_fn_without_self.stderr b/tests/ui/suggestions/assoc_fn_without_self.stderr index a7fab36bf8d..26fcc2a0181 100644 --- a/tests/ui/suggestions/assoc_fn_without_self.stderr +++ b/tests/ui/suggestions/assoc_fn_without_self.stderr @@ -12,6 +12,9 @@ LL | Self::foo(); error[E0425]: cannot find function `bar` in this scope --> $DIR/assoc_fn_without_self.rs:17:9 | +LL | fn bar(&self) {} + | --- a method by that name is available on `Self` here +... LL | bar(); | ^^^ not found in this scope