about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2018-06-01 17:25:13 -0600
committerGitHub <noreply@github.com>2018-06-01 17:25:13 -0600
commit361a82ca7b8cc4ddbd8266e3e7a66997e98a4e43 (patch)
treec5a2440ce5b99164afc5133cc4bf19d33cd357e9
parentaa094a43cc041c8483b7c80fb0ec4be233dd01b7 (diff)
parent59b03b16b991c6920ccb0f79acc1e5d04ccc2abd (diff)
downloadrust-361a82ca7b8cc4ddbd8266e3e7a66997e98a4e43.tar.gz
rust-361a82ca7b8cc4ddbd8266e3e7a66997e98a4e43.zip
Rollup merge of #51135 - estebank:sugg-7575, r=oli-obk
Tweak output on E0599 for assoc fn used as method

 - Use suggestion instead of `help` when possible
 - Add primary span label
 - Remove incorrect `help` suggestion using incorrect syntax
 - Do not refer to only one possible candidate as `candidate #1`, refer to it as `the candidate`
-rw-r--r--src/librustc_typeck/check/method/suggest.rs62
-rw-r--r--src/test/ui/hygiene/no_implicit_prelude.stderr2
-rw-r--r--src/test/ui/hygiene/trait_items.stderr2
-rw-r--r--src/test/ui/span/issue-7575.stderr16
4 files changed, 57 insertions, 25 deletions
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 8a575c14787..6031984350b 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -119,11 +119,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             }
                         };
 
-                        let note_str = format!("candidate #{} is defined in an impl{} \
-                                                for the type `{}`",
-                                               idx + 1,
-                                               insertion,
-                                               impl_ty);
+                        let note_str = if sources.len() > 1 {
+                            format!("candidate #{} is defined in an impl{} for the type `{}`",
+                                    idx + 1,
+                                    insertion,
+                                    impl_ty)
+                        } else {
+                            format!("the candidate is defined in an impl{} for the type `{}`",
+                                    insertion,
+                                    impl_ty)
+                        };
                         if let Some(note_span) = note_span {
                             // We have a span pointing to the method. Show note with snippet.
                             err.span_note(self.tcx.sess.codemap().def_span(note_span), &note_str);
@@ -137,11 +142,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             .unwrap();
                         let item_span = self.tcx.sess.codemap()
                             .def_span(self.tcx.def_span(item.def_id));
-                        span_note!(err,
-                                   item_span,
-                                   "candidate #{} is defined in the trait `{}`",
-                                   idx + 1,
-                                   self.tcx.item_path_str(trait_did));
+                        if sources.len() > 1 {
+                            span_note!(err,
+                                       item_span,
+                                       "candidate #{} is defined in the trait `{}`",
+                                       idx + 1,
+                                       self.tcx.item_path_str(trait_did));
+                        } else {
+                            span_note!(err,
+                                       item_span,
+                                       "the candidate is defined in the trait `{}`",
+                                       self.tcx.item_path_str(trait_did));
+                        }
                         err.help(&format!("to disambiguate the method call, write `{}::{}({}{})` \
                                           instead",
                                           self.tcx.item_path_str(trait_did),
@@ -285,7 +297,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     tcx.sess.diagnostic().struct_dummy()
                 };
 
-                if let Some(def) =  actual.ty_adt_def() {
+                if let Some(def) = actual.ty_adt_def() {
                     if let Some(full_sp) = tcx.hir.span_if_local(def.did) {
                         let def_sp = tcx.sess.codemap().def_span(full_sp);
                         err.span_label(def_sp, format!("{} `{}` not found {}",
@@ -368,7 +380,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 if !static_sources.is_empty() {
                     err.note("found the following associated functions; to be used as methods, \
                               functions must have a `self` parameter");
-                    err.help(&format!("try with `{}::{}`", self.ty_to_string(actual), item_name));
+                    err.span_label(span, "this is an associated function, not a method");
+                }
+                if static_sources.len() == 1 {
+                    if let Some(expr) = rcvr_expr {
+                        err.span_suggestion(expr.span.to(span),
+                                            "use associated function syntax instead",
+                                            format!("{}::{}",
+                                                    self.ty_to_string(actual),
+                                                    item_name));
+                    } else {
+                        err.help(&format!("try with `{}::{}`",
+                                          self.ty_to_string(actual), item_name));
+                    }
+
+                    report_candidates(&mut err, static_sources);
+                } else if static_sources.len() > 1 {
 
                     report_candidates(&mut err, static_sources);
                 }
@@ -468,9 +495,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         } else {
             let limit = if candidates.len() == 5 { 5 } else { 4 };
             for (i, trait_did) in candidates.iter().take(limit).enumerate() {
-                msg.push_str(&format!("\ncandidate #{}: `use {};`",
-                                        i + 1,
-                                        self.tcx.item_path_str(*trait_did)));
+                if candidates.len() > 1 {
+                    msg.push_str(&format!("\ncandidate #{}: `use {};`",
+                                            i + 1,
+                                            self.tcx.item_path_str(*trait_did)));
+                } else {
+                    msg.push_str(&format!("\n`use {};`",
+                                            self.tcx.item_path_str(*trait_did)));
+                }
             }
             if candidates.len() > limit {
                 msg.push_str(&format!("\nand {} others", candidates.len() - limit));
diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr
index 5753d1a32f7..b3d82e9094b 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude.stderr
@@ -22,7 +22,7 @@ LL |         ().clone() //~ ERROR no method named `clone` found
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
-           candidate #1: `use std::clone::Clone;`
+           `use std::clone::Clone;`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/hygiene/trait_items.stderr b/src/test/ui/hygiene/trait_items.stderr
index 56d9c585d6f..1b2975bcf1c 100644
--- a/src/test/ui/hygiene/trait_items.stderr
+++ b/src/test/ui/hygiene/trait_items.stderr
@@ -9,7 +9,7 @@ LL |     pub macro m() { ().f() } //~ ERROR no method named `f` found for type `
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
-           candidate #1: `use foo::T;`
+           `use foo::T;`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr
index dc2cd4c2ddc..e31134f843b 100644
--- a/src/test/ui/span/issue-7575.stderr
+++ b/src/test/ui/span/issue-7575.stderr
@@ -2,10 +2,9 @@ error[E0599]: no method named `f9` found for type `usize` in the current scope
   --> $DIR/issue-7575.rs:74:18
    |
 LL |     u.f8(42) + u.f9(342) + m.fff(42)
-   |                  ^^
+   |                  ^^ this is an associated function, not a method
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
-   = help: try with `usize::f9`
 note: candidate #1 is defined in the trait `CtxtFn`
   --> $DIR/issue-7575.rs:16:5
    |
@@ -37,11 +36,13 @@ LL | struct Myisize(isize);
    | ---------------------- method `fff` not found for this
 ...
 LL |     u.f8(42) + u.f9(342) + m.fff(42)
-   |                              ^^^
+   |                            --^^^
+   |                            | |
+   |                            | this is an associated function, not a method
+   |                            help: use associated function syntax instead: `Myisize::fff`
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
-   = help: try with `Myisize::fff`
-note: candidate #1 is defined in an impl for the type `Myisize`
+note: the candidate is defined in an impl for the type `Myisize`
   --> $DIR/issue-7575.rs:51:5
    |
 LL |     fn fff(i: isize) -> isize {
@@ -51,11 +52,10 @@ error[E0599]: no method named `is_str` found for type `T` in the current scope
   --> $DIR/issue-7575.rs:82:7
    |
 LL |     t.is_str()
-   |       ^^^^^^
+   |       ^^^^^^ this is an associated function, not a method
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
-   = help: try with `T::is_str`
-note: candidate #1 is defined in the trait `ManyImplTrait`
+note: the candidate is defined in the trait `ManyImplTrait`
   --> $DIR/issue-7575.rs:57:5
    |
 LL |     fn is_str() -> bool {