| #![warn(clippy::nonnull_unchecked_on_box_ptr)] |
| |
| use std::ptr::NonNull; |
| |
| macro_rules! identity { |
| ($x:expr) => { |
| $x |
| }; |
| } |
| |
| macro_rules! weird { |
| ($x:expr) => {{ |
| let y = 1; |
| $x |
| }}; |
| } |
| |
| macro_rules! from_macro { |
| ($x:expr) => { |
| unsafe { NonNull::new_unchecked(Box::into_raw($x)) } |
| }; |
| } |
| |
| fn identity<T>(x: T) -> T { |
| x |
| } |
| |
| unsafe fn unsafe_identity<T>(x: T) -> T { |
| x |
| } |
| |
| fn lint() { |
| fn basic() { |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(identity(one))); |
| } |
| |
| fn qualifiers() { |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| |
| { |
| use Box as Box2; |
| use NonNull as NonNull2; |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| } |
| |
| { |
| type Box2<T> = Box<T>; |
| type NonNull2<T> = NonNull<T>; |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| } |
| } |
| |
| fn macros() { |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| |
| let one = Box::new(1); |
| let _ = identity!(NonNull::from_mut(Box::leak(one))); |
| |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(weird!(one))); |
| } |
| |
| fn keep_unsafe_block() { |
| let one = Box::new(1); |
| let _ = unsafe { |
| NonNull::from_mut(Box::leak(unsafe_identity(one))) |
| //~^ nonnull_unchecked_on_box_ptr |
| }; |
| |
| let one = Box::new(1); |
| let _ = unsafe { |
| identity(NonNull::from_mut(Box::leak(one))) |
| //~^ nonnull_unchecked_on_box_ptr |
| }; |
| |
| let one = Box::new(1); |
| let _ = unsafe { |
| unsafe_identity(NonNull::from_mut(Box::leak(one))) |
| //~^ nonnull_unchecked_on_box_ptr |
| }; |
| |
| let _ = unsafe { |
| NonNull::from_mut(Box::leak(Box::new(std::num::NonZeroI32::new_unchecked(1)))) |
| //~^ nonnull_unchecked_on_box_ptr |
| }; |
| |
| let _ = unsafe { |
| let one = Box::new(1); |
| NonNull::from_mut(Box::leak(one)) |
| //~^ nonnull_unchecked_on_box_ptr |
| }; |
| } |
| } |
| |
| fn no_lint() { |
| fn basic() { |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| |
| let one = Box::new(1); |
| let _ = unsafe { NonNull::new_unchecked(identity(Box::into_raw(one))) }; |
| } |
| |
| // TODO? |
| fn does_not_check_expr_init() { |
| let one = Box::new(1); |
| let leaked = Box::into_raw(one); |
| let _ = unsafe { NonNull::new_unchecked(leaked) }; |
| |
| let one = Box::new(1); |
| let leaked = Box::leak(one); |
| let _ = NonNull::from_mut(leaked); |
| } |
| |
| fn macros() { |
| let one = Box::new(1); |
| let _ = from_macro!(one); |
| } |
| } |
| |
| #[clippy::msrv = "1.25"] |
| fn msrv_1_25() { |
| let one = Box::new(1); |
| let _ = unsafe { NonNull::new_unchecked(Box::into_raw(one)) }; |
| } |
| |
| #[clippy::msrv = "1.26"] |
| fn msrv_1_26() { |
| let one = Box::new(1); |
| let _ = NonNull::from(Box::leak(one)); |
| } |
| |
| #[clippy::msrv = "1.89"] |
| fn msrv_1_89() { |
| let one = Box::new(1); |
| let _ = NonNull::from_mut(Box::leak(one)); |
| } |
| |
| fn main() {} |