Skip to content

Commit 9925f99

Browse files
committed
update borrow_as_ptr to suggest &raw when the MSRV allows it
1 parent c8b10ac commit 9925f99

File tree

6 files changed

+84
-15
lines changed

6 files changed

+84
-15
lines changed

clippy_lints/src/casts/borrow_as_ptr.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::msrvs::Msrv;
23
use clippy_utils::source::snippet_with_context;
3-
use clippy_utils::{is_lint_allowed, std_or_core};
4+
use clippy_utils::{is_lint_allowed, msrvs, std_or_core};
45
use rustc_errors::Applicability;
56
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};
67
use rustc_lint::LateContext;
@@ -13,16 +14,12 @@ pub(super) fn check<'tcx>(
1314
expr: &'tcx Expr<'_>,
1415
cast_expr: &'tcx Expr<'_>,
1516
cast_to: &'tcx Ty<'_>,
17+
msrv: &Msrv,
1618
) -> bool {
1719
if matches!(cast_to.kind, TyKind::Ptr(_))
1820
&& let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind
19-
&& let Some(std_or_core) = std_or_core(cx)
2021
&& !is_lint_allowed(cx, BORROW_AS_PTR, expr.hir_id)
2122
{
22-
let macro_name = match mutability {
23-
Mutability::Not => "addr_of",
24-
Mutability::Mut => "addr_of_mut",
25-
};
2623
let mut app = Applicability::MachineApplicable;
2724
let snip = snippet_with_context(cx, e.span, cast_expr.span.ctxt(), "..", &mut app).0;
2825
// Fix #9884
@@ -35,13 +32,30 @@ pub(super) fn check<'tcx>(
3532
return false;
3633
}
3734

35+
let suggestion = if msrv.meets(msrvs::RAW_REF_OP) {
36+
let operator_kind = match mutability {
37+
Mutability::Not => "const",
38+
Mutability::Mut => "mut",
39+
};
40+
format!("&raw {operator_kind} {snip}")
41+
} else {
42+
let Some(std_or_core) = std_or_core(cx) else {
43+
return false;
44+
};
45+
let macro_name = match mutability {
46+
Mutability::Not => "addr_of",
47+
Mutability::Mut => "addr_of_mut",
48+
};
49+
format!("{std_or_core}::ptr::{macro_name}!({snip})")
50+
};
51+
3852
span_lint_and_sugg(
3953
cx,
4054
BORROW_AS_PTR,
4155
expr.span,
4256
"borrow as raw pointer",
4357
"try",
44-
format!("{std_or_core}::ptr::{macro_name}!({snip})"),
58+
suggestion,
4559
Applicability::MachineApplicable,
4660
);
4761
return true;

clippy_lints/src/casts/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -574,13 +574,13 @@ declare_clippy_lint! {
574574
declare_clippy_lint! {
575575
/// ### What it does
576576
/// Checks for the usage of `&expr as *const T` or
577-
/// `&mut expr as *mut T`, and suggest using `ptr::addr_of` or
578-
/// `ptr::addr_of_mut` instead.
577+
/// `&mut expr as *mut T`, and suggest using `&raw const` or
578+
/// `&raw mut` instead.
579579
///
580580
/// ### Why is this bad?
581581
/// This would improve readability and avoid creating a reference
582582
/// that points to an uninitialized value or unaligned place.
583-
/// Read the `ptr::addr_of` docs for more information.
583+
/// Read the `&raw` explanation in the Reference for more information.
584584
///
585585
/// ### Example
586586
/// ```no_run
@@ -593,10 +593,10 @@ declare_clippy_lint! {
593593
/// Use instead:
594594
/// ```no_run
595595
/// let val = 1;
596-
/// let p = std::ptr::addr_of!(val);
596+
/// let p = &raw const val;
597597
///
598598
/// let mut val_mut = 1;
599-
/// let p_mut = std::ptr::addr_of_mut!(val_mut);
599+
/// let p_mut = &raw mut val_mut;
600600
/// ```
601601
#[clippy::version = "1.60.0"]
602602
pub BORROW_AS_PTR,
@@ -807,7 +807,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
807807
as_underscore::check(cx, expr, cast_to_hir);
808808

809809
let was_borrow_as_ptr_emitted = if self.msrv.meets(msrvs::BORROW_AS_PTR) {
810-
borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir)
810+
borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir, &self.msrv)
811811
} else {
812812
false
813813
};

clippy_utils/src/msrvs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ macro_rules! msrv_aliases {
1919
// names may refer to stabilized feature flags or library items
2020
msrv_aliases! {
2121
1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY }
22-
1,82,0 { IS_NONE_OR, REPEAT_N }
22+
1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP }
2323
1,81,0 { LINT_REASONS_STABILIZATION }
24-
1,80,0 { BOX_INTO_ITER}
24+
1,80,0 { BOX_INTO_ITER }
2525
1,77,0 { C_STR_LITERALS }
2626
1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT }
2727
1,73,0 { MANUAL_DIV_CEIL }

tests/ui/borrow_as_ptr_raw_ref.fixed

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![warn(clippy::borrow_as_ptr)]
2+
#![allow(clippy::useless_vec)]
3+
4+
fn a() -> i32 {
5+
0
6+
}
7+
8+
#[clippy::msrv = "1.82"]
9+
fn main() {
10+
let val = 1;
11+
let _p = &raw const val;
12+
let _p = &0 as *const i32;
13+
let _p = &a() as *const i32;
14+
let vec = vec![1];
15+
let _p = &vec.len() as *const usize;
16+
17+
let mut val_mut = 1;
18+
let _p_mut = &raw mut val_mut;
19+
}

tests/ui/borrow_as_ptr_raw_ref.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![warn(clippy::borrow_as_ptr)]
2+
#![allow(clippy::useless_vec)]
3+
4+
fn a() -> i32 {
5+
0
6+
}
7+
8+
#[clippy::msrv = "1.82"]
9+
fn main() {
10+
let val = 1;
11+
let _p = &val as *const i32;
12+
let _p = &0 as *const i32;
13+
let _p = &a() as *const i32;
14+
let vec = vec![1];
15+
let _p = &vec.len() as *const usize;
16+
17+
let mut val_mut = 1;
18+
let _p_mut = &mut val_mut as *mut i32;
19+
}

tests/ui/borrow_as_ptr_raw_ref.stderr

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: borrow as raw pointer
2+
--> tests/ui/borrow_as_ptr_raw_ref.rs:11:14
3+
|
4+
LL | let _p = &val as *const i32;
5+
| ^^^^^^^^^^^^^^^^^^ help: try: `&raw const val`
6+
|
7+
= note: `-D clippy::borrow-as-ptr` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`
9+
10+
error: borrow as raw pointer
11+
--> tests/ui/borrow_as_ptr_raw_ref.rs:18:18
12+
|
13+
LL | let _p_mut = &mut val_mut as *mut i32;
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut val_mut`
15+
16+
error: aborting due to 2 previous errors
17+

0 commit comments

Comments
 (0)