about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJosh Stone <cuviper@gmail.com>2019-03-27 18:15:24 -0700
committerGitHub <noreply@github.com>2019-03-27 18:15:24 -0700
commite5fa59735bdc6624a4489b82801c4dc44998f81b (patch)
treea48fbd1828f081d4bf52fc2a3625c8ef0fc33ea0
parentecf63630cfbeeb62764a9b417f29258d6abdd2df (diff)
parente929d19edc99e5eb7af319709247470cff99719b (diff)
downloadrust-e5fa59735bdc6624a4489b82801c4dc44998f81b.tar.gz
rust-e5fa59735bdc6624a4489b82801c4dc44998f81b.zip
Rollup merge of #59268 - estebank:from-string, r=QuietMisdreavus
Add suggestion to use `&*var` when `&str: From<String>` is expected

Fix #53879.
-rw-r--r--src/doc/unstable-book/src/language-features/on-unimplemented.md13
-rw-r--r--src/libcore/convert.rs6
-rw-r--r--src/test/ui/suggestions/into-str.rs6
-rw-r--r--src/test/ui/suggestions/into-str.stderr17
4 files changed, 42 insertions, 0 deletions
diff --git a/src/doc/unstable-book/src/language-features/on-unimplemented.md b/src/doc/unstable-book/src/language-features/on-unimplemented.md
index f787f629756..a770ab65c26 100644
--- a/src/doc/unstable-book/src/language-features/on-unimplemented.md
+++ b/src/doc/unstable-book/src/language-features/on-unimplemented.md
@@ -138,3 +138,16 @@ error[E0277]: `&str` is not an iterator
   = help: the trait `std::iter::Iterator` is not implemented for `&str`
   = note: required by `std::iter::IntoIterator::into_iter`
 ```
+
+If you need to filter on multiple attributes, you can use `all`, `any` or
+`not` in the following way:
+
+```rust,compile_fail
+#[rustc_on_unimplemented(
+    on(
+        all(_Self="&str", T="std::string::String"),
+        note="you can coerce a `{T}` into a `{Self}` by writing `&*variable`"
+    )
+)]
+pub trait From<T>: Sized { /* ... */ }
+```
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index cee4fc6f49a..a6c65e890a5 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -363,6 +363,12 @@ pub trait Into<T>: Sized {
 /// [`from`]: trait.From.html#tymethod.from
 /// [book]: ../../book/ch09-00-error-handling.html
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    on(
+        all(_Self="&str", T="std::string::String"),
+        note="to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
+    )
+)]
 pub trait From<T>: Sized {
     /// Performs the conversion.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/test/ui/suggestions/into-str.rs b/src/test/ui/suggestions/into-str.rs
new file mode 100644
index 00000000000..9793ee801d1
--- /dev/null
+++ b/src/test/ui/suggestions/into-str.rs
@@ -0,0 +1,6 @@
+fn foo<'a, T>(_t: T) where T: Into<&'a str> {}
+
+fn main() {
+    foo(String::new());
+    //~^ ERROR the trait bound `&str: std::convert::From<std::string::String>` is not satisfied
+}
diff --git a/src/test/ui/suggestions/into-str.stderr b/src/test/ui/suggestions/into-str.stderr
new file mode 100644
index 00000000000..3e28700ce95
--- /dev/null
+++ b/src/test/ui/suggestions/into-str.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `&str: std::convert::From<std::string::String>` is not satisfied
+  --> $DIR/into-str.rs:4:5
+   |
+LL |     foo(String::new());
+   |     ^^^ the trait `std::convert::From<std::string::String>` is not implemented for `&str`
+   |
+   = note: to coerce a `std::string::String` into a `&str`, use `&*` as a prefix
+   = note: required because of the requirements on the impl of `std::convert::Into<&str>` for `std::string::String`
+note: required by `foo`
+  --> $DIR/into-str.rs:1:1
+   |
+LL | fn foo<'a, T>(_t: T) where T: Into<&'a str> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.