Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Take lifetime extension into account in ref_as_ptr #12260

Merged
merged 1 commit into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 10 additions & 2 deletions clippy_lints/src/casts/ref_as_ptr.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_no_std_crate;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg;
use clippy_utils::{expr_use_ctxt, is_no_std_crate, ExprUseNode};
use rustc_errors::Applicability;
use rustc_hir::{Expr, Mutability, Ty, TyKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, TypeAndMut};

use super::REF_AS_PTR;

pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to_hir_ty: &Ty<'_>) {
pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'_>,
cast_expr: &'tcx Expr<'_>,
cast_to_hir_ty: &Ty<'_>,
) {
let (cast_from, cast_to) = (
cx.typeck_results().expr_ty(cast_expr),
cx.typeck_results().expr_ty(expr),
);

if matches!(cast_from.kind(), ty::Ref(..))
&& let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, .. }) = cast_to.kind()
&& let Some(use_cx) = expr_use_ctxt(cx, expr)
// TODO: only block the lint if `cast_expr` is a temporary
&& !matches!(use_cx.node, ExprUseNode::Local(_) | ExprUseNode::ConstStatic(_))
{
let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
let fn_name = match to_mutbl {
Expand Down
88 changes: 47 additions & 41 deletions tests/ui/ref_as_ptr.fixed
Original file line number Diff line number Diff line change
@@ -1,55 +1,61 @@
#![warn(clippy::ref_as_ptr)]
#![allow(clippy::unnecessary_mut_passed)]

fn f<T>(_: T) {}

fn main() {
let _ = std::ptr::from_ref(&1u8);
let _ = std::ptr::from_ref::<u32>(&2u32);
let _ = std::ptr::from_ref::<f64>(&3.0f64);
f(std::ptr::from_ref(&1u8));
f(std::ptr::from_ref::<u32>(&2u32));
f(std::ptr::from_ref::<f64>(&3.0f64));

let _ = std::ptr::from_ref(&4) as *const f32;
let _ = std::ptr::from_ref::<f32>(&5.0f32) as *const u32;
f(std::ptr::from_ref(&4) as *const f32);
f(std::ptr::from_ref::<f32>(&5.0f32) as *const u32);

let _ = std::ptr::from_ref(&mut 6u8);
let _ = std::ptr::from_ref::<u32>(&mut 7u32);
let _ = std::ptr::from_ref::<f64>(&mut 8.0f64);
f(std::ptr::from_ref(&mut 6u8));
f(std::ptr::from_ref::<u32>(&mut 7u32));
f(std::ptr::from_ref::<f64>(&mut 8.0f64));

let _ = std::ptr::from_ref(&mut 9) as *const f32;
let _ = std::ptr::from_ref::<f32>(&mut 10.0f32) as *const u32;
f(std::ptr::from_ref(&mut 9) as *const f32);
f(std::ptr::from_ref::<f32>(&mut 10.0f32) as *const u32);

let _ = std::ptr::from_mut(&mut 11u8);
let _ = std::ptr::from_mut::<u32>(&mut 12u32);
let _ = std::ptr::from_mut::<f64>(&mut 13.0f64);
f(std::ptr::from_mut(&mut 11u8));
f(std::ptr::from_mut::<u32>(&mut 12u32));
f(std::ptr::from_mut::<f64>(&mut 13.0f64));

let _ = std::ptr::from_mut(&mut 14) as *const f32;
let _ = std::ptr::from_mut::<f32>(&mut 15.0f32) as *const u32;
f(std::ptr::from_mut(&mut 14) as *const f32);
f(std::ptr::from_mut::<f32>(&mut 15.0f32) as *const u32);

let _ = std::ptr::from_ref(&1u8);
let _ = std::ptr::from_ref::<u32>(&2u32);
let _ = std::ptr::from_ref::<f64>(&3.0f64);
f(std::ptr::from_ref(&1u8));
f(std::ptr::from_ref::<u32>(&2u32));
f(std::ptr::from_ref::<f64>(&3.0f64));

let _ = std::ptr::from_ref(&4) as *const f32;
let _ = std::ptr::from_ref::<f32>(&5.0f32) as *const u32;
f(std::ptr::from_ref(&4) as *const f32);
f(std::ptr::from_ref::<f32>(&5.0f32) as *const u32);

let val = 1;
let _ = std::ptr::from_ref(&val);
let _ = std::ptr::from_ref::<i32>(&val);
f(std::ptr::from_ref(&val));
f(std::ptr::from_ref::<i32>(&val));

let _ = std::ptr::from_ref(&val) as *const f32;
let _ = std::ptr::from_ref::<i32>(&val) as *const f64;
f(std::ptr::from_ref(&val) as *const f32);
f(std::ptr::from_ref::<i32>(&val) as *const f64);

let mut val: u8 = 2;
let _ = std::ptr::from_mut::<u8>(&mut val);
let _ = std::ptr::from_mut(&mut val);
f(std::ptr::from_mut::<u8>(&mut val));
f(std::ptr::from_mut(&mut val));

f(std::ptr::from_ref::<u8>(&mut val));
f(std::ptr::from_ref(&mut val));

let _ = std::ptr::from_ref::<u8>(&mut val);
let _ = std::ptr::from_ref(&mut val);
f(std::ptr::from_ref::<u8>(&mut val) as *const f64);
f::<*const Option<u8>>(std::ptr::from_ref(&mut val) as *const _);

let _ = std::ptr::from_ref::<u8>(&mut val) as *const f64;
let _: *const Option<u8> = std::ptr::from_ref(&mut val) as *const _;
f(std::ptr::from_ref::<[usize; 7]>(&std::array::from_fn(|i| i * i)));
f(std::ptr::from_ref::<[usize; 8]>(&mut std::array::from_fn(|i| i * i)));
f(std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i)));

let _ = std::ptr::from_ref::<[usize; 7]>(&std::array::from_fn(|i| i * i));
let _ = std::ptr::from_ref::<[usize; 8]>(&mut std::array::from_fn(|i| i * i));
let _ = std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i));
let _ = &String::new() as *const _;
let _ = &mut String::new() as *mut _;
const FOO: *const String = &String::new() as *const _;
}

#[clippy::msrv = "1.75"]
Expand All @@ -58,27 +64,27 @@ fn _msrv_1_75() {
let mut_val = &mut 42_i32;

// `std::ptr::from_{ref, mut}` was stabilized in 1.76. Do not lint this
let _ = val as *const i32;
let _ = mut_val as *mut i32;
f(val as *const i32);
f(mut_val as *mut i32);
}

#[clippy::msrv = "1.76"]
fn _msrv_1_76() {
let val = &42_i32;
let mut_val = &mut 42_i32;

let _ = std::ptr::from_ref::<i32>(val);
let _ = std::ptr::from_mut::<i32>(mut_val);
f(std::ptr::from_ref::<i32>(val));
f(std::ptr::from_mut::<i32>(mut_val));
}

fn foo(val: &[u8]) {
let _ = std::ptr::from_ref(val);
let _ = std::ptr::from_ref::<[u8]>(val);
f(std::ptr::from_ref(val));
f(std::ptr::from_ref::<[u8]>(val));
}

fn bar(val: &mut str) {
let _ = std::ptr::from_mut(val);
let _ = std::ptr::from_mut::<str>(val);
f(std::ptr::from_mut(val));
f(std::ptr::from_mut::<str>(val));
}

struct X<'a>(&'a i32);
Expand Down
88 changes: 47 additions & 41 deletions tests/ui/ref_as_ptr.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,61 @@
#![warn(clippy::ref_as_ptr)]
#![allow(clippy::unnecessary_mut_passed)]

fn f<T>(_: T) {}

fn main() {
let _ = &1u8 as *const _;
let _ = &2u32 as *const u32;
let _ = &3.0f64 as *const f64;
f(&1u8 as *const _);
f(&2u32 as *const u32);
f(&3.0f64 as *const f64);

let _ = &4 as *const _ as *const f32;
let _ = &5.0f32 as *const f32 as *const u32;
f(&4 as *const _ as *const f32);
f(&5.0f32 as *const f32 as *const u32);

let _ = &mut 6u8 as *const _;
let _ = &mut 7u32 as *const u32;
let _ = &mut 8.0f64 as *const f64;
f(&mut 6u8 as *const _);
f(&mut 7u32 as *const u32);
f(&mut 8.0f64 as *const f64);

let _ = &mut 9 as *const _ as *const f32;
let _ = &mut 10.0f32 as *const f32 as *const u32;
f(&mut 9 as *const _ as *const f32);
f(&mut 10.0f32 as *const f32 as *const u32);

let _ = &mut 11u8 as *mut _;
let _ = &mut 12u32 as *mut u32;
let _ = &mut 13.0f64 as *mut f64;
f(&mut 11u8 as *mut _);
f(&mut 12u32 as *mut u32);
f(&mut 13.0f64 as *mut f64);

let _ = &mut 14 as *mut _ as *const f32;
let _ = &mut 15.0f32 as *mut f32 as *const u32;
f(&mut 14 as *mut _ as *const f32);
f(&mut 15.0f32 as *mut f32 as *const u32);

let _ = &1u8 as *const _;
let _ = &2u32 as *const u32;
let _ = &3.0f64 as *const f64;
f(&1u8 as *const _);
f(&2u32 as *const u32);
f(&3.0f64 as *const f64);

let _ = &4 as *const _ as *const f32;
let _ = &5.0f32 as *const f32 as *const u32;
f(&4 as *const _ as *const f32);
f(&5.0f32 as *const f32 as *const u32);

let val = 1;
let _ = &val as *const _;
let _ = &val as *const i32;
f(&val as *const _);
f(&val as *const i32);

let _ = &val as *const _ as *const f32;
let _ = &val as *const i32 as *const f64;
f(&val as *const _ as *const f32);
f(&val as *const i32 as *const f64);

let mut val: u8 = 2;
let _ = &mut val as *mut u8;
let _ = &mut val as *mut _;
f(&mut val as *mut u8);
f(&mut val as *mut _);

f(&mut val as *const u8);
f(&mut val as *const _);

let _ = &mut val as *const u8;
let _ = &mut val as *const _;
f(&mut val as *const u8 as *const f64);
f::<*const Option<u8>>(&mut val as *const _ as *const _);

let _ = &mut val as *const u8 as *const f64;
let _: *const Option<u8> = &mut val as *const _ as *const _;
f(&std::array::from_fn(|i| i * i) as *const [usize; 7]);
f(&mut std::array::from_fn(|i| i * i) as *const [usize; 8]);
f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]);

let _ = &std::array::from_fn(|i| i * i) as *const [usize; 7];
let _ = &mut std::array::from_fn(|i| i * i) as *const [usize; 8];
let _ = &mut std::array::from_fn(|i| i * i) as *mut [usize; 9];
let _ = &String::new() as *const _;
let _ = &mut String::new() as *mut _;
const FOO: *const String = &String::new() as *const _;
}

#[clippy::msrv = "1.75"]
Expand All @@ -58,27 +64,27 @@ fn _msrv_1_75() {
let mut_val = &mut 42_i32;

// `std::ptr::from_{ref, mut}` was stabilized in 1.76. Do not lint this
let _ = val as *const i32;
let _ = mut_val as *mut i32;
f(val as *const i32);
f(mut_val as *mut i32);
}

#[clippy::msrv = "1.76"]
fn _msrv_1_76() {
let val = &42_i32;
let mut_val = &mut 42_i32;

let _ = val as *const i32;
let _ = mut_val as *mut i32;
f(val as *const i32);
f(mut_val as *mut i32);
}

fn foo(val: &[u8]) {
let _ = val as *const _;
let _ = val as *const [u8];
f(val as *const _);
f(val as *const [u8]);
}

fn bar(val: &mut str) {
let _ = val as *mut _;
let _ = val as *mut str;
f(val as *mut _);
f(val as *mut str);
}

struct X<'a>(&'a i32);
Expand Down