|
1 | 1 | //! impl bool {} |
2 | 2 |
|
| 3 | +use crate::intrinsics; |
| 4 | +use crate::ub_checks::assert_unsafe_precondition; |
| 5 | + |
3 | 6 | impl bool { |
4 | 7 | /// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html), |
5 | 8 | /// or `None` otherwise. |
@@ -128,4 +131,46 @@ impl bool { |
128 | 131 | pub fn ok_or_else<E, F: FnOnce() -> E>(self, f: F) -> Result<(), E> { |
129 | 132 | if self { Ok(()) } else { Err(f()) } |
130 | 133 | } |
| 134 | + |
| 135 | + /// Same value as `self | other`, but UB if any bit position is set in both inputs. |
| 136 | + /// |
| 137 | + /// This is a situational micro-optimization for places where you'd rather |
| 138 | + /// use addition on some platforms and bitwise or on other platforms, based |
| 139 | + /// on exactly which instructions combine better with whatever else you're |
| 140 | + /// doing. Note that there's no reason to bother using this for places |
| 141 | + /// where it's clear from the operations involved that they can't overlap. |
| 142 | + /// For example, if you're combining `u16`s into a `u32` with |
| 143 | + /// `((a as u32) << 16) | (b as u32)`, that's fine, as the backend will |
| 144 | + /// know those sides of the `|` are disjoint without needing help. |
| 145 | + /// |
| 146 | + /// # Examples |
| 147 | + /// |
| 148 | + /// ``` |
| 149 | + /// #![feature(disjoint_bitor)] |
| 150 | + /// |
| 151 | + /// // SAFETY: `false` and `true` have no bits in common. |
| 152 | + /// unsafe { false.unchecked_disjoint_bitor(true) } |
| 153 | + /// ``` |
| 154 | + /// |
| 155 | + /// # Safety |
| 156 | + /// |
| 157 | + /// Requires that `self` and `rhs` are disjoint to each other, i.e. do not |
| 158 | + /// have overlapping ones (thus `self & rhs == false`). By extension, requires |
| 159 | + /// that `self | rhs`, `self + rhs`, and `self ^ rhs` are equivalent. |
| 160 | + #[unstable(feature = "disjoint_bitor", issue = "135758")] |
| 161 | + #[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")] |
| 162 | + #[inline] |
| 163 | + pub const unsafe fn unchecked_disjoint_bitor(self, rhs: Self) -> Self { |
| 164 | + assert_unsafe_precondition!( |
| 165 | + check_language_ub, |
| 166 | + "attempt to disjoint or conjoint values", |
| 167 | + ( |
| 168 | + lhs: bool = self, |
| 169 | + rhs: bool = rhs, |
| 170 | + ) => (lhs & rhs) == false, |
| 171 | + ); |
| 172 | + |
| 173 | + // SAFETY: Same precondition. |
| 174 | + unsafe { intrinsics::disjoint_bitor(self, rhs) } |
| 175 | + } |
131 | 176 | } |
0 commit comments