From 447d894edf1a7414e52e45f14d17f35012b80aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 27 May 2018 13:30:16 -0700 Subject: [PATCH 1/9] Use suggestion for assoc fn called like method When encountering an unexisting method for a given trait where an associated function has the same name, suggest using the appropriate syntax, instead of using `help` text. When only one candidate is found, do not call it "candidate #1", just call it "the candidate". --- src/librustc_typeck/check/method/suggest.rs | 52 ++++++++++++++----- .../ui/hygiene/no_implicit_prelude.stderr | 2 +- src/test/ui/hygiene/trait_items.stderr | 2 +- src/test/ui/span/issue-7575.stderr | 19 ++++--- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 8a575c1478765..ce49feed7d947 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), ¬e_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), @@ -368,7 +380,14 @@ 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)); + if let Some(expr) = rcvr_expr { + err.span_suggestion(expr.span.to(span), + "use associated function syntax intead", + 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); } @@ -468,9 +487,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 5753d1a32f74f..b3d82e9094ba7 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 56d9c585d6f85..1b2975bcf1c28 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 dc2cd4c2ddc30..00f08f1d8e085 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -2,10 +2,11 @@ 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) - | ^^ + | --^^ + | | + | help: use associated function syntax intead: `usize::f9` | = 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 +38,12 @@ LL | struct Myisize(isize); | ---------------------- method `fff` not found for this ... LL | u.f8(42) + u.f9(342) + m.fff(42) - | ^^^ + | --^^^ + | | + | help: use associated function syntax intead: `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 +53,12 @@ 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() - | ^^^^^^ + | --^^^^^^ + | | + | help: use associated function syntax intead: `T::is_str` | = 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 { From 6c7a5ba02043324580f5c75c6386e84812e83940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 28 May 2018 10:12:23 -0700 Subject: [PATCH 2/9] Only suggest assoc fn when sure about the type --- src/librustc_typeck/check/method/suggest.rs | 5 +++++ src/test/ui/span/issue-7575.stderr | 8 ++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index ce49feed7d947..2fc4b3bea58bc 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -380,6 +380,8 @@ 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"); + } + if static_sources.len() == 1 { if let Some(expr) = rcvr_expr { err.span_suggestion(expr.span.to(span), "use associated function syntax intead", @@ -389,6 +391,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { 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); } diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 00f08f1d8e085..3ae784b32a4ee 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -2,9 +2,7 @@ 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) - | --^^ - | | - | help: use associated function syntax intead: `usize::f9` + | ^^ | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: candidate #1 is defined in the trait `CtxtFn` @@ -53,9 +51,7 @@ 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() - | --^^^^^^ - | | - | help: use associated function syntax intead: `T::is_str` + | ^^^^^^ | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `ManyImplTrait` From b169cf112807024e811154b15e622662ea8eea23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 28 May 2018 10:29:49 -0700 Subject: [PATCH 3/9] Add primary span label --- src/librustc_typeck/check/method/suggest.rs | 3 ++- src/test/ui/span/issue-7575.stderr | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 2fc4b3bea58bc..4d4e91913785d 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -297,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 {}", @@ -380,6 +380,7 @@ 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.span_label(span, "this is an associated function, not a method"); } if static_sources.len() == 1 { if let Some(expr) = rcvr_expr { diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 3ae784b32a4ee..1061a8d968158 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -2,7 +2,7 @@ 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 note: candidate #1 is defined in the trait `CtxtFn` @@ -37,7 +37,8 @@ LL | struct Myisize(isize); ... LL | u.f8(42) + u.f9(342) + m.fff(42) | --^^^ - | | + | | | + | | this is an associated function, not a method | help: use associated function syntax intead: `Myisize::fff` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter @@ -51,7 +52,7 @@ 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 note: the candidate is defined in the trait `ManyImplTrait` From 2b2eff15cdfedce296b68ffefca367346291c85e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 28 May 2018 10:57:26 -0700 Subject: [PATCH 4/9] Fix tidy --- src/librustc_typeck/check/method/suggest.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 4d4e91913785d..8213bd217b87f 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -386,7 +386,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(expr) = rcvr_expr { err.span_suggestion(expr.span.to(span), "use associated function syntax intead", - format!("{}::{}", self.ty_to_string(actual), item_name)); + format!("{}::{}", + self.ty_to_string(actual), + item_name)); } else { err.help(&format!("try with `{}::{}`", self.ty_to_string(actual), item_name)); From 59b03b16b991c6920ccb0f79acc1e5d04ccc2abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 29 May 2018 14:48:23 -0700 Subject: [PATCH 5/9] Fix typo --- src/librustc_typeck/check/method/suggest.rs | 2 +- src/test/ui/span/issue-7575.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 8213bd217b87f..6031984350b95 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -385,7 +385,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if static_sources.len() == 1 { if let Some(expr) = rcvr_expr { err.span_suggestion(expr.span.to(span), - "use associated function syntax intead", + "use associated function syntax instead", format!("{}::{}", self.ty_to_string(actual), item_name)); diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 1061a8d968158..e31134f843b72 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -39,7 +39,7 @@ LL | u.f8(42) + u.f9(342) + m.fff(42) | --^^^ | | | | | this is an associated function, not a method - | help: use associated function syntax intead: `Myisize::fff` + | 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 note: the candidate is defined in an impl for the type `Myisize` From 32dcaab58578e8c0cb6f76e8a1842e5a2b79a3fb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 1 Jun 2018 01:29:22 +0200 Subject: [PATCH 6/9] Add missing whitespace in num example --- src/libcore/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 013d0334d4164..2418b5e8c75cc 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -2313,7 +2313,7 @@ Basic usage: ``` ", $Feature, "assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(1), ", "Some(", stringify!($SelfT), "::max_value() - 1)); -assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3),None);", $EndFeature, " +assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] #[inline] From 8e90a2d02f4d90409dcd65a8e54b76f1edcba42c Mon Sep 17 00:00:00 2001 From: CrLF0710 Date: Tue, 29 May 2018 15:58:50 +0800 Subject: [PATCH 7/9] Replace `if` with `if and only if` in the definition dox of `Sync` The old text was: "The precise definition is: a type T is Sync if &T is Send." Since we've also got ``` impl<'a, T> Send for &'a T where T: Sync + ?Sized, ``` I purpose we can change the `if` to `if and only if` to make it more precise. --- src/libcore/marker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 77db165bcbde3..3d3f63ecf37d5 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -294,7 +294,7 @@ pub trait Copy : Clone { /// This trait is automatically implemented when the compiler determines /// it's appropriate. /// -/// The precise definition is: a type `T` is `Sync` if `&T` is +/// The precise definition is: a type `T` is `Sync` if and only if `&T` is /// [`Send`][send]. In other words, if there is no possibility of /// [undefined behavior][ub] (including data races) when passing /// `&T` references between threads. From 48bd07e3a9220a937fdfa139c7127009ee5a1130 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 1 Jun 2018 08:24:36 -0400 Subject: [PATCH 8/9] Remove feature flag from fs::read_to_string example This is stable, and so no longer needed --- src/libstd/fs.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 442a0873ae075..987687ea8e865 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -295,8 +295,6 @@ pub fn read>(path: P) -> io::Result> { /// # Examples /// /// ```no_run -/// #![feature(fs_read_write)] -/// /// use std::fs; /// use std::net::SocketAddr; /// From 21423ec3134fda7d429047db94fbbfabb78f7ef1 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 1 Jun 2018 17:23:52 -0600 Subject: [PATCH 9/9] Pull in release notes from stable --- RELEASES.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 758de62a84823..0403a2ac1feb3 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,13 @@ +Version 1.26.2 (2018-06-05) +========================== + +Compatibility Notes +------------------- + +- [The borrow checker was fixed to avoid unsoundness when using match ergonomics][51117] + +[51117]: https://github.com/rust-lang/rust/issues/51117 + Version 1.26.1 (2018-05-29) ==========================