Skip to content

Commit 7f866c7

Browse files
authored
New lint for as *const _ and as *mut _ pointer casts (#13251)
changelog: New lint for as *const _ and as *mut _ pointer casts EDIT: lets go with the simpler version
2 parents 5198941 + 1496711 commit 7f866c7

7 files changed

+98
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5380,6 +5380,7 @@ Released 2018-09-13
53805380
[`arc_with_non_send_sync`]: https://rust-lang.github.io/rust-clippy/master/index.html#arc_with_non_send_sync
53815381
[`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects
53825382
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
5383+
[`as_pointer_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_pointer_underscore
53835384
[`as_ptr_cast_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_ptr_cast_mut
53845385
[`as_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore
53855386
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use rustc_errors::Applicability;
2+
use rustc_lint::LateContext;
3+
use rustc_middle::ty::Ty;
4+
5+
pub fn check<'tcx>(cx: &LateContext<'tcx>, ty_into: Ty<'_>, cast_to_hir: &'tcx rustc_hir::Ty<'tcx>) {
6+
if let rustc_hir::TyKind::Ptr(rustc_hir::MutTy { ty, .. }) = cast_to_hir.kind
7+
&& matches!(ty.kind, rustc_hir::TyKind::Infer)
8+
{
9+
clippy_utils::diagnostics::span_lint_and_sugg(
10+
cx,
11+
super::AS_POINTER_UNDERSCORE,
12+
cast_to_hir.span,
13+
"using inferred pointer cast",
14+
"use explicit type",
15+
ty_into.to_string(),
16+
Applicability::MachineApplicable,
17+
);
18+
}
19+
}

clippy_lints/src/casts/mod.rs

+30
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod as_pointer_underscore;
12
mod as_ptr_cast_mut;
23
mod as_underscore;
34
mod borrow_as_ptr;
@@ -726,6 +727,33 @@ declare_clippy_lint! {
726727
"using `as` to cast a reference to pointer"
727728
}
728729

730+
declare_clippy_lint! {
731+
/// ### What it does
732+
/// Checks for the usage of `as *const _` or `as *mut _` conversion using inferred type.
733+
///
734+
/// ### Why restrict this?
735+
/// The conversion might include a dangerous cast that might go undetected due to the type being inferred.
736+
///
737+
/// ### Example
738+
/// ```no_run
739+
/// fn as_usize<T>(t: &T) -> usize {
740+
/// // BUG: `t` is already a reference, so we will here
741+
/// // return a dangling pointer to a temporary value instead
742+
/// &t as *const _ as usize
743+
/// }
744+
/// ```
745+
/// Use instead:
746+
/// ```no_run
747+
/// fn as_usize<T>(t: &T) -> usize {
748+
/// t as *const T as usize
749+
/// }
750+
/// ```
751+
#[clippy::version = "1.81.0"]
752+
pub AS_POINTER_UNDERSCORE,
753+
restriction,
754+
"detects `as *mut _` and `as *const _` conversion"
755+
}
756+
729757
pub struct Casts {
730758
msrv: Msrv,
731759
}
@@ -763,6 +791,7 @@ impl_lint_pass!(Casts => [
763791
CAST_NAN_TO_INT,
764792
ZERO_PTR,
765793
REF_AS_PTR,
794+
AS_POINTER_UNDERSCORE,
766795
]);
767796

768797
impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -805,6 +834,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
805834
}
806835

807836
as_underscore::check(cx, expr, cast_to_hir);
837+
as_pointer_underscore::check(cx, cast_to, cast_to_hir);
808838

809839
let was_borrow_as_ptr_emitted = if self.msrv.meets(msrvs::BORROW_AS_PTR) {
810840
borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir, &self.msrv)

clippy_lints/src/declared_lints.rs

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
7575
crate::cargo::NEGATIVE_FEATURE_NAMES_INFO,
7676
crate::cargo::REDUNDANT_FEATURE_NAMES_INFO,
7777
crate::cargo::WILDCARD_DEPENDENCIES_INFO,
78+
crate::casts::AS_POINTER_UNDERSCORE_INFO,
7879
crate::casts::AS_PTR_CAST_MUT_INFO,
7980
crate::casts::AS_UNDERSCORE_INFO,
8081
crate::casts::BORROW_AS_PTR_INFO,

tests/ui/as_pointer_underscore.fixed

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![warn(clippy::as_pointer_underscore)]
2+
#![crate_type = "lib"]
3+
#![no_std]
4+
5+
struct S;
6+
7+
fn f(s: &S) -> usize {
8+
&s as *const &S as usize
9+
//~^ ERROR: using inferred pointer cast
10+
}
11+
12+
fn g(s: &mut S) -> usize {
13+
s as *mut S as usize
14+
//~^ ERROR: using inferred pointer cast
15+
}

tests/ui/as_pointer_underscore.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![warn(clippy::as_pointer_underscore)]
2+
#![crate_type = "lib"]
3+
#![no_std]
4+
5+
struct S;
6+
7+
fn f(s: &S) -> usize {
8+
&s as *const _ as usize
9+
//~^ ERROR: using inferred pointer cast
10+
}
11+
12+
fn g(s: &mut S) -> usize {
13+
s as *mut _ as usize
14+
//~^ ERROR: using inferred pointer cast
15+
}

tests/ui/as_pointer_underscore.stderr

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: using inferred pointer cast
2+
--> tests/ui/as_pointer_underscore.rs:8:11
3+
|
4+
LL | &s as *const _ as usize
5+
| ^^^^^^^^ help: use explicit type: `*const &S`
6+
|
7+
= note: `-D clippy::as-pointer-underscore` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::as_pointer_underscore)]`
9+
10+
error: using inferred pointer cast
11+
--> tests/ui/as_pointer_underscore.rs:13:10
12+
|
13+
LL | s as *mut _ as usize
14+
| ^^^^^^ help: use explicit type: `*mut S`
15+
16+
error: aborting due to 2 previous errors
17+

0 commit comments

Comments
 (0)