diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs index b209a9e4a2d..c725e9d0465 100644 --- a/src/libcore/ops/mod.rs +++ b/src/libcore/ops/mod.rs @@ -155,6 +155,7 @@ mod index; mod place; mod range; mod try; +mod unsize; #[stable(feature = "rust1", since = "1.0.0")] pub use self::arith::{Add, Sub, Mul, Div, Rem, Neg}; @@ -190,7 +191,8 @@ pub use self::try::Try; #[unstable(feature = "placement_new_protocol", issue = "27779")] pub use self::place::{Place, Placer, InPlace, Boxed, BoxPlace}; -use marker::Unsize; +#[unstable(feature = "coerce_unsized", issue = "27732")] +pub use self::unsize::CoerceUnsized; /// The `Drop` trait is used to run some code when a value goes out of scope. /// This is sometimes called a 'destructor'. @@ -281,71 +283,3 @@ pub trait Drop { #[stable(feature = "rust1", since = "1.0.0")] fn drop(&mut self); } - -/// 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` -/// by converting from a thin pointer to a fat pointer. -/// -/// For custom types, the coercion here works by coercing `Foo` to `Foo` -/// provided an impl of `CoerceUnsized> for Foo` exists. -/// Such an impl can only be written if `Foo` has only a single non-phantomdata -/// field involving `T`. If the type of that field is `Bar`, an implementation -/// of `CoerceUnsized> for Bar` must exist. The coercion will work by -/// by coercing the `Bar` field into `Bar` and filling in the rest of the fields -/// from `Foo` to create a `Foo`. This will effectively drill down to a pointer -/// field and coerce that. -/// -/// Generally, for smart pointers you will implement -/// `CoerceUnsized> for Ptr where T: Unsize, U: ?Sized`, with an -/// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T` -/// like `Cell` and `RefCell`, you -/// can directly implement `CoerceUnsized> for Wrap where T: CoerceUnsized`. -/// This will let coercions of types like `Cell>` 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 { - // Empty. -} - -// &mut T -> &mut U -#[unstable(feature = "coerce_unsized", issue = "27732")] -impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} -// &mut T -> &U -#[unstable(feature = "coerce_unsized", issue = "27732")] -impl<'a, 'b: 'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} -// &mut T -> *mut U -#[unstable(feature = "coerce_unsized", issue = "27732")] -impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} -// &mut T -> *const U -#[unstable(feature = "coerce_unsized", issue = "27732")] -impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} - -// &T -> &U -#[unstable(feature = "coerce_unsized", issue = "27732")] -impl<'a, 'b: 'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -// &T -> *const U -#[unstable(feature = "coerce_unsized", issue = "27732")] -impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a T {} - -// *mut T -> *mut U -#[unstable(feature = "coerce_unsized", issue = "27732")] -impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} -// *mut T -> *const U -#[unstable(feature = "coerce_unsized", issue = "27732")] -impl, U: ?Sized> CoerceUnsized<*const U> for *mut T {} - -// *const T -> *const U -#[unstable(feature = "coerce_unsized", issue = "27732")] -impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} diff --git a/src/libcore/ops/unsize.rs b/src/libcore/ops/unsize.rs new file mode 100644 index 00000000000..1914216e9f0 --- /dev/null +++ b/src/libcore/ops/unsize.rs @@ -0,0 +1,79 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use marker::Unsize; + +/// 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` +/// by converting from a thin pointer to a fat pointer. +/// +/// For custom types, the coercion here works by coercing `Foo` to `Foo` +/// provided an impl of `CoerceUnsized> for Foo` exists. +/// Such an impl can only be written if `Foo` has only a single non-phantomdata +/// field involving `T`. If the type of that field is `Bar`, an implementation +/// of `CoerceUnsized> for Bar` must exist. The coercion will work by +/// by coercing the `Bar` field into `Bar` and filling in the rest of the fields +/// from `Foo` to create a `Foo`. This will effectively drill down to a pointer +/// field and coerce that. +/// +/// Generally, for smart pointers you will implement +/// `CoerceUnsized> for Ptr where T: Unsize, U: ?Sized`, with an +/// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T` +/// like `Cell` and `RefCell`, you +/// can directly implement `CoerceUnsized> for Wrap where T: CoerceUnsized`. +/// This will let coercions of types like `Cell>` 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 { + // Empty. +} + +// &mut T -> &mut U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} +// &mut T -> &U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, 'b: 'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} +// &mut T -> *mut U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} +// &mut T -> *const U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} + +// &T -> &U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, 'b: 'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +// &T -> *const U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a T {} + +// *mut T -> *mut U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +// *mut T -> *const U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl, U: ?Sized> CoerceUnsized<*const U> for *mut T {} + +// *const T -> *const U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl, U: ?Sized> CoerceUnsized<*const U> for *const T {}