about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/std/src/fs.rs12
-rw-r--r--library/std/src/fs/tests.rs2
-rw-r--r--library/std/src/io/error.rs34
-rw-r--r--library/std/src/io/mod.rs2
-rw-r--r--library/std/src/net/tcp/tests.rs2
-rw-r--r--library/std/src/os/wasi/fs.rs2
-rw-r--r--library/std/src/process.rs4
-rw-r--r--library/std/src/sys/hermit/mod.rs2
-rw-r--r--library/std/src/sys/hermit/net.rs43
-rw-r--r--library/std/src/sys/hermit/stdio.rs8
-rw-r--r--library/std/src/sys/hermit/thread.rs2
-rw-r--r--library/std/src/sys/sgx/mod.rs6
-rw-r--r--library/std/src/sys/sgx/net.rs2
-rw-r--r--library/std/src/sys/sgx/stdio.rs2
-rw-r--r--library/std/src/sys/unix/fs.rs2
-rw-r--r--library/std/src/sys/unix/mod.rs2
-rw-r--r--library/std/src/sys/unix/net.rs4
-rw-r--r--library/std/src/sys/unix/os.rs10
-rw-r--r--library/std/src/sys/unsupported/common.rs2
-rw-r--r--library/std/src/sys/wasi/fs.rs4
-rw-r--r--library/std/src/sys/wasi/mod.rs4
-rw-r--r--library/std/src/sys/windows/fs.rs7
-rw-r--r--library/std/src/sys/windows/mod.rs2
-rw-r--r--src/test/ui/write-fmt-errors.rs4
24 files changed, 89 insertions, 75 deletions
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index a1636e2f604..661077a7756 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -880,8 +880,7 @@ impl OpenOptions {
     /// This function will return an error under a number of different
     /// circumstances. Some of these error conditions are listed here, together
     /// with their [`io::ErrorKind`]. The mapping to [`io::ErrorKind`]s is not
-    /// part of the compatibility contract of the function, especially the
-    /// [`Other`] kind might change to more specific kinds in the future.
+    /// part of the compatibility contract of the function.
     ///
     /// * [`NotFound`]: The specified file does not exist and neither `create`
     ///   or `create_new` is set.
@@ -895,9 +894,11 @@ impl OpenOptions {
     ///   exists.
     /// * [`InvalidInput`]: Invalid combinations of open options (truncate
     ///   without write access, no access mode set, etc.).
-    /// * [`Other`]: One of the directory components of the specified file path
+    ///
+    /// The following errors don't match any existing [`io::ErrorKind`] at the moment:
+    /// * One of the directory components of the specified file path
     ///   was not, in fact, a directory.
-    /// * [`Other`]: Filesystem-level errors: full disk, write permission
+    /// * Filesystem-level errors: full disk, write permission
     ///   requested on a read-only file system, exceeded disk quota, too many
     ///   open files, too long filename, too many symbolic links in the
     ///   specified path (Unix-like systems only), etc.
@@ -913,7 +914,6 @@ impl OpenOptions {
     /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists
     /// [`InvalidInput`]: io::ErrorKind::InvalidInput
     /// [`NotFound`]: io::ErrorKind::NotFound
-    /// [`Other`]: io::ErrorKind::Other
     /// [`PermissionDenied`]: io::ErrorKind::PermissionDenied
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
@@ -2190,7 +2190,7 @@ impl DirBuilder {
             Some(p) => self.create_dir_all(p)?,
             None => {
                 return Err(io::Error::new_const(
-                    io::ErrorKind::Other,
+                    io::ErrorKind::Unknown,
                     &"failed to create whole tree",
                 ));
             }
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index ce8d3a56f7a..cc856b4cd45 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1329,7 +1329,7 @@ fn metadata_access_times() {
         match (a.created(), b.created()) {
             (Ok(t1), Ok(t2)) => assert!(t1 <= t2),
             (Err(e1), Err(e2))
-                if e1.kind() == ErrorKind::Other && e2.kind() == ErrorKind::Other
+                if e1.kind() == ErrorKind::Unknown && e2.kind() == ErrorKind::Unknown
                     || e1.kind() == ErrorKind::Unsupported
                         && e2.kind() == ErrorKind::Unsupported => {}
             (a, b) => {
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 56e6f08268c..9eb7e43e284 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -163,14 +163,6 @@ pub enum ErrorKind {
     /// Interrupted operations can typically be retried.
     #[stable(feature = "rust1", since = "1.0.0")]
     Interrupted,
-    /// Any I/O error not part of this list.
-    ///
-    /// Errors that are `Other` now may move to a different or a new
-    /// [`ErrorKind`] variant in the future. It is not recommended to match
-    /// an error against `Other` and to expect any additional characteristics,
-    /// e.g., a specific [`Error::raw_os_error`] return value.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    Other,
 
     /// An error returned when an operation could not be completed because an
     /// "end of file" was reached prematurely.
@@ -180,6 +172,18 @@ pub enum ErrorKind {
     /// read.
     #[stable(feature = "read_exact", since = "1.6.0")]
     UnexpectedEof,
+    /// A custom error that does not fall under any other I/O error kind.
+    ///
+    /// This can be used to construct your own [`Error`]s that do not match any
+    /// [`ErrorKind`].
+    ///
+    /// This [`ErrorKind`] is not used by the standard library.
+    ///
+    /// Errors from the standard library that do not fall under any of the I/O
+    /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
+    /// New [`ErrorKind`]s might be added in the future for some of those.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Other,
 
     /// This operation is unsupported on this platform.
     ///
@@ -191,6 +195,15 @@ pub enum ErrorKind {
     /// to allocate enough memory.
     #[stable(feature = "out_of_memory_error", since = "1.54.0")]
     OutOfMemory,
+
+    /// Any I/O error from the standard library that's not part of this list.
+    ///
+    /// Errors that are `Unknown` now may move to a different or a new
+    /// [`ErrorKind`] variant in the future. It is not recommended to match
+    /// an error against `Unknown`; use a wildcard match (`_`) instead.
+    #[unstable(feature = "io_error_unknown", issue = "none")]
+    #[doc(hidden)]
+    Unknown,
 }
 
 impl ErrorKind {
@@ -212,10 +225,11 @@ impl ErrorKind {
             ErrorKind::TimedOut => "timed out",
             ErrorKind::WriteZero => "write zero",
             ErrorKind::Interrupted => "operation interrupted",
-            ErrorKind::Other => "other os error",
             ErrorKind::UnexpectedEof => "unexpected end of file",
             ErrorKind::Unsupported => "unsupported",
             ErrorKind::OutOfMemory => "out of memory",
+            ErrorKind::Other => "other error",
+            ErrorKind::Unknown => "other os error",
         }
     }
 }
@@ -538,7 +552,7 @@ impl Error {
     /// }
     ///
     /// fn main() {
-    ///     // Will print "Other".
+    ///     // Will print "Unknown".
     ///     print_error(Error::last_os_error());
     ///     // Will print "AddrInUse".
     ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 4c154dbe01a..4a605e4928b 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1592,7 +1592,7 @@ pub trait Write {
                 if output.error.is_err() {
                     output.error
                 } else {
-                    Err(Error::new_const(ErrorKind::Other, &"formatter error"))
+                    Err(Error::new_const(ErrorKind::Unknown, &"formatter error"))
                 }
             }
         }
diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs
index abe9bc24cec..a664a335462 100644
--- a/library/std/src/net/tcp/tests.rs
+++ b/library/std/src/net/tcp/tests.rs
@@ -342,7 +342,7 @@ fn double_bind() {
             Err(e) => {
                 assert!(
                     e.kind() == ErrorKind::ConnectionRefused
-                        || e.kind() == ErrorKind::Other
+                        || e.kind() == ErrorKind::Unknown
                         || e.kind() == ErrorKind::AddrInUse,
                     "unknown error: {} {:?}",
                     e,
diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs
index ba4057bd34c..b47dbacee68 100644
--- a/library/std/src/os/wasi/fs.rs
+++ b/library/std/src/os/wasi/fs.rs
@@ -532,5 +532,5 @@ pub fn symlink_path<P: AsRef<Path>, U: AsRef<Path>>(old_path: P, new_path: U) ->
 }
 
 fn osstr2str(f: &OsStr) -> io::Result<&str> {
-    f.to_str().ok_or_else(|| io::Error::new_const(io::ErrorKind::Other, &"input must be utf-8"))
+    f.to_str().ok_or_else(|| io::Error::new_const(io::ErrorKind::Unknown, &"input must be utf-8"))
 }
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 6903ba90560..675ba5f62e4 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1658,8 +1658,7 @@ impl Child {
     /// Forces the child process to exit. If the child has already exited, an [`InvalidInput`]
     /// error is returned.
     ///
-    /// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function,
-    /// especially the [`Other`] kind might change to more specific kinds in the future.
+    /// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function.
     ///
     /// This is equivalent to sending a SIGKILL on Unix platforms.
     ///
@@ -1680,7 +1679,6 @@ impl Child {
     ///
     /// [`ErrorKind`]: io::ErrorKind
     /// [`InvalidInput`]: io::ErrorKind::InvalidInput
-    /// [`Other`]: io::ErrorKind::Other
     #[stable(feature = "process", since = "1.0.0")]
     pub fn kill(&mut self) -> io::Result<()> {
         self.handle.kill()
diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs
index 15a76bbd2c9..70a0a8abc32 100644
--- a/library/std/src/sys/hermit/mod.rs
+++ b/library/std/src/sys/hermit/mod.rs
@@ -149,7 +149,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         x if x == 1 as i32 => ErrorKind::PermissionDenied,
         x if x == 32 as i32 => ErrorKind::BrokenPipe,
         x if x == 110 as i32 => ErrorKind::TimedOut,
-        _ => ErrorKind::Other,
+        _ => ErrorKind::Unknown,
     }
 }
 
diff --git a/library/std/src/sys/hermit/net.rs b/library/std/src/sys/hermit/net.rs
index 5f8839157ea..57c93e2edb3 100644
--- a/library/std/src/sys/hermit/net.rs
+++ b/library/std/src/sys/hermit/net.rs
@@ -15,7 +15,7 @@ use crate::time::Duration;
 pub fn init() -> io::Result<()> {
     if abi::network_init() < 0 {
         return Err(io::Error::new_const(
-            ErrorKind::Other,
+            ErrorKind::Unknown,
             &"Unable to initialize network interface",
         ));
     }
@@ -51,7 +51,7 @@ impl TcpStream {
         match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
             Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
             _ => Err(io::Error::new_const(
-                ErrorKind::Other,
+                ErrorKind::Unknown,
                 &"Unable to initiate a connection on a socket",
             )),
         }
@@ -65,7 +65,7 @@ impl TcpStream {
         ) {
             Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
             _ => Err(io::Error::new_const(
-                ErrorKind::Other,
+                ErrorKind::Unknown,
                 &"Unable to initiate a connection on a socket",
             )),
         }
@@ -73,7 +73,7 @@ impl TcpStream {
 
     pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
         abi::tcpstream::set_read_timeout(*self.0.as_inner(), duration.map(|d| d.as_millis() as u64))
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"Unable to set timeout value"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"Unable to set timeout value"))
     }
 
     pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
@@ -81,12 +81,12 @@ impl TcpStream {
             *self.0.as_inner(),
             duration.map(|d| d.as_millis() as u64),
         )
-        .map_err(|_| io::Error::new_const(ErrorKind::Other, &"Unable to set timeout value"))
+        .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"Unable to set timeout value"))
     }
 
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
         let duration = abi::tcpstream::get_read_timeout(*self.0.as_inner()).map_err(|_| {
-            io::Error::new_const(ErrorKind::Other, &"Unable to determine timeout value")
+            io::Error::new_const(ErrorKind::Unknown, &"Unable to determine timeout value")
         })?;
 
         Ok(duration.map(|d| Duration::from_millis(d)))
@@ -94,7 +94,7 @@ impl TcpStream {
 
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
         let duration = abi::tcpstream::get_write_timeout(*self.0.as_inner()).map_err(|_| {
-            io::Error::new_const(ErrorKind::Other, &"Unable to determine timeout value")
+            io::Error::new_const(ErrorKind::Unknown, &"Unable to determine timeout value")
         })?;
 
         Ok(duration.map(|d| Duration::from_millis(d)))
@@ -102,7 +102,7 @@ impl TcpStream {
 
     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
         abi::tcpstream::peek(*self.0.as_inner(), buf)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"set_nodelay failed"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"set_nodelay failed"))
     }
 
     pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
@@ -113,8 +113,9 @@ impl TcpStream {
         let mut size: usize = 0;
 
         for i in ioslice.iter_mut() {
-            let ret = abi::tcpstream::read(*self.0.as_inner(), &mut i[0..])
-                .map_err(|_| io::Error::new_const(ErrorKind::Other, &"Unable to read on socket"))?;
+            let ret = abi::tcpstream::read(*self.0.as_inner(), &mut i[0..]).map_err(|_| {
+                io::Error::new_const(ErrorKind::Unknown, &"Unable to read on socket")
+            })?;
 
             if ret != 0 {
                 size += ret;
@@ -138,7 +139,7 @@ impl TcpStream {
 
         for i in ioslice.iter() {
             size += abi::tcpstream::write(*self.0.as_inner(), i).map_err(|_| {
-                io::Error::new_const(ErrorKind::Other, &"Unable to write on socket")
+                io::Error::new_const(ErrorKind::Unknown, &"Unable to write on socket")
             })?;
         }
 
@@ -152,13 +153,13 @@ impl TcpStream {
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         let (ipaddr, port) = abi::tcpstream::peer_addr(*self.0.as_inner())
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"peer_addr failed"))?;
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"peer_addr failed"))?;
 
         let saddr = match ipaddr {
             Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
             Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
             _ => {
-                return Err(io::Error::new_const(ErrorKind::Other, &"peer_addr failed"));
+                return Err(io::Error::new_const(ErrorKind::Unknown, &"peer_addr failed"));
             }
         };
 
@@ -171,7 +172,7 @@ impl TcpStream {
 
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         abi::tcpstream::shutdown(*self.0.as_inner(), how as i32)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"unable to shutdown socket"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"unable to shutdown socket"))
     }
 
     pub fn duplicate(&self) -> io::Result<TcpStream> {
@@ -180,22 +181,22 @@ impl TcpStream {
 
     pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
         abi::tcpstream::set_nodelay(*self.0.as_inner(), mode)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"set_nodelay failed"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"set_nodelay failed"))
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
         abi::tcpstream::nodelay(*self.0.as_inner())
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"nodelay failed"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"nodelay failed"))
     }
 
     pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
         abi::tcpstream::set_tll(*self.0.as_inner(), tll)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"unable to set TTL"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"unable to set TTL"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
         abi::tcpstream::get_tll(*self.0.as_inner())
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"unable to get TTL"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"unable to get TTL"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
@@ -204,7 +205,7 @@ impl TcpStream {
 
     pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
         abi::tcpstream::set_nonblocking(*self.0.as_inner(), mode)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"unable to set blocking mode"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"unable to set blocking mode"))
     }
 }
 
@@ -230,12 +231,12 @@ impl TcpListener {
 
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
         let (handle, ipaddr, port) = abi::tcplistener::accept(self.0.port())
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"accept failed"))?;
+            .map_err(|_| io::Error::new_const(ErrorKind::Unknown, &"accept failed"))?;
         let saddr = match ipaddr {
             Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
             Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
             _ => {
-                return Err(io::Error::new_const(ErrorKind::Other, &"accept failed"));
+                return Err(io::Error::new_const(ErrorKind::Unknown, &"accept failed"));
             }
         };
 
diff --git a/library/std/src/sys/hermit/stdio.rs b/library/std/src/sys/hermit/stdio.rs
index 6bff13ca92c..e3c3912fc58 100644
--- a/library/std/src/sys/hermit/stdio.rs
+++ b/library/std/src/sys/hermit/stdio.rs
@@ -40,7 +40,7 @@ impl io::Write for Stdout {
         unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
 
         if len < 0 {
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Stdout is not able to print"))
+            Err(io::Error::new_const(io::ErrorKind::Unknown, &"Stdout is not able to print"))
         } else {
             Ok(len as usize)
         }
@@ -52,7 +52,7 @@ impl io::Write for Stdout {
         unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
 
         if len < 0 {
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Stdout is not able to print"))
+            Err(io::Error::new_const(io::ErrorKind::Unknown, &"Stdout is not able to print"))
         } else {
             Ok(len as usize)
         }
@@ -81,7 +81,7 @@ impl io::Write for Stderr {
         unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
 
         if len < 0 {
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Stderr is not able to print"))
+            Err(io::Error::new_const(io::ErrorKind::Unknown, &"Stderr is not able to print"))
         } else {
             Ok(len as usize)
         }
@@ -93,7 +93,7 @@ impl io::Write for Stderr {
         unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
 
         if len < 0 {
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Stderr is not able to print"))
+            Err(io::Error::new_const(io::ErrorKind::Unknown, &"Stderr is not able to print"))
         } else {
             Ok(len as usize)
         }
diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs
index f35a3a8a80f..2c5d218dc28 100644
--- a/library/std/src/sys/hermit/thread.rs
+++ b/library/std/src/sys/hermit/thread.rs
@@ -37,7 +37,7 @@ impl Thread {
             // The thread failed to start and as a result p was not consumed. Therefore, it is
             // safe to reconstruct the box so that it gets deallocated.
             drop(Box::from_raw(p));
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Unable to create thread!"))
+            Err(io::Error::new_const(io::ErrorKind::Unknown, &"Unable to create thread!"))
         } else {
             Ok(Thread { tid: tid })
         };
diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs
index cdfceca19fc..ae7b98281a3 100644
--- a/library/std/src/sys/sgx/mod.rs
+++ b/library/std/src/sys/sgx/mod.rs
@@ -70,7 +70,7 @@ pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
     static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
     if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
         Err(crate::io::Error::new_const(
-            ErrorKind::Other,
+            ErrorKind::Unknown,
             &"operation can't be trusted to have any effect on SGX",
         ))
     } else {
@@ -115,11 +115,11 @@ pub fn decode_error_kind(code: i32) -> ErrorKind {
     } else if code == Error::Interrupted as _ {
         ErrorKind::Interrupted
     } else if code == Error::Other as _ {
-        ErrorKind::Other
+        ErrorKind::Unknown
     } else if code == Error::UnexpectedEof as _ {
         ErrorKind::UnexpectedEof
     } else {
-        ErrorKind::Other
+        ErrorKind::Unknown
     }
 }
 
diff --git a/library/std/src/sys/sgx/net.rs b/library/std/src/sys/sgx/net.rs
index 5ccedece0f8..b2b5972eb41 100644
--- a/library/std/src/sys/sgx/net.rs
+++ b/library/std/src/sys/sgx/net.rs
@@ -466,7 +466,7 @@ pub struct LookupHost(!);
 
 impl LookupHost {
     fn new(host: String) -> io::Result<LookupHost> {
-        Err(io::Error::new(io::ErrorKind::Other, NonIpSockAddr { host }))
+        Err(io::Error::new(io::ErrorKind::Unknown, NonIpSockAddr { host }))
     }
 
     pub fn port(&self) -> u16 {
diff --git a/library/std/src/sys/sgx/stdio.rs b/library/std/src/sys/sgx/stdio.rs
index 548e28a43d6..f9e3d83be43 100644
--- a/library/std/src/sys/sgx/stdio.rs
+++ b/library/std/src/sys/sgx/stdio.rs
@@ -65,7 +65,7 @@ impl io::Write for Stderr {
 pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
 
 pub fn is_ebadf(err: &io::Error) -> bool {
-    // FIXME: Rust normally maps Unix EBADF to `Other`
+    // FIXME: Rust normally maps Unix EBADF to `Unknown`
     err.raw_os_error() == Some(abi::Error::BrokenPipe as _)
 }
 
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index f8ca67c844c..ed0ba7cf3ee 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -358,7 +358,7 @@ impl FileAttr {
                     }))
                 } else {
                     Err(io::Error::new_const(
-                        io::ErrorKind::Other,
+                        io::ErrorKind::Unknown,
                         &"creation time is not available for the filesystem",
                     ))
                 };
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index 57d91441b6f..ae16ea07f24 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -155,7 +155,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         // clause
         x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => ErrorKind::WouldBlock,
 
-        _ => ErrorKind::Other,
+        _ => ErrorKind::Unknown,
     }
 }
 
diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs
index e6b61062d15..9db670408c3 100644
--- a/library/std/src/sys/unix/net.rs
+++ b/library/std/src/sys/unix/net.rs
@@ -38,7 +38,7 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
         str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap().to_owned()
     };
     Err(io::Error::new(
-        io::ErrorKind::Other,
+        io::ErrorKind::Unknown,
         &format!("failed to lookup address information: {}", detail)[..],
     ))
 }
@@ -178,7 +178,7 @@ impl Socket {
                     if pollfd.revents & libc::POLLHUP != 0 {
                         let e = self.take_error()?.unwrap_or_else(|| {
                             io::Error::new_const(
-                                io::ErrorKind::Other,
+                                io::ErrorKind::Unknown,
                                 &"no error set after POLLHUP",
                             )
                         });
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index bbc4691d963..f0fc1f60580 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -280,7 +280,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
             ))?;
             if path_len <= 1 {
                 return Err(io::Error::new_const(
-                    io::ErrorKind::Other,
+                    io::ErrorKind::Unknown,
                     &"KERN_PROC_PATHNAME sysctl returned zero-length string",
                 ));
             }
@@ -303,7 +303,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
             return crate::fs::read_link(curproc_exe);
         }
         Err(io::Error::new_const(
-            io::ErrorKind::Other,
+            io::ErrorKind::Unknown,
             &"/proc/curproc/exe doesn't point to regular file.",
         ))
     }
@@ -321,7 +321,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
         cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_len, ptr::null_mut(), 0))?;
         argv.set_len(argv_len as usize);
         if argv[0].is_null() {
-            return Err(io::Error::new_const(io::ErrorKind::Other, &"no current exe available"));
+            return Err(io::Error::new_const(io::ErrorKind::Unknown, &"no current exe available"));
         }
         let argv0 = CStr::from_ptr(argv[0]).to_bytes();
         if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') {
@@ -336,7 +336,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 pub fn current_exe() -> io::Result<PathBuf> {
     match crate::fs::read_link("/proc/self/exe") {
         Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::Error::new_const(
-            io::ErrorKind::Other,
+            io::ErrorKind::Unknown,
             &"no /proc/self/exe available. Is /proc mounted?",
         )),
         other => other,
@@ -423,7 +423,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
             _get_next_image_info(0, &mut cookie, &mut info, mem::size_of::<image_info>() as i32);
         if result != 0 {
             use crate::io::ErrorKind;
-            Err(io::Error::new_const(ErrorKind::Other, &"Error getting executable path"))
+            Err(io::Error::new_const(ErrorKind::Unknown, &"Error getting executable path"))
         } else {
             let name = CStr::from_ptr(info.name.as_ptr()).to_bytes();
             Ok(PathBuf::from(OsStr::from_bytes(name)))
diff --git a/library/std/src/sys/unsupported/common.rs b/library/std/src/sys/unsupported/common.rs
index 6e72a7c632e..523185f9c8f 100644
--- a/library/std/src/sys/unsupported/common.rs
+++ b/library/std/src/sys/unsupported/common.rs
@@ -30,7 +30,7 @@ pub fn unsupported_err() -> std_io::Error {
 }
 
 pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
-    crate::io::ErrorKind::Other
+    crate::io::ErrorKind::Unknown
 }
 
 pub fn abort_internal() -> ! {
diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs
index 45e38f68b8c..75eaa8446a3 100644
--- a/library/std/src/sys/wasi/fs.rs
+++ b/library/std/src/sys/wasi/fs.rs
@@ -648,7 +648,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
                      through which {:?} could be opened",
                     p
                 );
-                return Err(io::Error::new(io::ErrorKind::Other, msg));
+                return Err(io::Error::new(io::ErrorKind::Unknown, msg));
             }
             let relative = CStr::from_ptr(relative_path).to_bytes().to_vec();
 
@@ -670,7 +670,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
 }
 
 pub fn osstr2str(f: &OsStr) -> io::Result<&str> {
-    f.to_str().ok_or_else(|| io::Error::new_const(io::ErrorKind::Other, &"input must be utf-8"))
+    f.to_str().ok_or_else(|| io::Error::new_const(io::ErrorKind::Unknown, &"input must be utf-8"))
 }
 
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs
index 45a829c0cd2..17107213181 100644
--- a/library/std/src/sys/wasi/mod.rs
+++ b/library/std/src/sys/wasi/mod.rs
@@ -58,7 +58,7 @@ pub use common::*;
 pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
     use std_io::ErrorKind::*;
     if errno > u16::MAX as i32 || errno < 0 {
-        return Other;
+        return Unknown;
     }
     match errno as u16 {
         wasi::ERRNO_CONNREFUSED => ConnectionRefused,
@@ -77,7 +77,7 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
         wasi::ERRNO_AGAIN => WouldBlock,
         wasi::ERRNO_NOSYS => Unsupported,
         wasi::ERRNO_NOMEM => OutOfMemory,
-        _ => Other,
+        _ => Unknown,
     }
 }
 
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index 2b6143de960..1f3fb6f0c24 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -514,7 +514,7 @@ impl File {
                 }
                 _ => {
                     return Err(io::Error::new_const(
-                        io::ErrorKind::Other,
+                        io::ErrorKind::Unknown,
                         &"Unsupported reparse point type",
                     ));
                 }
@@ -961,9 +961,8 @@ pub fn try_exists(path: &Path) -> io::Result<bool> {
             // `ERROR_SHARING_VIOLATION` means that the file has been locked by
             // another process. This is often temporary so we simply report it
             // as the file existing.
-            io::ErrorKind::Other if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as i32) => {
-                Ok(true)
-            }
+            _ if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as i32) => Ok(true),
+
             // Other errors such as `ERROR_ACCESS_DENIED` may indicate that the
             // file exists. However, these types of errors are usually more
             // permanent so we report them here.
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index f23e874f249..5e857af85c1 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -103,7 +103,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         c::WSAEWOULDBLOCK => ErrorKind::WouldBlock,
         c::WSAETIMEDOUT => ErrorKind::TimedOut,
 
-        _ => ErrorKind::Other,
+        _ => ErrorKind::Unknown,
     }
 }
 
diff --git a/src/test/ui/write-fmt-errors.rs b/src/test/ui/write-fmt-errors.rs
index 7dd98564425..afbe4e3b2ce 100644
--- a/src/test/ui/write-fmt-errors.rs
+++ b/src/test/ui/write-fmt-errors.rs
@@ -1,5 +1,7 @@
 // run-pass
 
+#![feature(io_error_unknown)]
+
 use std::fmt;
 use std::io::{self, Error, Write, sink};
 
@@ -13,7 +15,7 @@ impl fmt::Display for ErrorDisplay {
 
 struct ErrorWriter;
 
-const FORMAT_ERROR: io::ErrorKind = io::ErrorKind::Other;
+const FORMAT_ERROR: io::ErrorKind = io::ErrorKind::Unknown;
 const WRITER_ERROR: io::ErrorKind = io::ErrorKind::NotConnected;
 
 impl Write for ErrorWriter {