Rollup merge of #79058 - dtolnay:likelymacro, r=Mark-Simulacrum

Move likely/unlikely argument outside of invisible unsafe block

The previous `likely!`/`unlikely!` macros were unsound because it permits the caller's expr to contain arbitrary unsafe code.

```rust
pub fn huh() -> bool {
    likely!(std::ptr::read(&() as *const () as *const bool))
}
```

**Before:** compiles cleanly.
**After:**

```console
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
   |
70 |     likely!(std::ptr::read(&() as *const () as *const bool))
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
   |
   = note: consult the function's documentation for information on how to avoid undefined behavior
```
This commit is contained in:
Jonas Schievink 2020-11-15 13:40:03 +01:00 committed by GitHub
commit ae1916b3b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -47,9 +47,9 @@ pub fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
#[macro_export]
macro_rules! likely {
($e:expr) => {
#[allow(unused_unsafe)]
{
unsafe { std::intrinsics::likely($e) }
match $e {
#[allow(unused_unsafe)]
e => unsafe { std::intrinsics::likely(e) },
}
};
}
@ -57,9 +57,9 @@ macro_rules! likely {
#[macro_export]
macro_rules! unlikely {
($e:expr) => {
#[allow(unused_unsafe)]
{
unsafe { std::intrinsics::unlikely($e) }
match $e {
#[allow(unused_unsafe)]
e => unsafe { std::intrinsics::unlikely(e) },
}
};
}