Skip to content

Commit a5e46a6

Browse files
authored
update borrow_as_ptr to suggest &raw syntax (rust-lang#13689)
This PR updates the `borrow_as_ptr` lint to no longer suggest `addr_of!` and `addr_of_mut!` and instead use the preferred `&raw const` and `&raw mut` syntax. Not sure about two things: 1. Do I need to set or update a MSRV for the lint anywhere? 2. There is a `borrow_as_ptr_no_std` test as well as a `borrow_as_ptr` test. They used to be more relevant as the lint needed to select `std` or `core`, but that is gone now, so maybe the `borrow_as_ptr_no_std` should be deleted? changelog: update `borrow_as_ptr` to suggest `&raw` syntax
2 parents 2550530 + 9925f99 commit a5e46a6

9 files changed

+133
-19
lines changed
+26-9
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::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,15 +14,12 @@ pub(super) fn check<'tcx>(
1314
expr: &'tcx Expr<'_>,
1415
cast_expr: &'tcx Expr<'_>,
1516
cast_to: &'tcx Ty<'_>,
16-
) {
17+
msrv: &Msrv,
18+
) -> 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)
21+
&& !is_lint_allowed(cx, BORROW_AS_PTR, expr.hir_id)
2022
{
21-
let macro_name = match mutability {
22-
Mutability::Not => "addr_of",
23-
Mutability::Mut => "addr_of_mut",
24-
};
2523
let mut app = Applicability::MachineApplicable;
2624
let snip = snippet_with_context(cx, e.span, cast_expr.span.ctxt(), "..", &mut app).0;
2725
// Fix #9884
@@ -31,17 +29,36 @@ pub(super) fn check<'tcx>(
3129
.get(base.hir_id)
3230
.is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
3331
}) {
34-
return;
32+
return false;
3533
}
3634

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+
3752
span_lint_and_sugg(
3853
cx,
3954
BORROW_AS_PTR,
4055
expr.span,
4156
"borrow as raw pointer",
4257
"try",
43-
format!("{std_or_core}::ptr::{macro_name}!({snip})"),
58+
suggestion,
4459
Applicability::MachineApplicable,
4560
);
61+
return true;
4662
}
63+
false
4764
}

clippy_lints/src/casts/mod.rs

+11-8
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,
@@ -806,10 +806,13 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
806806

807807
as_underscore::check(cx, expr, cast_to_hir);
808808

809-
if self.msrv.meets(msrvs::PTR_FROM_REF) {
809+
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, &self.msrv)
811+
} else {
812+
false
813+
};
814+
if self.msrv.meets(msrvs::PTR_FROM_REF) && !was_borrow_as_ptr_emitted {
810815
ref_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir);
811-
} else if self.msrv.meets(msrvs::BORROW_AS_PTR) {
812-
borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir);
813816
}
814817
}
815818

clippy_utils/src/msrvs.rs

+2-2
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_and_ref_as_ptr.fixed

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Make sure that `ref_as_ptr` is not emitted when `borrow_as_ptr` is.
2+
3+
#![warn(clippy::ref_as_ptr, clippy::borrow_as_ptr)]
4+
5+
fn f<T>(_: T) {}
6+
7+
fn main() {
8+
let mut val = 0;
9+
f(&raw const val);
10+
f(&raw mut val);
11+
}

tests/ui/borrow_and_ref_as_ptr.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Make sure that `ref_as_ptr` is not emitted when `borrow_as_ptr` is.
2+
3+
#![warn(clippy::ref_as_ptr, clippy::borrow_as_ptr)]
4+
5+
fn f<T>(_: T) {}
6+
7+
fn main() {
8+
let mut val = 0;
9+
f(&val as *const _);
10+
f(&mut val as *mut i32);
11+
}

tests/ui/borrow_and_ref_as_ptr.stderr

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: borrow as raw pointer
2+
--> tests/ui/borrow_and_ref_as_ptr.rs:9:7
3+
|
4+
LL | f(&val as *const _);
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_and_ref_as_ptr.rs:10:7
12+
|
13+
LL | f(&mut val as *mut i32);
14+
| ^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut val`
15+
16+
error: aborting due to 2 previous errors
17+

tests/ui/borrow_as_ptr_raw_ref.fixed

+19
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

+19
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

+17
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)