pub type Never = core::convert::Infallible;
#[inline]
pub fn absurd<A>(never: core::convert::Infallible) -> A {
match never {}
}
#[cfg(test)]
mod tests {
use super::*;
mod never_type {
use super::*;
#[test]
fn never_is_zero_sized() {
assert_eq!(std::mem::size_of::<Never>(), 0);
}
#[test]
fn never_has_no_alignment_requirements() {
assert_eq!(std::mem::align_of::<Never>(), 1);
}
}
mod absurd_function {
use super::*;
#[test]
fn absurd_signature_compiles() {
fn _uses_absurd(n: Never) -> i32 {
absurd(n)
}
fn _uses_absurd_string(n: Never) -> String {
absurd(n)
}
}
#[test]
fn absurd_in_match_arm() {
let result: Result<i32, Never> = Ok(42);
let value = match result {
Ok(v) => v,
Err(never) => absurd(never),
};
assert_eq!(value, 42);
}
}
mod laws {
use super::*;
#[test]
fn never_is_identity_for_either_left() {
let either: Result<i32, Never> = Ok(42);
let value: i32 = match either {
Ok(a) => a,
Err(n) => absurd(n),
};
assert_eq!(value, 42);
}
#[test]
fn result_with_never_error_always_succeeds() {
fn infallible_add(a: i32, b: i32) -> Result<i32, Never> {
Ok(a + b)
}
let result = infallible_add(2, 3);
assert!(result.is_ok());
let value = match result {
Ok(v) => v,
Err(n) => absurd(n),
};
assert_eq!(value, 5);
}
}
mod practical_usage {
use super::*;
use std::convert::Infallible;
#[test]
fn never_is_same_as_infallible() {
fn _takes_infallible(_: Infallible) {}
fn _takes_never(_: Never) {}
fn _coerce(n: Never) -> Infallible {
n
}
fn _coerce_back(i: Infallible) -> Never {
i
}
}
}
}