diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-09-24 01:14:06 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-24 01:14:06 +0200 |
| commit | 61b38b216a683af2f5df42c036c52c5bee34ef1c (patch) | |
| tree | 25a00d437d27a7a6302b4aeaa3e6f5a15b90378d /compiler | |
| parent | 8c9e516e6e97bd8a03f6d171ee3f678e43ee7858 (diff) | |
| parent | 7d8559ac9077e35a687d5b16f17f2f493421f3ab (diff) | |
| download | rust-61b38b216a683af2f5df42c036c52c5bee34ef1c.tar.gz rust-61b38b216a683af2f5df42c036c52c5bee34ef1c.zip | |
Rollup merge of #116086 - estebank:issue-115992, r=compiler-errors
More accurate suggestion for `self.` and `Self::` Detect that we can't suggest `self.` in an associated function without `&self` receiver. Partially address #115992. r? ``@compiler-errors``
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index c34b7df9b46..06a08f29a1e 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,32 +225,41 @@ 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 let AssocItemKind::Fn(..) | AssocItemKind::Const(..) = &i.kind - && i.ident.name == item_str.name - // don't suggest if the item is in Fn signature arguments - // issue #112590 + 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 true - } - 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_) if fn_.sig.decl.has_self() => Some(( + sp, + "consider using the method on `Self`", + "self.".to_string(), + )), + AssocItemKind::Fn(_) => Some(( + sp, + "consider using the associated function on `Self`", + "Self::".to_string(), + )), + AssocItemKind::Const(..) => Some(( + sp, + "consider using the associated constant on `Self`", + "Self::".to_string(), + )), + _ => None + } } else { None }; @@ -314,7 +324,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, |
