summaryrefslogtreecommitdiffstats
path: root/third_party/rust/void/src
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/void/src')
-rw-r--r--third_party/rust/void/src/lib.rs121
1 files changed, 121 insertions, 0 deletions
diff --git a/third_party/rust/void/src/lib.rs b/third_party/rust/void/src/lib.rs
new file mode 100644
index 0000000000..3b6287c1b2
--- /dev/null
+++ b/third_party/rust/void/src/lib.rs
@@ -0,0 +1,121 @@
+#![cfg_attr(test, deny(warnings))]
+#![deny(missing_docs)]
+#![cfg_attr(not(feature = "std"), no_std)]
+
+//! # Void
+//!
+//! The uninhabited void type for use in statically impossible cases.
+//!
+//! In its own crate so all the users in the ecosystem can share the same type.
+//! This crate also comes ready with several extension traits for Result that add
+//! extra functionality to `Result<T, Void>` and `Result<Void, E>`.
+//!
+
+#[cfg(not(feature = "std"))]
+mod coreprovider {
+ extern crate core;
+ pub use core::{fmt, cmp};
+}
+
+#[cfg(feature = "std")]
+mod coreprovider {
+ pub use std::{fmt, cmp, error};
+}
+
+use coreprovider::*;
+
+/// The empty type for cases which can't occur.
+#[derive(Copy)]
+pub enum Void { }
+
+impl Clone for Void {
+ fn clone(&self) -> Void {
+ unreachable(*self)
+ }
+}
+
+impl fmt::Debug for Void {
+ fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+ unreachable(*self)
+ }
+}
+
+impl fmt::Display for Void {
+ fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+ unreachable(*self)
+ }
+}
+
+impl<T> cmp::PartialEq<T> for Void {
+ fn eq(&self, _: &T) -> bool {
+ unreachable(*self)
+ }
+}
+
+impl<T> cmp::PartialOrd<T> for Void {
+ fn partial_cmp(&self, _: &T) -> Option<cmp::Ordering> {
+ unreachable(*self)
+ }
+}
+
+#[cfg(feature = "std")]
+impl error::Error for Void {
+ fn description(&self) -> &str {
+ unreachable(*self)
+ }
+
+ fn cause(&self) -> Option<&error::Error> {
+ unreachable(*self)
+ }
+}
+
+/// A safe version of `intrinsincs::unreachable`.
+///
+/// If this typechecks, anything that causes this to run is unreachable code.
+///
+/// Calling this function in reachable code invokes undefined behavior, but
+/// should not be possible unless `unsafe` was used elsewhere to construct
+/// an instance of `Void` (which is already undefined behavior).
+#[inline(always)]
+pub fn unreachable(x: Void) -> ! {
+ match x {}
+}
+
+/// Extensions to `Result<T, Void>`
+pub trait ResultVoidExt<T>: Sized {
+ /// Get the value out of a wrapper.
+ fn void_unwrap(self) -> T;
+}
+
+impl<T> ResultVoidExt<T> for Result<T, Void> {
+ /// Get the value out of an always-ok Result.
+ ///
+ /// Never panics, since it is statically known to be Ok.
+ #[inline]
+ fn void_unwrap(self) -> T {
+ match self {
+ Ok(val) => val,
+ Err(e) => unreachable(e)
+ }
+ }
+}
+
+/// Extensions to `Result<Void, E>`
+pub trait ResultVoidErrExt<E>: Sized {
+ /// Get the error out of a wrapper.
+ fn void_unwrap_err(self) -> E;
+}
+
+impl<E> ResultVoidErrExt<E> for Result<Void, E> {
+ /// Get the error out of an always-err Result.
+ ///
+ /// Never panics, since it is statically known to be Err.
+ #[inline]
+ fn void_unwrap_err(self) -> E {
+ match self {
+ Ok(v) => unreachable(v),
+ Err(e) => e
+ }
+ }
+}
+