Skip to content

Commit eed04f6

Browse files
authored
clippy: avoid invalid ref_as_ptr suggestions in const/static initializers (#17415)
Fixes #13910. `ref_as_ptr` can suggest `std::ptr::from_ref`/`std::ptr::from_mut` for nested reference-to-raw-pointer casts inside `const` and `static` initializers. The suggested replacement then fails during const evaluation. The existing guard only checks the immediate expression use site, which misses nested cast expressions. Extend it to also check whether the expression is inside an always-const context using `is_inside_always_const_context`. ### Testing - Added a regression test reproducing the reported nested `static mut` case. - Ran the `ref_as_ptr` UI tests. changelog: [`ref_as_ptr`]: avoid invalid suggestions in const/static initializers
2 parents 4814577 + d728c37 commit eed04f6

4 files changed

Lines changed: 26 additions & 14 deletions

File tree

clippy_lints/src/casts/ref_as_ptr.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +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, get_expr_use_site, is_expr_temporary_value, std_or_core};
4+
use clippy_utils::{
5+
ExprUseNode, get_expr_use_site, is_expr_temporary_value, is_inside_always_const_context, std_or_core,
6+
};
57
use rustc_errors::Applicability;
68
use rustc_hir::{Expr, ExprKind, Mutability, Ty, TyKind};
79
use rustc_lint::LateContext;
@@ -26,10 +28,10 @@ pub(super) fn check<'tcx>(
2628
{
2729
if let ExprKind::AddrOf(_, _, addr_inner) = cast_expr.kind
2830
&& is_expr_temporary_value(cx, addr_inner)
29-
&& matches!(
31+
&& (matches!(
3032
get_expr_use_site(cx.tcx, cx.typeck_results(), expr.span.ctxt(), expr).use_node(cx),
3133
ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_)
32-
)
34+
) || is_inside_always_const_context(cx.tcx, expr.hir_id))
3335
{
3436
return;
3537
}

tests/ui/ref_as_ptr.fixed

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ fn main() {
9999
let _ = &String::new() as *const _;
100100
let _ = &mut String::new() as *mut _;
101101
const FOO: *const String = &String::new() as *const _;
102+
103+
// Regression test for #13910.
104+
// This should not lint because the suggested replacement fails during
105+
// const evaluation.
106+
static mut REGRESSION: *mut i32 = &mut [42] as *mut [i32] as *mut i32;
102107
}
103108

104109
#[clippy::msrv = "1.75"]

tests/ui/ref_as_ptr.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ fn main() {
9999
let _ = &String::new() as *const _;
100100
let _ = &mut String::new() as *mut _;
101101
const FOO: *const String = &String::new() as *const _;
102+
103+
// Regression test for #13910.
104+
// This should not lint because the suggested replacement fails during
105+
// const evaluation.
106+
static mut REGRESSION: *mut i32 = &mut [42] as *mut [i32] as *mut i32;
102107
}
103108

104109
#[clippy::msrv = "1.75"]

tests/ui/ref_as_ptr.stderr

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -218,67 +218,67 @@ LL | let _ = &*x as *const _;
218218
| ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&*x)`
219219

220220
error: reference as raw pointer
221-
--> tests/ui/ref_as_ptr.rs:119:7
221+
--> tests/ui/ref_as_ptr.rs:124:7
222222
|
223223
LL | f(val as *const i32);
224224
| ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<i32>(val)`
225225

226226
error: reference as raw pointer
227-
--> tests/ui/ref_as_ptr.rs:121:7
227+
--> tests/ui/ref_as_ptr.rs:126:7
228228
|
229229
LL | f(mut_val as *mut i32);
230230
| ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<i32>(mut_val)`
231231

232232
error: reference as raw pointer
233-
--> tests/ui/ref_as_ptr.rs:126:7
233+
--> tests/ui/ref_as_ptr.rs:131:7
234234
|
235235
LL | f(val as *const _);
236236
| ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(val)`
237237

238238
error: reference as raw pointer
239-
--> tests/ui/ref_as_ptr.rs:128:7
239+
--> tests/ui/ref_as_ptr.rs:133:7
240240
|
241241
LL | f(val as *const [u8]);
242242
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[u8]>(val)`
243243

244244
error: reference as raw pointer
245-
--> tests/ui/ref_as_ptr.rs:133:7
245+
--> tests/ui/ref_as_ptr.rs:138:7
246246
|
247247
LL | f(val as *mut _);
248248
| ^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(val)`
249249

250250
error: reference as raw pointer
251-
--> tests/ui/ref_as_ptr.rs:135:7
251+
--> tests/ui/ref_as_ptr.rs:140:7
252252
|
253253
LL | f(val as *mut str);
254254
| ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<str>(val)`
255255

256256
error: reference as raw pointer
257-
--> tests/ui/ref_as_ptr.rs:143:9
257+
--> tests/ui/ref_as_ptr.rs:148:9
258258
|
259259
LL | self.0 as *const _ as *const _
260260
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
261261

262262
error: reference as raw pointer
263-
--> tests/ui/ref_as_ptr.rs:148:9
263+
--> tests/ui/ref_as_ptr.rs:153:9
264264
|
265265
LL | self.0 as *const _ as *const _
266266
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
267267

268268
error: reference as raw pointer
269-
--> tests/ui/ref_as_ptr.rs:157:9
269+
--> tests/ui/ref_as_ptr.rs:162:9
270270
|
271271
LL | self.0 as *const _ as *const _
272272
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
273273

274274
error: reference as raw pointer
275-
--> tests/ui/ref_as_ptr.rs:162:9
275+
--> tests/ui/ref_as_ptr.rs:167:9
276276
|
277277
LL | self.0 as *const _ as *const _
278278
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
279279

280280
error: reference as raw pointer
281-
--> tests/ui/ref_as_ptr.rs:167:9
281+
--> tests/ui/ref_as_ptr.rs:172:9
282282
|
283283
LL | self.0 as *mut _ as *mut _
284284
| ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(self.0)`

0 commit comments

Comments
 (0)