diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2017-01-03 22:29:15 -0800 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2017-01-04 02:42:10 -0800 |
| commit | 07e844f95fb7894281c08f65f2d127a568525142 (patch) | |
| tree | 3ac737d707e24a1419f08287012fad6e9250cabf /src/libcore | |
| parent | 75f5981d4500e52de767d61ec50a34b97be2a301 (diff) | |
| download | rust-07e844f95fb7894281c08f65f2d127a568525142.tar.gz rust-07e844f95fb7894281c08f65f2d127a568525142.zip | |
Add more docs for CoerceUnsized and Unsize
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/marker.rs | 15 | ||||
| -rw-r--r-- | src/libcore/ops.rs | 29 |
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> { |
