diff options
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/clone.rs | 2 | ||||
| -rw-r--r-- | src/libcore/cmp.rs | 8 | ||||
| -rw-r--r-- | src/libcore/convert/mod.rs | 95 | ||||
| -rw-r--r-- | src/libcore/fmt/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 2 | ||||
| -rw-r--r-- | src/libcore/marker.rs | 2 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 11 |
7 files changed, 108 insertions, 16 deletions
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 6e7a46ba62a..18f808638de 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -195,7 +195,7 @@ mod impls { bool char } - #[stable(feature = "never_type", since = "1.41.0")] + #[unstable(feature = "never_type", issue = "35121")] impl Clone for ! { #[inline] fn clone(&self) -> Self { diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index fd4be02e20f..4aa52a7a390 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -1141,24 +1141,24 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } - #[stable(feature = "never_type", since = "1.41.0")] + #[unstable(feature = "never_type", issue = "35121")] impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } } - #[stable(feature = "never_type", since = "1.41.0")] + #[unstable(feature = "never_type", issue = "35121")] impl Eq for ! {} - #[stable(feature = "never_type", since = "1.41.0")] + #[unstable(feature = "never_type", issue = "35121")] impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option<Ordering> { *self } } - #[stable(feature = "never_type", since = "1.41.0")] + #[unstable(feature = "never_type", issue = "35121")] impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self diff --git a/src/libcore/convert/mod.rs b/src/libcore/convert/mod.rs index cdd994d5fc7..e5599f1dd37 100644 --- a/src/libcore/convert/mod.rs +++ b/src/libcore/convert/mod.rs @@ -40,6 +40,8 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::fmt; + mod num; #[unstable(feature = "convert_float_to_int", issue = "67057")] @@ -430,7 +432,9 @@ pub trait TryInto<T>: Sized { /// - `TryFrom<T> for U` implies [`TryInto`]`<U> for T` /// - [`try_from`] is reflexive, which means that `TryFrom<T> for T` /// is implemented and cannot fail -- the associated `Error` type for -/// calling `T::try_from()` on a value of type `T` is [`!`]. +/// calling `T::try_from()` on a value of type `T` is [`Infallible`]. +/// When the [`!`] type is stabilized [`Infallible`] and [`!`] will be +/// equivalent. /// /// `TryFrom<T>` can be implemented as follows: /// @@ -479,6 +483,7 @@ pub trait TryInto<T>: Sized { /// [`TryInto`]: trait.TryInto.html /// [`i32::MAX`]: ../../std/i32/constant.MAX.html /// [`!`]: ../../std/primitive.never.html +/// [`Infallible`]: enum.Infallible.html #[stable(feature = "try_from", since = "1.34.0")] pub trait TryFrom<T>: Sized { /// The type returned in the event of a conversion error. @@ -634,9 +639,9 @@ impl AsRef<str> for str { // THE NO-ERROR ERROR TYPE //////////////////////////////////////////////////////////////////////////////// -/// A type alias for [the `!` “never” type][never]. +/// The error type for errors that can never happen. /// -/// `Infallible` represents types of errors that can never happen since `!` has no valid values. +/// Since this enum has no variant, a value of this type can never actually exist. /// This can be useful for generic APIs that use [`Result`] and parameterize the error type, /// to indicate that the result is always [`Ok`]. /// @@ -653,10 +658,33 @@ impl AsRef<str> for str { /// } /// ``` /// -/// # Eventual deprecation +/// # Future compatibility +/// +/// This enum has the same role as [the `!` “never” type][never], +/// which is unstable in this version of Rust. +/// When `!` is stabilized, we plan to make `Infallible` a type alias to it: +/// +/// ```ignore (illustrates future std change) +/// pub type Infallible = !; +/// ``` +/// +/// … and eventually deprecate `Infallible`. +/// +/// +/// However there is one case where `!` syntax can be used +/// before `!` is stabilized as a full-fleged type: in the position of a function’s return type. +/// Specifically, it is possible implementations for two different function pointer types: +/// +/// ``` +/// trait MyTrait {} +/// impl MyTrait for fn() -> ! {} +/// impl MyTrait for fn() -> std::convert::Infallible {} +/// ``` /// -/// Previously, `Infallible` was defined as `enum Infallible {}`. -/// Now that it is merely a type alias to `!`, we will eventually deprecate `Infallible`. +/// With `Infallible` being an enum, this code is valid. +/// However when `Infallible` becomes an alias for the never type, +/// the two `impl`s will start to overlap +/// and therefore will be disallowed by the language’s trait coherence rules. /// /// [`Ok`]: ../result/enum.Result.html#variant.Ok /// [`Result`]: ../result/enum.Result.html @@ -664,4 +692,57 @@ impl AsRef<str> for str { /// [`Into`]: trait.Into.html /// [never]: ../../std/primitive.never.html #[stable(feature = "convert_infallible", since = "1.34.0")] -pub type Infallible = !; +#[derive(Copy)] +pub enum Infallible {} + +#[stable(feature = "convert_infallible", since = "1.34.0")] +impl Clone for Infallible { + fn clone(&self) -> Infallible { + match *self {} + } +} + +#[stable(feature = "convert_infallible", since = "1.34.0")] +impl fmt::Debug for Infallible { + fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self {} + } +} + +#[stable(feature = "convert_infallible", since = "1.34.0")] +impl fmt::Display for Infallible { + fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self {} + } +} + +#[stable(feature = "convert_infallible", since = "1.34.0")] +impl PartialEq for Infallible { + fn eq(&self, _: &Infallible) -> bool { + match *self {} + } +} + +#[stable(feature = "convert_infallible", since = "1.34.0")] +impl Eq for Infallible {} + +#[stable(feature = "convert_infallible", since = "1.34.0")] +impl PartialOrd for Infallible { + fn partial_cmp(&self, _other: &Self) -> Option<crate::cmp::Ordering> { + match *self {} + } +} + +#[stable(feature = "convert_infallible", since = "1.34.0")] +impl Ord for Infallible { + fn cmp(&self, _other: &Self) -> crate::cmp::Ordering { + match *self {} + } +} + +#[stable(feature = "convert_infallible", since = "1.34.0")] +impl From<!> for Infallible { + fn from(x: !) -> Self { + x + } +} diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index e2f49ee25a7..223f91d909b 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1940,14 +1940,14 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[stable(feature = "never_type", since = "1.41.0")] +#[unstable(feature = "never_type", issue = "35121")] impl Debug for ! { fn fmt(&self, _: &mut Formatter<'_>) -> Result { *self } } -#[stable(feature = "never_type", since = "1.41.0")] +#[unstable(feature = "never_type", issue = "35121")] impl Display for ! { fn fmt(&self, _: &mut Formatter<'_>) -> Result { *self diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 146d582eb7a..7fe4f7e41a8 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -87,7 +87,7 @@ #![feature(iter_once_with)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] -#![cfg_attr(bootstrap, feature(never_type))] +#![feature(never_type)] #![feature(nll)] #![feature(exhaustive_patterns)] #![feature(no_core)] diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 288017b7ca5..2db55508ad5 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -776,7 +776,7 @@ mod copy_impls { bool char } - #[stable(feature = "never_type", since = "1.41.0")] + #[unstable(feature = "never_type", issue = "35121")] impl Copy for ! {} #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 5a97aa4acfa..88c14dfe7d1 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -4,6 +4,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::convert::Infallible; use crate::fmt; use crate::intrinsics; use crate::mem; @@ -5032,8 +5033,18 @@ impl fmt::Display for TryFromIntError { } #[stable(feature = "try_from", since = "1.34.0")] +impl From<Infallible> for TryFromIntError { + fn from(x: Infallible) -> TryFromIntError { + match x {} + } +} + +#[unstable(feature = "never_type", issue = "35121")] impl From<!> for TryFromIntError { fn from(never: !) -> TryFromIntError { + // Match rather than coerce to make sure that code like + // `From<Infallible> for TryFromIntError` above will keep working + // when `Infallible` becomes an alias to `!`. match never {} } } |
