Skip to content

Commit f206ef8

Browse files
authored
Fix clippy::ref_as_ptr for non-temporary references in let/const (#16214)
Fix `ref_as_ptr` false positives for temporary values and let/static/const initializers. Fixes #16220 changelog: [`ref_as_ptr`]: Only lint on non-temporary expressions)
2 parents d06ae84 + aefb01b commit f206ef8

File tree

4 files changed

+62
-16
lines changed

4 files changed

+62
-16
lines changed

clippy_lints/src/casts/ref_as_ptr.rs

Lines changed: 12 additions & 4 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::{ExprUseNode, expr_use_ctxt, 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

@@ -23,10 +23,18 @@ pub(super) fn check<'tcx>(
2323
if matches!(cast_from.kind(), ty::Ref(..))
2424
&& let ty::RawPtr(_, to_mutbl) = cast_to.kind()
2525
&& 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(_))
2826
&& let Some(std_or_core) = std_or_core(cx)
2927
{
28+
if let ExprKind::AddrOf(_, _, addr_inner) = cast_expr.kind
29+
&& is_expr_temporary_value(cx, addr_inner)
30+
&& matches!(
31+
use_cx.use_node(cx),
32+
ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_)
33+
)
34+
{
35+
return;
36+
}
37+
3038
let fn_name = match to_mutbl {
3139
Mutability::Not => "from_ref",
3240
Mutability::Mut => "from_mut",

tests/ui/ref_as_ptr.fixed

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ fn main() {
8686
f(std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i)));
8787
//~^ ref_as_ptr
8888

89+
let x = (10, 20);
90+
let _ = std::ptr::from_ref(&x);
91+
//~^ ref_as_ptr
92+
let _ = std::ptr::from_ref(&x.0);
93+
//~^ ref_as_ptr
94+
95+
let x = Box::new(10);
96+
let _ = std::ptr::from_ref(&*x);
97+
//~^ ref_as_ptr
98+
8999
let _ = &String::new() as *const _;
90100
let _ = &mut String::new() as *mut _;
91101
const FOO: *const String = &String::new() as *const _;

tests/ui/ref_as_ptr.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ fn main() {
8686
f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]);
8787
//~^ ref_as_ptr
8888

89+
let x = (10, 20);
90+
let _ = &x as *const _;
91+
//~^ ref_as_ptr
92+
let _ = &x.0 as *const _;
93+
//~^ ref_as_ptr
94+
95+
let x = Box::new(10);
96+
let _ = &*x as *const _;
97+
//~^ ref_as_ptr
98+
8999
let _ = &String::new() as *const _;
90100
let _ = &mut String::new() as *mut _;
91101
const FOO: *const String = &String::new() as *const _;

tests/ui/ref_as_ptr.stderr

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -200,70 +200,88 @@ LL | f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]);
200200
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i))`
201201

202202
error: reference as raw pointer
203-
--> tests/ui/ref_as_ptr.rs:109:7
203+
--> tests/ui/ref_as_ptr.rs:90:13
204+
|
205+
LL | let _ = &x as *const _;
206+
| ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&x)`
207+
208+
error: reference as raw pointer
209+
--> tests/ui/ref_as_ptr.rs:92:13
210+
|
211+
LL | let _ = &x.0 as *const _;
212+
| ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&x.0)`
213+
214+
error: reference as raw pointer
215+
--> tests/ui/ref_as_ptr.rs:96:13
216+
|
217+
LL | let _ = &*x as *const _;
218+
| ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&*x)`
219+
220+
error: reference as raw pointer
221+
--> tests/ui/ref_as_ptr.rs:119:7
204222
|
205223
LL | f(val as *const i32);
206224
| ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<i32>(val)`
207225

208226
error: reference as raw pointer
209-
--> tests/ui/ref_as_ptr.rs:111:7
227+
--> tests/ui/ref_as_ptr.rs:121:7
210228
|
211229
LL | f(mut_val as *mut i32);
212230
| ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<i32>(mut_val)`
213231

214232
error: reference as raw pointer
215-
--> tests/ui/ref_as_ptr.rs:116:7
233+
--> tests/ui/ref_as_ptr.rs:126:7
216234
|
217235
LL | f(val as *const _);
218236
| ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(val)`
219237

220238
error: reference as raw pointer
221-
--> tests/ui/ref_as_ptr.rs:118:7
239+
--> tests/ui/ref_as_ptr.rs:128:7
222240
|
223241
LL | f(val as *const [u8]);
224242
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[u8]>(val)`
225243

226244
error: reference as raw pointer
227-
--> tests/ui/ref_as_ptr.rs:123:7
245+
--> tests/ui/ref_as_ptr.rs:133:7
228246
|
229247
LL | f(val as *mut _);
230248
| ^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(val)`
231249

232250
error: reference as raw pointer
233-
--> tests/ui/ref_as_ptr.rs:125:7
251+
--> tests/ui/ref_as_ptr.rs:135:7
234252
|
235253
LL | f(val as *mut str);
236254
| ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<str>(val)`
237255

238256
error: reference as raw pointer
239-
--> tests/ui/ref_as_ptr.rs:133:9
257+
--> tests/ui/ref_as_ptr.rs:143:9
240258
|
241259
LL | self.0 as *const _ as *const _
242260
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
243261

244262
error: reference as raw pointer
245-
--> tests/ui/ref_as_ptr.rs:138:9
263+
--> tests/ui/ref_as_ptr.rs:148:9
246264
|
247265
LL | self.0 as *const _ as *const _
248266
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
249267

250268
error: reference as raw pointer
251-
--> tests/ui/ref_as_ptr.rs:147:9
269+
--> tests/ui/ref_as_ptr.rs:157:9
252270
|
253271
LL | self.0 as *const _ as *const _
254272
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
255273

256274
error: reference as raw pointer
257-
--> tests/ui/ref_as_ptr.rs:152:9
275+
--> tests/ui/ref_as_ptr.rs:162:9
258276
|
259277
LL | self.0 as *const _ as *const _
260278
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
261279

262280
error: reference as raw pointer
263-
--> tests/ui/ref_as_ptr.rs:157:9
281+
--> tests/ui/ref_as_ptr.rs:167:9
264282
|
265283
LL | self.0 as *mut _ as *mut _
266284
| ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(self.0)`
267285

268-
error: aborting due to 44 previous errors
286+
error: aborting due to 47 previous errors
269287

0 commit comments

Comments
 (0)