Skip to content

Commit 237dd59

Browse files
committed
Auto merge of rust-lang#11288 - Centri3:rust-lang#11278, r=Alexendoo
[`ptr_as_ptr`]: Take snippet instead of pretty printing type Fixes rust-lang#11278 changelog: [`ptr_as_ptr`]: Include leading `super`s in suggestion
2 parents 97d1cfa + fef85c9 commit 237dd59

File tree

4 files changed

+82
-42
lines changed

4 files changed

+82
-42
lines changed

clippy_lints/src/casts/ptr_as_ptr.rs

+35-29
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use std::borrow::Cow;
2-
31
use clippy_utils::diagnostics::span_lint_and_sugg;
42
use clippy_utils::msrvs::{self, Msrv};
3+
use clippy_utils::source::snippet_with_applicability;
54
use clippy_utils::sugg::Sugg;
6-
use if_chain::if_chain;
75
use rustc_errors::Applicability;
86
use rustc_hir::{Expr, ExprKind, Mutability, TyKind};
97
use rustc_lint::LateContext;
@@ -16,33 +14,41 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
1614
return;
1715
}
1816

19-
if_chain! {
20-
if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind;
21-
let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr));
22-
if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind();
23-
if let ty::RawPtr(TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl }) = cast_to.kind();
24-
if matches!((from_mutbl, to_mutbl),
25-
(Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut));
17+
if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind
18+
&& let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr))
19+
&& let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind()
20+
&& let ty::RawPtr(TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl }) = cast_to.kind()
21+
&& matches!((from_mutbl, to_mutbl),
22+
(Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut))
2623
// The `U` in `pointer::cast` have to be `Sized`
2724
// as explained here: https://github.com/rust-lang/rust/issues/60602.
28-
if to_pointee_ty.is_sized(cx.tcx, cx.param_env);
29-
then {
30-
let mut applicability = Applicability::MachineApplicable;
31-
let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut applicability);
32-
let turbofish = match &cast_to_hir_ty.kind {
33-
TyKind::Infer => Cow::Borrowed(""),
34-
TyKind::Ptr(mut_ty) if matches!(mut_ty.ty.kind, TyKind::Infer) => Cow::Borrowed(""),
35-
_ => Cow::Owned(format!("::<{to_pointee_ty}>")),
36-
};
37-
span_lint_and_sugg(
38-
cx,
39-
PTR_AS_PTR,
40-
expr.span,
41-
"`as` casting between raw pointers without changing its mutability",
42-
"try `pointer::cast`, a safer alternative",
43-
format!("{}.cast{turbofish}()", cast_expr_sugg.maybe_par()),
44-
applicability,
45-
);
46-
}
25+
&& to_pointee_ty.is_sized(cx.tcx, cx.param_env)
26+
{
27+
let mut app = Applicability::MachineApplicable;
28+
let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app);
29+
let turbofish = match &cast_to_hir_ty.kind {
30+
TyKind::Infer => String::new(),
31+
TyKind::Ptr(mut_ty) => {
32+
if matches!(mut_ty.ty.kind, TyKind::Infer) {
33+
String::new()
34+
} else {
35+
format!(
36+
"::<{}>",
37+
snippet_with_applicability(cx, mut_ty.ty.span, "/* type */", &mut app)
38+
)
39+
}
40+
},
41+
_ => return,
42+
};
43+
44+
span_lint_and_sugg(
45+
cx,
46+
PTR_AS_PTR,
47+
expr.span,
48+
"`as` casting between raw pointers without changing its mutability",
49+
"try `pointer::cast`, a safer alternative",
50+
format!("{}.cast{turbofish}()", cast_expr_sugg.maybe_par()),
51+
app,
52+
);
4753
}
4854
}

tests/ui/ptr_as_ptr.fixed

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,22 @@
33

44
#![warn(clippy::ptr_as_ptr)]
55

6+
#[macro_use]
67
extern crate proc_macros;
7-
use proc_macros::{external, inline_macros};
8+
9+
mod issue_11278_a {
10+
#[derive(Debug)]
11+
pub struct T<D: std::fmt::Debug + ?Sized> {
12+
pub p: D,
13+
}
14+
}
15+
16+
mod issue_11278_b {
17+
pub fn f(o: &mut super::issue_11278_a::T<dyn std::fmt::Debug>) -> super::issue_11278_a::T<String> {
18+
// Retain `super`
19+
*unsafe { Box::from_raw(Box::into_raw(Box::new(o)).cast::<super::issue_11278_a::T<String>>()) }
20+
}
21+
}
822

923
#[inline_macros]
1024
fn main() {

tests/ui/ptr_as_ptr.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,22 @@
33

44
#![warn(clippy::ptr_as_ptr)]
55

6+
#[macro_use]
67
extern crate proc_macros;
7-
use proc_macros::{external, inline_macros};
8+
9+
mod issue_11278_a {
10+
#[derive(Debug)]
11+
pub struct T<D: std::fmt::Debug + ?Sized> {
12+
pub p: D,
13+
}
14+
}
15+
16+
mod issue_11278_b {
17+
pub fn f(o: &mut super::issue_11278_a::T<dyn std::fmt::Debug>) -> super::issue_11278_a::T<String> {
18+
// Retain `super`
19+
*unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T<String>) }
20+
}
21+
}
822

923
#[inline_macros]
1024
fn main() {

tests/ui/ptr_as_ptr.stderr

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,60 @@
11
error: `as` casting between raw pointers without changing its mutability
2-
--> $DIR/ptr_as_ptr.rs:14:13
2+
--> $DIR/ptr_as_ptr.rs:19:33
33
|
4-
LL | let _ = ptr as *const i32;
5-
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
4+
LL | *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T<String>) }
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `Box::into_raw(Box::new(o)).cast::<super::issue_11278_a::T<String>>()`
66
|
77
= note: `-D clippy::ptr-as-ptr` implied by `-D warnings`
88

99
error: `as` casting between raw pointers without changing its mutability
10-
--> $DIR/ptr_as_ptr.rs:15:13
10+
--> $DIR/ptr_as_ptr.rs:28:13
11+
|
12+
LL | let _ = ptr as *const i32;
13+
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
14+
15+
error: `as` casting between raw pointers without changing its mutability
16+
--> $DIR/ptr_as_ptr.rs:29:13
1117
|
1218
LL | let _ = mut_ptr as *mut i32;
1319
| ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
1420

1521
error: `as` casting between raw pointers without changing its mutability
16-
--> $DIR/ptr_as_ptr.rs:20:17
22+
--> $DIR/ptr_as_ptr.rs:34:17
1723
|
1824
LL | let _ = *ptr_ptr as *const i32;
1925
| ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::<i32>()`
2026

2127
error: `as` casting between raw pointers without changing its mutability
22-
--> $DIR/ptr_as_ptr.rs:33:25
28+
--> $DIR/ptr_as_ptr.rs:47:25
2329
|
2430
LL | let _: *const i32 = ptr as *const _;
2531
| ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()`
2632

2733
error: `as` casting between raw pointers without changing its mutability
28-
--> $DIR/ptr_as_ptr.rs:34:23
34+
--> $DIR/ptr_as_ptr.rs:48:23
2935
|
3036
LL | let _: *mut i32 = mut_ptr as _;
3137
| ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()`
3238

3339
error: `as` casting between raw pointers without changing its mutability
34-
--> $DIR/ptr_as_ptr.rs:37:21
40+
--> $DIR/ptr_as_ptr.rs:51:21
3541
|
3642
LL | let _ = inline!($ptr as *const i32);
3743
| ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::<i32>()`
3844
|
3945
= note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
4046

4147
error: `as` casting between raw pointers without changing its mutability
42-
--> $DIR/ptr_as_ptr.rs:58:13
48+
--> $DIR/ptr_as_ptr.rs:72:13
4349
|
4450
LL | let _ = ptr as *const i32;
4551
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
4652

4753
error: `as` casting between raw pointers without changing its mutability
48-
--> $DIR/ptr_as_ptr.rs:59:13
54+
--> $DIR/ptr_as_ptr.rs:73:13
4955
|
5056
LL | let _ = mut_ptr as *mut i32;
5157
| ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
5258

53-
error: aborting due to 8 previous errors
59+
error: aborting due to 9 previous errors
5460

0 commit comments

Comments
 (0)