Skip to content

Commit e767f7f

Browse files
committed
Fix clippy::ref_as_ptr for non-temporary references in let/const
1 parent 961ea1c commit e767f7f

File tree

4 files changed

+47
-195
lines changed

4 files changed

+47
-195
lines changed

clippy_lints/src/casts/ref_as_ptr.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::source::snippet_with_applicability;
33
use clippy_utils::sugg::Sugg;
4-
use clippy_utils::{ExprUseNode, expr_use_ctxt, std_or_core};
4+
use clippy_utils::{is_expr_temporary_value, std_or_core};
55
use rustc_errors::Applicability;
6-
use rustc_hir::{Expr, Mutability, Ty, TyKind};
6+
use rustc_hir::{Expr, ExprKind, Mutability, Ty, TyKind};
77
use rustc_lint::LateContext;
88
use rustc_middle::ty;
99

@@ -22,11 +22,17 @@ pub(super) fn check<'tcx>(
2222

2323
if matches!(cast_from.kind(), ty::Ref(..))
2424
&& let ty::RawPtr(_, to_mutbl) = cast_to.kind()
25-
&& let use_cx = expr_use_ctxt(cx, expr)
26-
// TODO: only block the lint if `cast_expr` is a temporary
27-
&& !matches!(use_cx.use_node(cx), ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_))
2825
&& let Some(std_or_core) = std_or_core(cx)
2926
{
27+
if let ExprKind::AddrOf(_, _, addr_inner) = cast_expr.kind
28+
&& is_expr_temporary_value(cx, addr_inner)
29+
{
30+
// This IS the dangerous case. Let the lint proceed.
31+
} else {
32+
// This is a safe, long-lived reference (e.g., &x, &static).
33+
// The lint is unnecessary, so we return early.
34+
return;
35+
}
3036
let fn_name = match to_mutbl {
3137
Mutability::Not => "from_ref",
3238
Mutability::Mut => "from_mut",

tests/ui/ref_as_ptr.fixed

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -53,31 +53,21 @@ fn main() {
5353
//~^ ref_as_ptr
5454

5555
let val = 1;
56-
f(std::ptr::from_ref(&val));
57-
//~^ ref_as_ptr
58-
f(std::ptr::from_ref::<i32>(&val));
59-
//~^ ref_as_ptr
56+
f(&val as *const _);
57+
f(&val as *const i32);
6058

61-
f(std::ptr::from_ref(&val) as *const f32);
62-
//~^ ref_as_ptr
63-
f(std::ptr::from_ref::<i32>(&val) as *const f64);
64-
//~^ ref_as_ptr
59+
f(&val as *const _ as *const f32);
60+
f(&val as *const i32 as *const f64);
6561

6662
let mut val: u8 = 2;
67-
f(std::ptr::from_mut::<u8>(&mut val));
68-
//~^ ref_as_ptr
69-
f(std::ptr::from_mut(&mut val));
70-
//~^ ref_as_ptr
63+
f(&mut val as *mut u8);
64+
f(&mut val as *mut _);
7165

72-
f(std::ptr::from_ref::<u8>(&mut val));
73-
//~^ ref_as_ptr
74-
f(std::ptr::from_ref(&mut val));
75-
//~^ ref_as_ptr
66+
f(&mut val as *const u8);
67+
f(&mut val as *const _);
7668

77-
f(std::ptr::from_ref::<u8>(&mut val) as *const f64);
78-
//~^ ref_as_ptr
79-
f::<*const Option<u8>>(std::ptr::from_ref(&mut val) as *const _);
80-
//~^ ref_as_ptr
69+
f(&mut val as *const u8 as *const f64);
70+
f::<*const Option<u8>>(&mut val as *const _ as *const _);
8171

8272
f(std::ptr::from_ref::<[usize; 7]>(&std::array::from_fn(|i| i * i)));
8373
//~^ ref_as_ptr
@@ -86,9 +76,10 @@ fn main() {
8676
f(std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i)));
8777
//~^ ref_as_ptr
8878

89-
let _ = &String::new() as *const _;
90-
let _ = &mut String::new() as *mut _;
91-
const FOO: *const String = &String::new() as *const _;
79+
let _ = std::ptr::from_ref(&String::new());
80+
//~^ ref_as_ptr
81+
let _ = std::ptr::from_mut(&mut String::new());
82+
//~^ ref_as_ptr
9283
}
9384

9485
#[clippy::msrv = "1.75"]
@@ -106,55 +97,44 @@ fn _msrv_1_76() {
10697
let val = &42_i32;
10798
let mut_val = &mut 42_i32;
10899

109-
f(std::ptr::from_ref::<i32>(val));
110-
//~^ ref_as_ptr
111-
f(std::ptr::from_mut::<i32>(mut_val));
112-
//~^ ref_as_ptr
100+
f(val as *const i32);
101+
f(mut_val as *mut i32);
113102
}
114103

115104
fn foo(val: &[u8]) {
116-
f(std::ptr::from_ref(val));
117-
//~^ ref_as_ptr
118-
f(std::ptr::from_ref::<[u8]>(val));
119-
//~^ ref_as_ptr
105+
f(val as *const _);
106+
f(val as *const [u8]);
120107
}
121108

122109
fn bar(val: &mut str) {
123-
f(std::ptr::from_mut(val));
124-
//~^ ref_as_ptr
125-
f(std::ptr::from_mut::<str>(val));
126-
//~^ ref_as_ptr
110+
f(val as *mut _);
111+
f(val as *mut str);
127112
}
128113

129114
struct X<'a>(&'a i32);
130115

131116
impl<'a> X<'a> {
132117
fn foo(&self) -> *const i64 {
133-
std::ptr::from_ref(self.0) as *const _
134-
//~^ ref_as_ptr
118+
self.0 as *const _ as *const _
135119
}
136120

137121
fn bar(&mut self) -> *const i64 {
138-
std::ptr::from_ref(self.0) as *const _
139-
//~^ ref_as_ptr
122+
self.0 as *const _ as *const _
140123
}
141124
}
142125

143126
struct Y<'a>(&'a mut i32);
144127

145128
impl<'a> Y<'a> {
146129
fn foo(&self) -> *const i64 {
147-
std::ptr::from_ref(self.0) as *const _
148-
//~^ ref_as_ptr
130+
self.0 as *const _ as *const _
149131
}
150132

151133
fn bar(&mut self) -> *const i64 {
152-
std::ptr::from_ref(self.0) as *const _
153-
//~^ ref_as_ptr
134+
self.0 as *const _ as *const _
154135
}
155136

156137
fn baz(&mut self) -> *const i64 {
157-
std::ptr::from_mut(self.0) as *mut _
158-
//~^ ref_as_ptr
138+
self.0 as *mut _ as *mut _
159139
}
160140
}

tests/ui/ref_as_ptr.rs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -54,30 +54,20 @@ fn main() {
5454

5555
let val = 1;
5656
f(&val as *const _);
57-
//~^ ref_as_ptr
5857
f(&val as *const i32);
59-
//~^ ref_as_ptr
6058

6159
f(&val as *const _ as *const f32);
62-
//~^ ref_as_ptr
6360
f(&val as *const i32 as *const f64);
64-
//~^ ref_as_ptr
6561

6662
let mut val: u8 = 2;
6763
f(&mut val as *mut u8);
68-
//~^ ref_as_ptr
6964
f(&mut val as *mut _);
70-
//~^ ref_as_ptr
7165

7266
f(&mut val as *const u8);
73-
//~^ ref_as_ptr
7467
f(&mut val as *const _);
75-
//~^ ref_as_ptr
7668

7769
f(&mut val as *const u8 as *const f64);
78-
//~^ ref_as_ptr
7970
f::<*const Option<u8>>(&mut val as *const _ as *const _);
80-
//~^ ref_as_ptr
8171

8272
f(&std::array::from_fn(|i| i * i) as *const [usize; 7]);
8373
//~^ ref_as_ptr
@@ -87,8 +77,9 @@ fn main() {
8777
//~^ ref_as_ptr
8878

8979
let _ = &String::new() as *const _;
80+
//~^ ref_as_ptr
9081
let _ = &mut String::new() as *mut _;
91-
const FOO: *const String = &String::new() as *const _;
82+
//~^ ref_as_ptr
9283
}
9384

9485
#[clippy::msrv = "1.75"]
@@ -107,36 +98,28 @@ fn _msrv_1_76() {
10798
let mut_val = &mut 42_i32;
10899

109100
f(val as *const i32);
110-
//~^ ref_as_ptr
111101
f(mut_val as *mut i32);
112-
//~^ ref_as_ptr
113102
}
114103

115104
fn foo(val: &[u8]) {
116105
f(val as *const _);
117-
//~^ ref_as_ptr
118106
f(val as *const [u8]);
119-
//~^ ref_as_ptr
120107
}
121108

122109
fn bar(val: &mut str) {
123110
f(val as *mut _);
124-
//~^ ref_as_ptr
125111
f(val as *mut str);
126-
//~^ ref_as_ptr
127112
}
128113

129114
struct X<'a>(&'a i32);
130115

131116
impl<'a> X<'a> {
132117
fn foo(&self) -> *const i64 {
133118
self.0 as *const _ as *const _
134-
//~^ ref_as_ptr
135119
}
136120

137121
fn bar(&mut self) -> *const i64 {
138122
self.0 as *const _ as *const _
139-
//~^ ref_as_ptr
140123
}
141124
}
142125

@@ -145,16 +128,13 @@ struct Y<'a>(&'a mut i32);
145128
impl<'a> Y<'a> {
146129
fn foo(&self) -> *const i64 {
147130
self.0 as *const _ as *const _
148-
//~^ ref_as_ptr
149131
}
150132

151133
fn bar(&mut self) -> *const i64 {
152134
self.0 as *const _ as *const _
153-
//~^ ref_as_ptr
154135
}
155136

156137
fn baz(&mut self) -> *const i64 {
157138
self.0 as *mut _ as *mut _
158-
//~^ ref_as_ptr
159139
}
160140
}

0 commit comments

Comments
 (0)