about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/clone.rs2
-rw-r--r--src/libcore/cmp.rs8
-rw-r--r--src/libcore/convert/mod.rs95
-rw-r--r--src/libcore/fmt/mod.rs4
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/libcore/marker.rs2
-rw-r--r--src/libcore/num/mod.rs11
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 {}
     }
 }