|
491 | 491 |
|
492 | 492 | use crate::iter::{self, FromIterator, FusedIterator, TrustedLen};
|
493 | 493 | use crate::marker::Destruct;
|
| 494 | +use crate::mem::ManuallyDrop; |
494 | 495 | use crate::ops::{self, ControlFlow, Deref, DerefMut};
|
495 |
| -use crate::{convert, fmt, hint}; |
| 496 | +use crate::{convert, fmt, hint, mem, ptr}; |
496 | 497 |
|
497 | 498 | /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).
|
498 | 499 | ///
|
@@ -1524,6 +1525,14 @@ impl<T, E> Result<T, E> {
|
1524 | 1525 | #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")]
|
1525 | 1526 | pub unsafe fn unwrap_unchecked(self) -> T {
|
1526 | 1527 | debug_assert!(self.is_ok());
|
| 1528 | + // Make things easier for the optimizer when niches are involved |
| 1529 | + if const { mem::size_of::<T>() == mem::size_of::<Self>() } { |
| 1530 | + // SAFETY: Size equality implies niches are involved. And with niches |
| 1531 | + // transmutes are ok because they don't change bits, only make use of invalid values |
| 1532 | + unsafe { |
| 1533 | + return ptr::read(&ManuallyDrop::new(self) as *const _ as *const T); |
| 1534 | + } |
| 1535 | + } |
1527 | 1536 | match self {
|
1528 | 1537 | Ok(t) => t,
|
1529 | 1538 | // SAFETY: the safety contract must be upheld by the caller.
|
@@ -1556,6 +1565,14 @@ impl<T, E> Result<T, E> {
|
1556 | 1565 | #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")]
|
1557 | 1566 | pub unsafe fn unwrap_err_unchecked(self) -> E {
|
1558 | 1567 | debug_assert!(self.is_err());
|
| 1568 | + // Make things easier for the optimizer when niches are involved |
| 1569 | + if const { mem::size_of::<E>() == mem::size_of::<Self>() } { |
| 1570 | + // SAFETY: Size equality implies niches are involved. And with niches |
| 1571 | + // transmutes are ok because they don't change bits, only make use of invalid values |
| 1572 | + unsafe { |
| 1573 | + return ptr::read(&ManuallyDrop::new(self) as *const _ as *const E); |
| 1574 | + } |
| 1575 | + } |
1559 | 1576 | match self {
|
1560 | 1577 | // SAFETY: the safety contract must be upheld by the caller.
|
1561 | 1578 | Ok(_) => unsafe { hint::unreachable_unchecked() },
|
|
0 commit comments