]> git.lizzy.rs Git - rust.git/commitdiff
suggest calling the method of the same name when method not found
authoryukang <moorekang@gmail.com>
Tue, 25 Oct 2022 16:15:47 +0000 (00:15 +0800)
committeryukang <moorekang@gmail.com>
Tue, 25 Oct 2022 16:45:29 +0000 (00:45 +0800)
compiler/rustc_resolve/src/late/diagnostics.rs
src/test/ui/resolve/issue-103474.rs [new file with mode: 0644]
src/test/ui/resolve/issue-103474.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-2356.stderr
src/test/ui/self/class-missing-self.stderr
src/test/ui/suggestions/assoc_fn_without_self.stderr

index 23c5fac8b71c1a54f623a0f8d308d36911e7103e..23b9284db335fab7804bff1b30c1c8fafa8d1414 100644 (file)
@@ -213,26 +213,26 @@ fn make_base_error(
             let (mod_prefix, mod_str, suggestion) = if path.len() == 1 {
                 debug!(?self.diagnostic_metadata.current_impl_items);
                 debug!(?self.diagnostic_metadata.current_function);
-                let suggestion = if let Some(items) = self.diagnostic_metadata.current_impl_items
+                let suggestion = if self.current_trait_ref.is_none()
                     && let Some((fn_kind, _)) = self.diagnostic_metadata.current_function
-                    && self.current_trait_ref.is_none()
                     && let Some(FnCtxt::Assoc(_)) = fn_kind.ctxt()
+                    && let Some(items) = self.diagnostic_metadata.current_impl_items
                     && let Some(item) = items.iter().find(|i| {
-                        if let AssocItemKind::Fn(fn_) = &i.kind
-                            && !fn_.sig.decl.has_self()
-                            && i.ident.name == item_str.name
+                        if let AssocItemKind::Fn(_) = &i.kind && i.ident.name == item_str.name
                         {
                             debug!(?item_str.name);
-                            debug!(?fn_.sig.decl.inputs);
                             return true
                         }
                         false
                     })
+                    && let AssocItemKind::Fn(fn_) = &item.kind
                 {
+                    debug!(?fn_);
+                    let self_sugg = if fn_.sig.decl.has_self() { "self." } else { "Self::" };
                     Some((
-                        item_span,
+                        item_span.shrink_to_lo(),
                         "consider using the associated function",
-                        format!("Self::{}", item.ident)
+                        self_sugg.to_string()
                     ))
                 } else {
                     None
@@ -381,11 +381,13 @@ fn detect_assoct_type_constraint_meant_as_path(
     }
 
     fn suggest_self_or_self_ref(&mut self, err: &mut Diagnostic, path: &[Segment], span: Span) {
-        let is_assoc_fn = self.self_type_is_available();
+        if !self.self_type_is_available() {
+            return;
+        }
         let Some(path_last_segment) = path.last() else { return };
         let item_str = path_last_segment.ident;
         // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
-        if ["this", "my"].contains(&item_str.as_str()) && is_assoc_fn {
+        if ["this", "my"].contains(&item_str.as_str()) {
             err.span_suggestion_short(
                 span,
                 "you might have meant to use `self` here instead",
@@ -436,7 +438,6 @@ fn try_lookup_name_relaxed(
         let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _));
         let path_str = Segment::names_to_string(path);
         let ident_span = path.last().map_or(span, |ident| ident.ident.span);
-
         let mut candidates = self
             .r
             .lookup_import_candidates(ident, ns, &self.parent_scope, is_expected)
@@ -1512,7 +1513,6 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> {
                 _ => None,
             }
         }
-
         // Fields are generally expected in the same contexts as locals.
         if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) {
             if let Some(node_id) =
diff --git a/src/test/ui/resolve/issue-103474.rs b/src/test/ui/resolve/issue-103474.rs
new file mode 100644 (file)
index 0000000..408139c
--- /dev/null
@@ -0,0 +1,16 @@
+struct S {}
+impl S {
+    fn first(&self) {}
+
+    fn second(&self) {
+        first()
+        //~^ ERROR cannot find function `first` in this scope
+    }
+
+    fn third(&self) {
+        no_method_err()
+        //~^ ERROR cannot find function `no_method_err` in this scope
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-103474.stderr b/src/test/ui/resolve/issue-103474.stderr
new file mode 100644 (file)
index 0000000..78fa13f
--- /dev/null
@@ -0,0 +1,20 @@
+error[E0425]: cannot find function `first` in this scope
+  --> $DIR/issue-103474.rs:6:9
+   |
+LL |         first()
+   |         ^^^^^ not found in this scope
+   |
+help: consider using the associated function
+   |
+LL |         self.first()
+   |         +++++
+
+error[E0425]: cannot find function `no_method_err` in this scope
+  --> $DIR/issue-103474.rs:11:9
+   |
+LL |         no_method_err()
+   |         ^^^^^^^^^^^^^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
index e7c53ff44e6fe0ac3250894733f564fe57a430e6..36f3da7c9553794129913273f3194ddfcdb9da84 100644 (file)
@@ -85,7 +85,7 @@ LL |         static_method();
 help: consider using the associated function
    |
 LL |         Self::static_method();
-   |         ~~~~~~~~~~~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find function `purr` in this scope
   --> $DIR/issue-2356.rs:54:9
@@ -114,7 +114,7 @@ LL |     grow_older();
 help: consider using the associated function
    |
 LL |     Self::grow_older();
-   |     ~~~~~~~~~~~~~~~~
+   |     ++++++
 
 error[E0425]: cannot find function `shave` in this scope
   --> $DIR/issue-2356.rs:74:5
index d501200d73cec9c2b536e277a58fdb1fc6a1c73e..063c3f013c5390474fc2b54f14ad2fbfe7bdd413 100644 (file)
@@ -10,6 +10,10 @@ error[E0425]: cannot find function `sleep` in this scope
 LL |       sleep();
    |       ^^^^^ not found in this scope
    |
+help: consider using the associated function
+   |
+LL |       self.sleep();
+   |       +++++
 help: consider importing this function
    |
 LL | use std::thread::sleep;
index 88920b852905be955928e756c18aaf04cbaf21e6..febdd67338c991263c9f398ad89c7db59b988f4a 100644 (file)
@@ -7,13 +7,18 @@ LL |         foo();
 help: consider using the associated function
    |
 LL |         Self::foo();
-   |         ~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find function `bar` in this scope
   --> $DIR/assoc_fn_without_self.rs:17:9
    |
 LL |         bar();
    |         ^^^ not found in this scope
+   |
+help: consider using the associated function
+   |
+LL |         self.bar();
+   |         +++++
 
 error[E0425]: cannot find function `baz` in this scope
   --> $DIR/assoc_fn_without_self.rs:18:9
@@ -24,7 +29,7 @@ LL |         baz(2, 3);
 help: consider using the associated function
    |
 LL |         Self::baz(2, 3);
-   |         ~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find function `foo` in this scope
   --> $DIR/assoc_fn_without_self.rs:14:13