Skip to content

Commit 70770e6

Browse files
committed
First code
0 parents  commit 70770e6

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock

Cargo.toml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "unwrap-infallible"
3+
version = "0.1.0"
4+
authors = ["Mikhail Zabaluev <[email protected]>"]
5+
edition = "2018"
6+
7+
[features]
8+
default = []
9+
unstable = ["never_type"]
10+
never_type = []

src/lib.rs

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#![cfg_attr(feature = "never_type", feature(never_type))]
2+
3+
use core::hint::unreachable_unchecked;
4+
5+
#[cfg(not(feature = "never_type"))]
6+
use core::convert::Infallible;
7+
8+
pub trait UnwrapInfallible {
9+
type Ok;
10+
fn unwrap_infallible(self) -> Self::Ok;
11+
}
12+
13+
#[cfg(feature = "never_type")]
14+
impl<T, E: From<!>> UnwrapInfallible for Result<T, E> {
15+
type Ok = T;
16+
fn unwrap_infallible(self) -> T {
17+
self.unwrap_or_else(|_| {
18+
unsafe { unreachable_unchecked() }
19+
})
20+
}
21+
}
22+
23+
#[cfg(not(feature = "never_type"))]
24+
impl<T> UnwrapInfallible for Result<T, Infallible> {
25+
type Ok = T;
26+
fn unwrap_infallible(self) -> T {
27+
self.unwrap_or_else(|_: Infallible| {
28+
unsafe { unreachable_unchecked() }
29+
})
30+
}
31+
}
32+
33+
#[cfg(test)]
34+
mod tests {
35+
use super::UnwrapInfallible;
36+
use core::convert::TryFrom;
37+
use core::hint::unreachable_unchecked;
38+
39+
#[test]
40+
fn with_infallible() {
41+
let a = 42u8;
42+
let a = u64::try_from(a).unwrap_infallible();
43+
assert_eq!(a, 42u64);
44+
}
45+
46+
#[cfg(feature = "never_type")]
47+
#[test]
48+
fn with_never_type() {
49+
let r: Result<bool, !> = Ok(true);
50+
assert!(r.unwrap_infallible());
51+
}
52+
53+
enum MyInfallibleToken {}
54+
55+
#[cfg(feature = "never_type")]
56+
impl From<!> for MyInfallibleToken {
57+
fn from(_: !) -> Self {
58+
unsafe { unreachable_unchecked() }
59+
}
60+
}
61+
62+
#[cfg(not(feature = "never_type"))]
63+
impl<T> UnwrapInfallible for Result<T, MyInfallibleToken> {
64+
type Ok = T;
65+
fn unwrap_infallible(self) -> T {
66+
self.unwrap_or_else(|_| {
67+
unsafe { unreachable_unchecked() }
68+
})
69+
}
70+
}
71+
72+
#[test]
73+
fn with_custom_type() {
74+
let r: Result<bool, MyInfallibleToken> = Ok(true);
75+
assert!(r.unwrap_infallible());
76+
}
77+
}

0 commit comments

Comments
 (0)