about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-08-11 09:55:13 -0700
committerAlex Crichton <alex@alexcrichton.com>2017-08-11 09:55:13 -0700
commit3971a3d55ce6572f446e90946b13d0923052d735 (patch)
tree137e3bdf715c224575b083949d138eae58c4173e /src/liballoc
parent2b04afba632711eb205574ad03d086efdd4d11e0 (diff)
parent38bdbb7cf9bebcc4b6331644f52f9d6e52754782 (diff)
downloadrust-3971a3d55ce6572f446e90946b13d0923052d735.tar.gz
rust-3971a3d55ce6572f446e90946b13d0923052d735.zip
Merge remote-tracking branch 'origin/master' into gen
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/arc.rs2
-rw-r--r--src/liballoc/string.rs34
2 files changed, 33 insertions, 3 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 9e314251934..daf556795fa 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -95,7 +95,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
 /// # Cloning references
 ///
 /// Creating a new reference from an existing reference counted pointer is done using the
-/// `Clone` trait implemented for [`Arc<T>`][`arc`] and [`Weak<T>`][`weak`].
+/// `Clone` trait implemented for [`Arc<T>`][arc] and [`Weak<T>`][weak].
 ///
 /// ```
 /// use std::sync::Arc;
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 622cc68964b..322b137e99f 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,38 @@ 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. In the following example a string
+/// slice `&'a str` implements the trait `TraitExample`, and the function
+/// `example_func` takes anything that implements the trait. In this case Rust
+/// would need to make two implicit conversions, which Rust doesn't have the
+/// means to do. For that reason, the following example will not compile.
+///
+/// ```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);
+/// }
+/// ```
+///
+/// There are two options that would work instead. The first would be to
+/// change the line `example_func(&example_string);` to
+/// `example_func(example_string.as_str());`, using the method `as_str()`
+/// to explicitly extract the string slice containing the string. The second
+/// way changes `example_func(&example_string);` to
+/// `example_func(&*example_string);`. In this case we are dereferencing a
+/// `String` to a `str`, then referencing the `str` back to `&str`. The
+/// second way is more idiomatic, however both work to do the conversion
+/// explicitly rather than relying on the implicit conversion.
 ///
 /// # Representation
 ///