about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2017-01-03 22:29:15 -0800
committerManish Goregaokar <manishsmail@gmail.com>2017-01-04 02:42:10 -0800
commit07e844f95fb7894281c08f65f2d127a568525142 (patch)
tree3ac737d707e24a1419f08287012fad6e9250cabf /src/libcore
parent75f5981d4500e52de767d61ec50a34b97be2a301 (diff)
downloadrust-07e844f95fb7894281c08f65f2d127a568525142.tar.gz
rust-07e844f95fb7894281c08f65f2d127a568525142.zip
Add more docs for CoerceUnsized and Unsize
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/marker.rs15
-rw-r--r--src/libcore/ops.rs29
2 files changed, 43 insertions, 1 deletions
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 9af10966eda..a9e2bff5906 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -100,13 +100,26 @@ pub trait Sized {
 ///
 /// All implementations of `Unsize` are provided automatically by the compiler.
 ///
+/// `Unsize` is implemented for:
+///
+/// - `[T; N]` is `Unsize<[T]>`
+/// - `T` is `Unsize<Trait>` when `T: Trait`
+/// - `Foo<..., T, ...>` is `Unsize<Foo<..., U, ...>>` if:
+///   - `T: Unsize<U>`
+///   - Foo is a struct
+///   - Only the last field of `Foo` has a type involving `T`
+///   - `T` is not part of the type of any other fields
+///   - `Bar<T>: Unsize<Bar<U>>`, if the last field of `Foo` has type `Bar<T>`
+///
 /// `Unsize` is used along with [`ops::CoerceUnsized`][coerceunsized] to allow
 /// "user-defined" containers such as [`rc::Rc`][rc] to contain dynamically-sized
-/// types. See the [DST coercion RFC][RFC982] for more details.
+/// types. See the [DST coercion RFC][RFC982] and [the nomicon entry on coercion][nomicon-coerce]
+/// for more details.
 ///
 /// [coerceunsized]: ../ops/trait.CoerceUnsized.html
 /// [rc]: ../../std/rc/struct.Rc.html
 /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
+
 #[unstable(feature = "unsize", issue = "27732")]
 #[lang="unsize"]
 pub trait Unsize<T: ?Sized> {
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 07ae5b920b2..74771954333 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -2649,6 +2649,35 @@ mod impls {
 
 /// Trait that indicates that this is a pointer or a wrapper for one,
 /// where unsizing can be performed on the pointee.
+///
+/// See the [DST coercion RfC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce]
+/// for more details.
+///
+/// For builtin pointer types, pointers to `T` will coerce to pointers to `U` if `T: Unsize<U>`
+/// by converting from a thin pointer to a fat pointer.
+///
+/// For custom types, the coercion here works by coercing `Foo<T>` to `Foo<U>`
+/// provided an impl of `CoerceUnsized<Foo<U>> for Foo<T>` exists.
+/// Such an impl can only be written if `Foo<T>` has only a single non-phantomdata
+/// field involving `T`. If the type of that field is `Bar<T>`, an implementation
+/// of `CoerceUnsized<Bar<U>> for Bar<T>` must exist. The coercion will work by
+/// by coercing the `Bar<T>` field into `Bar<U>` and filling in the rest of the fields
+/// from `Foo<T>` to create a `Foo<U>`. This will effectively drill down to a pointer
+/// field and coerce that.
+///
+/// Generally, for smart pointers you will implement
+/// `CoerceUnsized<Ptr<U>> for Ptr<T> where T: Unsize<U>, U: ?Sized`, with an
+/// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T`
+/// like `Cell<T>` and `RefCell<T>`, you
+/// can directly implement `CoerceUnsized<Wrap<U>> for Wrap<T> where T: CoerceUnsized<U>`.
+/// This will let coercions of types like `Cell<Box<T>>` work.
+///
+/// [`Unsize`][unsize] is used to mark types which can be coerced to DSTs if behind
+/// pointers. It is implemented automatically by the compiler.
+///
+/// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
+/// [unsize]: ../marker/trait.Unsize.html
+/// [nomicon-coerce]: ../../nomicon/coercions.html
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 #[lang="coerce_unsized"]
 pub trait CoerceUnsized<T> {