1#![cfg_attr(test, deny(warnings))]
2#![deny(missing_docs)]
3#![cfg_attr(not(feature = "std"), no_std)]
4
5//! # Void
6//!
7//! The uninhabited void type for use in statically impossible cases.
8//!
9//! In its own crate so all the users in the ecosystem can share the same type.
10//! This crate also comes ready with several extension traits for Result that add
11//! extra functionality to `Result<T, Void>` and `Result<Void, E>`.
12//!
13
14#[cfg(not(feature = "std"))]
15mod coreprovider {
16 extern crate core;
17 pub use core::{fmt, cmp};
18}
19
20#[cfg(feature = "std")]
21mod coreprovider {
22 pub use std::{fmt, cmp, error};
23}
24
25use coreprovider::*;
26
27/// The empty type for cases which can't occur.
28#[derive(Copy)]
29pub enum Void { }
30
31impl Clone for Void {
32 fn clone(&self) -> Void {
33 unreachable(*self)
34 }
35}
36
37impl fmt::Debug for Void {
38 fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
39 unreachable(*self)
40 }
41}
42
43impl fmt::Display for Void {
44 fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
45 unreachable(*self)
46 }
47}
48
49impl<T> cmp::PartialEq<T> for Void {
50 fn eq(&self, _: &T) -> bool {
51 unreachable(*self)
52 }
53}
54
55impl<T> cmp::PartialOrd<T> for Void {
56 fn partial_cmp(&self, _: &T) -> Option<cmp::Ordering> {
57 unreachable(*self)
58 }
59}
60
61#[cfg(feature = "std")]
62impl error::Error for Void {
63 fn description(&self) -> &str {
64 unreachable(*self)
65 }
66
67 fn cause(&self) -> Option<&error::Error> {
68 unreachable(*self)
69 }
70}
71
72/// A safe version of `intrinsincs::unreachable`.
73///
74/// If this typechecks, anything that causes this to run is unreachable code.
75///
76/// Calling this function in reachable code invokes undefined behavior, but
77/// should not be possible unless `unsafe` was used elsewhere to construct
78/// an instance of `Void` (which is already undefined behavior).
79#[inline(always)]
80pub fn unreachable(x: Void) -> ! {
81 match x {}
82}
83
84/// Extensions to `Result<T, Void>`
85pub trait ResultVoidExt<T>: Sized {
86 /// Get the value out of a wrapper.
87 fn void_unwrap(self) -> T;
88}
89
90impl<T> ResultVoidExt<T> for Result<T, Void> {
91 /// Get the value out of an always-ok Result.
92 ///
93 /// Never panics, since it is statically known to be Ok.
94 #[inline]
95 fn void_unwrap(self) -> T {
96 match self {
97 Ok(val: T) => val,
98 Err(e: Void) => unreachable(e)
99 }
100 }
101}
102
103/// Extensions to `Result<Void, E>`
104pub trait ResultVoidErrExt<E>: Sized {
105 /// Get the error out of a wrapper.
106 fn void_unwrap_err(self) -> E;
107}
108
109impl<E> ResultVoidErrExt<E> for Result<Void, E> {
110 /// Get the error out of an always-err Result.
111 ///
112 /// Never panics, since it is statically known to be Err.
113 #[inline]
114 fn void_unwrap_err(self) -> E {
115 match self {
116 Ok(v: Void) => unreachable(v),
117 Err(e: E) => e
118 }
119 }
120}
121
122