about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNatalie Boehm <nmb56@pitt.edu>2017-08-04 12:25:05 -0400
committerGitHub <noreply@github.com>2017-08-04 12:25:05 -0400
commitb298a58c782f1434b09d4aaea6bffd4f99d3e7f6 (patch)
treefb8297a2ba213dccf8ce93296f2c714cb1f0a35d /src
parentf2a5af7a4c7424acc9acc52161fb57210a4bb219 (diff)
downloadrust-b298a58c782f1434b09d4aaea6bffd4f99d3e7f6.tar.gz
rust-b298a58c782f1434b09d4aaea6bffd4f99d3e7f6.zip
Update String Deref to explain why using &String does not always work
Diffstat (limited to 'src')
-rw-r--r--src/liballoc/string.rs27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 622cc68964b..110699c1e03 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -144,7 +144,7 @@ use boxed::Box;
 /// # Deref
 ///
 /// `String`s implement [`Deref`]`<Target=str>`, and so inherit all of [`str`]'s
-/// methods. In addition, this means that you can pass a `String` to any
+/// methods. In addition, this means that you can pass a `String` to a
 /// function which takes a [`&str`] by using an ampersand (`&`):
 ///
 /// ```
@@ -160,8 +160,31 @@ use boxed::Box;
 ///
 /// This will create a [`&str`] from the `String` and pass it in. This
 /// conversion is very inexpensive, and so generally, functions will accept
-/// [`&str`]s as arguments unless they need a `String` for some specific reason.
+/// [`&str`]s as arguments unless they need a `String` for some specific
+/// reason.
 ///
+/// In certain cases Rust doesn't have enough information to make this conversion,
+/// known as deref coercion. For example, in this case a string slice implements
+/// a trait and the function takes anything that implements the trait, Rust would
+/// need to make two implicit conversions which Rust doesn't know how to do. The
+/// following example will not compile for that reason.
+///
+/// ```compile_fail,E0277
+/// trait TraitExample {}
+///
+/// impl<'a> TraitExample for &'a str {}
+///
+/// fn example_func<A: TraitExample>(example_arg: A) {}
+///
+/// fn main() {
+///     let example_string = String::from("example_string");
+///     example_func(&example_string);
+/// }
+/// ```
+///
+/// What would work in this case is changing the line `example_func(&example_string);`
+/// to `example_func(example_string.to_str());`. This works because we're doing the
+/// conversion explicitly, rather than relying on the implicit conversion.
 ///
 /// # Representation
 ///