about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2019-02-08 14:54:22 +0100
committerSimon Sapin <simon.sapin@exyr.org>2019-02-13 18:00:18 +0100
commit85f13f0d42fe7ee0a5850a271e8a1c975ad5b85f (patch)
tree82cbf19af07bbd7faa715f8f9406ba972fbd9a27 /src
parente54494727855cd14229f5d456591ed2a2f027c46 (diff)
downloadrust-85f13f0d42fe7ee0a5850a271e8a1c975ad5b85f.tar.gz
rust-85f13f0d42fe7ee0a5850a271e8a1c975ad5b85f.zip
Add a convert::Infallible empty enum, make string::ParseError an alias
Diffstat (limited to 'src')
-rw-r--r--src/liballoc/string.rs37
-rw-r--r--src/libcore/convert.rs93
-rw-r--r--src/libstd/path.rs3
3 files changed, 97 insertions, 36 deletions
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 84c35c6f1bd..b714df5d36b 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -486,7 +486,7 @@ impl String {
     /// [`str::from_utf8`]: ../../std/str/fn.from_utf8.html
     /// [`as_bytes`]: struct.String.html#method.as_bytes
     /// [`FromUtf8Error`]: struct.FromUtf8Error.html
-    /// [`Err`]: ../../stdresult/enum.Result.html#variant.Err
+    /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
@@ -2073,48 +2073,17 @@ impl ops::DerefMut for String {
 /// [`String`]: struct.String.html
 /// [`from_str`]: ../../std/str/trait.FromStr.html#tymethod.from_str
 #[stable(feature = "str_parse_error", since = "1.5.0")]
-#[derive(Copy)]
-pub enum ParseError {}
+pub type ParseError = core::convert::Infallible;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for String {
-    type Err = ParseError;
+    type Err = core::convert::Infallible;
     #[inline]
     fn from_str(s: &str) -> Result<String, ParseError> {
         Ok(String::from(s))
     }
 }
 
-#[stable(feature = "str_parse_error", since = "1.5.0")]
-impl Clone for ParseError {
-    fn clone(&self) -> ParseError {
-        match *self {}
-    }
-}
-
-#[stable(feature = "str_parse_error", since = "1.5.0")]
-impl fmt::Debug for ParseError {
-    fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {}
-    }
-}
-
-#[stable(feature = "str_parse_error2", since = "1.8.0")]
-impl fmt::Display for ParseError {
-    fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {}
-    }
-}
-
-#[stable(feature = "str_parse_error", since = "1.5.0")]
-impl PartialEq for ParseError {
-    fn eq(&self, _: &ParseError) -> bool {
-        match *self {}
-    }
-}
-
-#[stable(feature = "str_parse_error", since = "1.5.0")]
-impl Eq for ParseError {}
 
 /// A trait for converting a value to a `String`.
 ///
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index 4a7c6e15a4d..b31b71aef65 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -499,3 +499,96 @@ impl AsRef<str> for str {
         self
     }
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// THE NO-ERROR ERROR TYPE
+////////////////////////////////////////////////////////////////////////////////
+
+/// The error type for errors that can never happen.
+///
+/// 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`].
+///
+/// For example, the [`TryFrom`] trait (conversion that returns a [`Result`])
+/// has a blanket implementation for all types where a reverse [`Into`] implementation exists.
+///
+/// ```ignore (illustrates std code, duplicating the impl in a doctest would be an error)
+/// impl<T, U> TryFrom<U> for T where U: Into<T> {
+///     type Error = Infallible;
+///
+///     fn try_from(value: U) -> Result<Self, Infallible> {
+///         Ok(U::into(value))  // Never returns `Err`
+///     }
+/// }
+/// ```
+///
+/// # 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 {}
+/// ```
+///
+/// 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
+/// [`TryFrom`]: trait.TryFrom.html
+/// [`Into`]: trait.Into.html
+/// [never]: ../../std/primitive.never.html
+#[stable(feature = "convert_infallible", since = "1.34.0")]
+#[derive(Copy)]
+pub enum Infallible {}
+
+#[stable(feature = "convert_infallible", since = "1.34.0")]
+impl Clone for Infallible {
+    fn clone(&self) -> Infallible {
+        match *self {}
+    }
+}
+
+use fmt;
+
+#[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 {}
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 0f1d627fa1e..d9199666e58 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -78,7 +78,6 @@ use iter::{self, FusedIterator};
 use ops::{self, Deref};
 use rc::Rc;
 use str::FromStr;
-use string::ParseError;
 use sync::Arc;
 
 use ffi::{OsStr, OsString};
@@ -1453,7 +1452,7 @@ impl From<String> for PathBuf {
 
 #[stable(feature = "path_from_str", since = "1.32.0")]
 impl FromStr for PathBuf {
-    type Err = ParseError;
+    type Err = core::convert::Infallible;
 
     fn from_str(s: &str) -> Result<Self, Self::Err> {
         Ok(PathBuf::from(s))