Skip to content

Commit 16d7739

Browse files
authored
Rollup merge of #91122 - dtolnay:not, r=m-ou-se
impl Not for ! The lack of this impl caused trouble for me in some degenerate cases of macro-generated code of the form `if !$cond {...}`, even without `feature(never_type)` on a stable compiler. Namely if `$cond` contains a `return` or `break` or similar diverging expression, which would otherwise be perfectly legal in boolean position, the code previously failed to compile with: ```console error[E0600]: cannot apply unary operator `!` to type `!` --> library/core/tests/ops.rs:239:8 | 239 | if !return () {} | ^^^^^^^^^^ cannot apply unary operator `!` ```
2 parents 9fa6349 + 5046309 commit 16d7739

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

core/src/ops/bit.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ macro_rules! not_impl {
6868

6969
not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
7070

71+
#[stable(feature = "not_never", since = "1.60.0")]
72+
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
73+
impl const Not for ! {
74+
type Output = !;
75+
76+
#[inline]
77+
fn not(self) -> ! {
78+
match self {}
79+
}
80+
}
81+
7182
/// The bitwise AND operator `&`.
7283
///
7384
/// Note that `Rhs` is `Self` by default, but this is not mandatory.

core/tests/ops.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,9 @@ fn deref_on_ref() {
232232
let y = deref(&mut x);
233233
assert_eq!(y, 4);
234234
}
235+
236+
#[test]
237+
#[allow(unreachable_code)]
238+
fn test_not_never() {
239+
if !return () {}
240+
}

0 commit comments

Comments
 (0)