about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2022-06-18 10:03:22 +0900
committerGitHub <noreply@github.com>2022-06-18 10:03:22 +0900
commitfc8027f188141d5d00547ff974f82b441003844d (patch)
treed61b6823672ff5991af62cf54df78139fdc14280
parentc3b7d7b496b5536bb0a3d501222d2d0a8b54a69e (diff)
parent0894660d3ba7b7bfb3114f91d97bb0664598df3c (diff)
downloadrust-fc8027f188141d5d00547ff974f82b441003844d.tar.gz
rust-fc8027f188141d5d00547ff974f82b441003844d.zip
Rollup merge of #97803 - Gankra:term, r=dtolnay
Impl Termination for Infallible and then make the Result impls of Termination more generic

This allows things like `Result<ExitCode, E>` to 'just work'
-rw-r--r--library/std/src/process.rs37
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr9
2 files changed, 18 insertions, 28 deletions
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index e733766741d..da8eee9030b 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -2141,16 +2141,6 @@ impl Termination for () {
 }
 
 #[stable(feature = "termination_trait_lib", since = "1.61.0")]
-impl<E: fmt::Debug> Termination for Result<(), E> {
-    fn report(self) -> ExitCode {
-        match self {
-            Ok(()) => ().report(),
-            Err(err) => Err::<!, _>(err).report(),
-        }
-    }
-}
-
-#[stable(feature = "termination_trait_lib", since = "1.61.0")]
 impl Termination for ! {
     fn report(self) -> ExitCode {
         self
@@ -2158,28 +2148,31 @@ impl Termination for ! {
 }
 
 #[stable(feature = "termination_trait_lib", since = "1.61.0")]
-impl<E: fmt::Debug> Termination for Result<!, E> {
+impl Termination for Infallible {
     fn report(self) -> ExitCode {
-        let Err(err) = self;
-        // Ignore error if the write fails, for example because stderr is
-        // already closed. There is not much point panicking at this point.
-        let _ = writeln!(io::stderr(), "Error: {err:?}");
-        ExitCode::FAILURE
+        match self {}
     }
 }
 
 #[stable(feature = "termination_trait_lib", since = "1.61.0")]
-impl<E: fmt::Debug> Termination for Result<Infallible, E> {
+impl Termination for ExitCode {
+    #[inline]
     fn report(self) -> ExitCode {
-        let Err(err) = self;
-        Err::<!, _>(err).report()
+        self
     }
 }
 
 #[stable(feature = "termination_trait_lib", since = "1.61.0")]
-impl Termination for ExitCode {
-    #[inline]
+impl<T: Termination, E: fmt::Debug> Termination for Result<T, E> {
     fn report(self) -> ExitCode {
-        self
+        match self {
+            Ok(val) => val.report(),
+            Err(err) => {
+                // Ignore error if the write fails, for example because stderr is
+                // already closed. There is not much point panicking at this point.
+                let _ = writeln!(io::stderr(), "Error: {err:?}");
+                ExitCode::FAILURE
+            }
+        }
     }
 }
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 96a899ecca5..6086723b5c4 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -1,4 +1,4 @@
-error[E0277]: `main` has invalid return type `Result<f32, ParseFloatError>`
+error[E0277]: `main` has invalid return type `f32`
   --> $DIR/termination-trait-test-wrong-type.rs:6:1
    |
 LL |   #[test]
@@ -8,11 +8,8 @@ LL | |     "0".parse()
 LL | | }
    | |_^ `main` can only return types that implement `Termination`
    |
-   = help: the trait `Termination` is not implemented for `Result<f32, ParseFloatError>`
-   = help: the following other types implement trait `Termination`:
-             Result<!, E>
-             Result<(), E>
-             Result<Infallible, E>
+   = help: the trait `Termination` is not implemented for `f32`
+   = note: required because of the requirements on the impl of `Termination` for `Result<f32, ParseFloatError>`
 note: required by a bound in `assert_test_result`
   --> $SRC_DIR/test/src/lib.rs:LL:COL
    |