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 `!` ```
This commit is contained in:
commit
55a1f8b955
@ -68,6 +68,17 @@ macro_rules! not_impl {
|
||||
|
||||
not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
||||
|
||||
#[stable(feature = "not_never", since = "1.60.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const Not for ! {
|
||||
type Output = !;
|
||||
|
||||
#[inline]
|
||||
fn not(self) -> ! {
|
||||
match self {}
|
||||
}
|
||||
}
|
||||
|
||||
/// The bitwise AND operator `&`.
|
||||
///
|
||||
/// Note that `Rhs` is `Self` by default, but this is not mandatory.
|
||||
|
@ -232,3 +232,9 @@ fn deref_on_ref() {
|
||||
let y = deref(&mut x);
|
||||
assert_eq!(y, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(unreachable_code)]
|
||||
fn test_not_never() {
|
||||
if !return () {}
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
#![deny(unreachable_code)]
|
||||
|
||||
fn foo() {
|
||||
let x: ! = ! { return; }; //~ ERROR unreachable
|
||||
//~| ERROR cannot apply unary operator `!` to type `!`
|
||||
let x: ! = * { return; }; //~ ERROR unreachable
|
||||
//~| ERROR type `!` cannot be dereferenced
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
@ -1,13 +1,13 @@
|
||||
error[E0600]: cannot apply unary operator `!` to type `!`
|
||||
error[E0614]: type `!` cannot be dereferenced
|
||||
--> $DIR/expr_unary.rs:8:16
|
||||
|
|
||||
LL | let x: ! = ! { return; };
|
||||
| ^^^^^^^^^^^^^ cannot apply unary operator `!`
|
||||
LL | let x: ! = * { return; };
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable expression
|
||||
--> $DIR/expr_unary.rs:8:16
|
||||
|
|
||||
LL | let x: ! = ! { return; };
|
||||
LL | let x: ! = * { return; };
|
||||
| ^^^^------^^^
|
||||
| | |
|
||||
| | any code following this expression is unreachable
|
||||
@ -21,4 +21,4 @@ LL | #![deny(unreachable_code)]
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0600`.
|
||||
For more information about this error, try `rustc --explain E0614`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user