mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-16 22:18:40 +00:00
Auto merge of #11288 - Centri3:#11278, r=Alexendoo
[`ptr_as_ptr`]: Take snippet instead of pretty printing type Fixes #11278 changelog: [`ptr_as_ptr`]: Include leading `super`s in suggestion
This commit is contained in:
commit
237dd599db
4 changed files with 82 additions and 42 deletions
|
@ -1,9 +1,7 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, Mutability, TyKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
@ -16,33 +14,41 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
|
|||
return;
|
||||
}
|
||||
|
||||
if_chain! {
|
||||
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));
|
||||
if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind();
|
||||
if let ty::RawPtr(TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl }) = cast_to.kind();
|
||||
if matches!((from_mutbl, to_mutbl),
|
||||
(Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut));
|
||||
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(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind()
|
||||
&& let ty::RawPtr(TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl }) = cast_to.kind()
|
||||
&& matches!((from_mutbl, to_mutbl),
|
||||
(Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut))
|
||||
// The `U` in `pointer::cast` have to be `Sized`
|
||||
// as explained here: https://github.com/rust-lang/rust/issues/60602.
|
||||
if to_pointee_ty.is_sized(cx.tcx, cx.param_env);
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut applicability);
|
||||
let turbofish = match &cast_to_hir_ty.kind {
|
||||
TyKind::Infer => Cow::Borrowed(""),
|
||||
TyKind::Ptr(mut_ty) if matches!(mut_ty.ty.kind, TyKind::Infer) => Cow::Borrowed(""),
|
||||
_ => Cow::Owned(format!("::<{to_pointee_ty}>")),
|
||||
};
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
PTR_AS_PTR,
|
||||
expr.span,
|
||||
"`as` casting between raw pointers without changing its mutability",
|
||||
"try `pointer::cast`, a safer alternative",
|
||||
format!("{}.cast{turbofish}()", cast_expr_sugg.maybe_par()),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
&& to_pointee_ty.is_sized(cx.tcx, cx.param_env)
|
||||
{
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app);
|
||||
let turbofish = match &cast_to_hir_ty.kind {
|
||||
TyKind::Infer => String::new(),
|
||||
TyKind::Ptr(mut_ty) => {
|
||||
if matches!(mut_ty.ty.kind, TyKind::Infer) {
|
||||
String::new()
|
||||
} else {
|
||||
format!(
|
||||
"::<{}>",
|
||||
snippet_with_applicability(cx, mut_ty.ty.span, "/* type */", &mut app)
|
||||
)
|
||||
}
|
||||
},
|
||||
_ => return,
|
||||
};
|
||||
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
PTR_AS_PTR,
|
||||
expr.span,
|
||||
"`as` casting between raw pointers without changing its mutability",
|
||||
"try `pointer::cast`, a safer alternative",
|
||||
format!("{}.cast{turbofish}()", cast_expr_sugg.maybe_par()),
|
||||
app,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,22 @@
|
|||
|
||||
#![warn(clippy::ptr_as_ptr)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macros;
|
||||
use proc_macros::{external, inline_macros};
|
||||
|
||||
mod issue_11278_a {
|
||||
#[derive(Debug)]
|
||||
pub struct T<D: std::fmt::Debug + ?Sized> {
|
||||
pub p: D,
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_11278_b {
|
||||
pub fn f(o: &mut super::issue_11278_a::T<dyn std::fmt::Debug>) -> super::issue_11278_a::T<String> {
|
||||
// Retain `super`
|
||||
*unsafe { Box::from_raw(Box::into_raw(Box::new(o)).cast::<super::issue_11278_a::T<String>>()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_macros]
|
||||
fn main() {
|
||||
|
|
|
@ -3,8 +3,22 @@
|
|||
|
||||
#![warn(clippy::ptr_as_ptr)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macros;
|
||||
use proc_macros::{external, inline_macros};
|
||||
|
||||
mod issue_11278_a {
|
||||
#[derive(Debug)]
|
||||
pub struct T<D: std::fmt::Debug + ?Sized> {
|
||||
pub p: D,
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_11278_b {
|
||||
pub fn f(o: &mut super::issue_11278_a::T<dyn std::fmt::Debug>) -> super::issue_11278_a::T<String> {
|
||||
// Retain `super`
|
||||
*unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T<String>) }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_macros]
|
||||
fn main() {
|
||||
|
|
|
@ -1,37 +1,43 @@
|
|||
error: `as` casting between raw pointers without changing its mutability
|
||||
--> $DIR/ptr_as_ptr.rs:14:13
|
||||
--> $DIR/ptr_as_ptr.rs:19:33
|
||||
|
|
||||
LL | let _ = ptr as *const i32;
|
||||
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
|
||||
LL | *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T<String>) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `Box::into_raw(Box::new(o)).cast::<super::issue_11278_a::T<String>>()`
|
||||
|
|
||||
= note: `-D clippy::ptr-as-ptr` implied by `-D warnings`
|
||||
|
||||
error: `as` casting between raw pointers without changing its mutability
|
||||
--> $DIR/ptr_as_ptr.rs:15:13
|
||||
--> $DIR/ptr_as_ptr.rs:28: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 its mutability
|
||||
--> $DIR/ptr_as_ptr.rs:29: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 its mutability
|
||||
--> $DIR/ptr_as_ptr.rs:20:17
|
||||
--> $DIR/ptr_as_ptr.rs:34:17
|
||||
|
|
||||
LL | let _ = *ptr_ptr as *const i32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::<i32>()`
|
||||
|
||||
error: `as` casting between raw pointers without changing its mutability
|
||||
--> $DIR/ptr_as_ptr.rs:33:25
|
||||
--> $DIR/ptr_as_ptr.rs:47:25
|
||||
|
|
||||
LL | let _: *const i32 = ptr as *const _;
|
||||
| ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()`
|
||||
|
||||
error: `as` casting between raw pointers without changing its mutability
|
||||
--> $DIR/ptr_as_ptr.rs:34:23
|
||||
--> $DIR/ptr_as_ptr.rs:48:23
|
||||
|
|
||||
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 its mutability
|
||||
--> $DIR/ptr_as_ptr.rs:37:21
|
||||
--> $DIR/ptr_as_ptr.rs:51:21
|
||||
|
|
||||
LL | let _ = inline!($ptr as *const i32);
|
||||
| ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::<i32>()`
|
||||
|
@ -39,16 +45,16 @@ LL | let _ = inline!($ptr as *const 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 its mutability
|
||||
--> $DIR/ptr_as_ptr.rs:58:13
|
||||
--> $DIR/ptr_as_ptr.rs:72: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 its mutability
|
||||
--> $DIR/ptr_as_ptr.rs:59:13
|
||||
--> $DIR/ptr_as_ptr.rs:73:13
|
||||
|
|
||||
LL | let _ = mut_ptr as *mut i32;
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue