{borrow,ptr}_as_ptr: don't lint inside proc-macros (#15473)

this could arguably be 2 separate PRs, but both of these were brought up
in the same issue, so..

fixes https://github.com/rust-lang/rust-clippy/issues/15398

- [x] I'm a bit doubtful about the last commit -- see the message for my
reasoning and do let me know whether it's right.

changelog: [`borrow_as_ptr`]: don't lint inside proc-macros
changelog: [`ptr_as_ptr`]: don't lint inside proc-macros
This commit is contained in:
Jason Newcomb 2025-08-15 13:34:52 +00:00 committed by GitHub
commit 9563a5ce46
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 75 additions and 54 deletions

View file

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::msrvs::Msrv;
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
use clippy_utils::sugg::has_enclosing_paren;
use clippy_utils::{get_parent_expr, is_expr_temporary_value, is_lint_allowed, msrvs, std_or_core};
use clippy_utils::{get_parent_expr, is_expr_temporary_value, is_from_proc_macro, is_lint_allowed, msrvs, std_or_core};
use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};
use rustc_lint::LateContext;
@ -22,13 +22,12 @@ pub(super) fn check<'tcx>(
&& !matches!(target.ty.kind, TyKind::TraitObject(..))
&& let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind
&& !is_lint_allowed(cx, BORROW_AS_PTR, expr.hir_id)
// Fix #9884
&& !is_expr_temporary_value(cx, e)
&& !is_from_proc_macro(cx, expr)
{
let mut app = Applicability::MachineApplicable;
let snip = snippet_with_context(cx, e.span, cast_expr.span.ctxt(), "..", &mut app).0;
// Fix #9884
if is_expr_temporary_value(cx, e) {
return false;
}
let (suggestion, span) = if msrv.meets(cx, msrvs::RAW_REF_OP) {
// Make sure that the span to be replaced doesn't include parentheses, that could break the

View file

@ -1,4 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_from_proc_macro;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg;
@ -25,7 +26,7 @@ impl OmitFollowedCastReason<'_> {
}
}
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Msrv) {
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Msrv) {
if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind
&& let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr))
&& let ty::RawPtr(_, from_mutbl) = cast_from.kind()
@ -36,6 +37,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Msrv) {
// as explained here: https://github.com/rust-lang/rust/issues/60602.
&& to_pointee_ty.is_sized(cx.tcx, cx.typing_env())
&& msrv.meets(cx, msrvs::POINTER_CAST)
&& !is_from_proc_macro(cx, expr)
{
let mut app = Applicability::MachineApplicable;
let turbofish = match &cast_to_hir_ty.kind {

View file

@ -1,6 +1,9 @@
//@aux-build:proc_macros.rs
#![warn(clippy::borrow_as_ptr)]
#![allow(clippy::useless_vec)]
extern crate proc_macros;
fn a() -> i32 {
0
}
@ -53,3 +56,12 @@ fn issue_15141() {
// Don't lint cast to dyn trait pointers
let b = &a as *const dyn std::any::Any;
}
fn issue15389() {
proc_macros::with_span! {
span
let var = 0u32;
// Don't lint in proc-macros
let _ = &var as *const u32;
};
}

View file

@ -1,6 +1,9 @@
//@aux-build:proc_macros.rs
#![warn(clippy::borrow_as_ptr)]
#![allow(clippy::useless_vec)]
extern crate proc_macros;
fn a() -> i32 {
0
}
@ -53,3 +56,12 @@ fn issue_15141() {
// Don't lint cast to dyn trait pointers
let b = &a as *const dyn std::any::Any;
}
fn issue15389() {
proc_macros::with_span! {
span
let var = 0u32;
// Don't lint in proc-macros
let _ = &var as *const u32;
};
}

View file

@ -1,5 +1,5 @@
error: borrow as raw pointer
--> tests/ui/borrow_as_ptr.rs:11:14
--> tests/ui/borrow_as_ptr.rs:14:14
|
LL | let _p = &val as *const i32;
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of!(val)`
@ -8,25 +8,25 @@ LL | let _p = &val as *const i32;
= help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`
error: borrow as raw pointer
--> tests/ui/borrow_as_ptr.rs:19:18
--> tests/ui/borrow_as_ptr.rs:22:18
|
LL | let _p_mut = &mut val_mut as *mut i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of_mut!(val_mut)`
error: borrow as raw pointer
--> tests/ui/borrow_as_ptr.rs:23:16
--> tests/ui/borrow_as_ptr.rs:26:16
|
LL | let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of_mut!(x[1])`
error: borrow as raw pointer
--> tests/ui/borrow_as_ptr.rs:29:17
--> tests/ui/borrow_as_ptr.rs:32:17
|
LL | let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1);
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut x[1]`
error: implicit borrow as raw pointer
--> tests/ui/borrow_as_ptr.rs:35:25
--> tests/ui/borrow_as_ptr.rs:38:25
|
LL | let p: *const i32 = &val;
| ^^^^
@ -37,7 +37,7 @@ LL | let p: *const i32 = &raw const val;
| +++++++++
error: implicit borrow as raw pointer
--> tests/ui/borrow_as_ptr.rs:39:23
--> tests/ui/borrow_as_ptr.rs:42:23
|
LL | let p: *mut i32 = &mut val;
| ^^^^^^^^
@ -48,7 +48,7 @@ LL | let p: *mut i32 = &raw mut val;
| +++
error: implicit borrow as raw pointer
--> tests/ui/borrow_as_ptr.rs:44:19
--> tests/ui/borrow_as_ptr.rs:47:19
|
LL | core::ptr::eq(&val, &1);
| ^^^^

View file

@ -2,8 +2,8 @@
#![warn(clippy::ptr_as_ptr)]
#[macro_use]
extern crate proc_macros;
use proc_macros::{external, inline_macros, with_span};
mod issue_11278_a {
#[derive(Debug)]
@ -53,11 +53,13 @@ fn main() {
//~^ ptr_as_ptr
// Make sure the lint is triggered inside a macro
let _ = inline!($ptr.cast::<i32>());
//~^ ptr_as_ptr
// FIXME: `is_from_proc_macro` incorrectly stops the lint from firing here
let _ = inline!($ptr as *const i32);
// Do not lint inside macros from external crates
let _ = external!($ptr as *const i32);
let _ = with_span!(expr $ptr as *const i32);
}
#[clippy::msrv = "1.37"]

View file

@ -2,8 +2,8 @@
#![warn(clippy::ptr_as_ptr)]
#[macro_use]
extern crate proc_macros;
use proc_macros::{external, inline_macros, with_span};
mod issue_11278_a {
#[derive(Debug)]
@ -53,11 +53,13 @@ fn main() {
//~^ ptr_as_ptr
// Make sure the lint is triggered inside a macro
// FIXME: `is_from_proc_macro` incorrectly stops the lint from firing here
let _ = inline!($ptr as *const i32);
//~^ ptr_as_ptr
// Do not lint inside macros from external crates
let _ = external!($ptr as *const i32);
let _ = with_span!(expr $ptr as *const i32);
}
#[clippy::msrv = "1.37"]

View file

@ -38,174 +38,166 @@ LL | let _: *mut i32 = mut_ptr as _;
| ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:56:21
|
LL | let _ = inline!($ptr as *const i32);
| ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::<i32>()`
|
= note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:78:13
--> tests/ui/ptr_as_ptr.rs:80:13
|
LL | let _ = ptr as *const i32;
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:80:13
--> tests/ui/ptr_as_ptr.rs:82:13
|
LL | let _ = mut_ptr as *mut i32;
| ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:88:9
--> tests/ui/ptr_as_ptr.rs:90:9
|
LL | ptr::null_mut() as *mut u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:93:9
--> tests/ui/ptr_as_ptr.rs:95:9
|
LL | std::ptr::null_mut() as *mut u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut::<u32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:99:9
--> tests/ui/ptr_as_ptr.rs:101:9
|
LL | ptr::null_mut() as *mut u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:104:9
--> tests/ui/ptr_as_ptr.rs:106:9
|
LL | core::ptr::null_mut() as *mut u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut::<u32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:110:9
--> tests/ui/ptr_as_ptr.rs:112:9
|
LL | ptr::null() as *const u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:115:9
--> tests/ui/ptr_as_ptr.rs:117:9
|
LL | std::ptr::null() as *const u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:121:9
--> tests/ui/ptr_as_ptr.rs:123:9
|
LL | ptr::null() as *const u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:126:9
--> tests/ui/ptr_as_ptr.rs:128:9
|
LL | core::ptr::null() as *const u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null::<u32>()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:134:9
--> tests/ui/ptr_as_ptr.rs:136:9
|
LL | ptr::null_mut() as *mut _
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:139:9
--> tests/ui/ptr_as_ptr.rs:141:9
|
LL | std::ptr::null_mut() as *mut _
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:145:9
--> tests/ui/ptr_as_ptr.rs:147:9
|
LL | ptr::null_mut() as *mut _
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:150:9
--> tests/ui/ptr_as_ptr.rs:152:9
|
LL | core::ptr::null_mut() as *mut _
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:156:9
--> tests/ui/ptr_as_ptr.rs:158:9
|
LL | ptr::null() as *const _
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:161:9
--> tests/ui/ptr_as_ptr.rs:163:9
|
LL | std::ptr::null() as *const _
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:167:9
--> tests/ui/ptr_as_ptr.rs:169:9
|
LL | ptr::null() as *const _
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:172:9
--> tests/ui/ptr_as_ptr.rs:174:9
|
LL | core::ptr::null() as *const _
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:180:9
--> tests/ui/ptr_as_ptr.rs:182:9
|
LL | ptr::null_mut() as _
| ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:185:9
--> tests/ui/ptr_as_ptr.rs:187:9
|
LL | std::ptr::null_mut() as _
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:191:9
--> tests/ui/ptr_as_ptr.rs:193:9
|
LL | ptr::null_mut() as _
| ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:196:9
--> tests/ui/ptr_as_ptr.rs:198:9
|
LL | core::ptr::null_mut() as _
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:202:9
--> tests/ui/ptr_as_ptr.rs:204:9
|
LL | ptr::null() as _
| ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:207:9
--> tests/ui/ptr_as_ptr.rs:209:9
|
LL | std::ptr::null() as _
| ^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:213:9
--> tests/ui/ptr_as_ptr.rs:215:9
|
LL | ptr::null() as _
| ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:218:9
--> tests/ui/ptr_as_ptr.rs:220:9
|
LL | core::ptr::null() as _
| ^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`
error: `as` casting between raw pointers without changing their constness
--> tests/ui/ptr_as_ptr.rs:226:43
--> tests/ui/ptr_as_ptr.rs:228:43
|
LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u8>()`
error: aborting due to 34 previous errors
error: aborting due to 33 previous errors