|
1 | 1 | mod as_ptr_cast_mut;
|
2 | 2 | mod as_underscore;
|
| 3 | +mod as_underscore_ptr; |
3 | 4 | mod borrow_as_ptr;
|
4 | 5 | mod cast_abs_to_unsigned;
|
5 | 6 | mod cast_enum_constructor;
|
@@ -555,6 +556,52 @@ declare_clippy_lint! {
|
555 | 556 | "detects `as _` conversion"
|
556 | 557 | }
|
557 | 558 |
|
| 559 | +declare_clippy_lint! { |
| 560 | + /// ### What it does |
| 561 | + /// Checks for the usage of `as *const _` or `as *mut _` where the pointed to type is inferred. |
| 562 | + /// |
| 563 | + /// ### Why is this bad? |
| 564 | + /// When converting to a pointer, it can be dangerous to not specify the type. Type inference can |
| 565 | + /// be affected by many things, types may not always be obvious, and when working with pointers, while |
| 566 | + /// the pointed to type doesn't technically matter until an access, you should always know what types |
| 567 | + /// you intend to work with. When using multiple chained `as` casts, it can be especially dangerous, |
| 568 | + /// because `*const T as *const U` **always compiles** (for Sized types T and U). |
| 569 | + /// |
| 570 | + /// ### Example |
| 571 | + /// ```rust |
| 572 | + /// // intent: turn a `&u64` into a `*const u8` that points to the bytes of the u64 (⚠️does not work⚠️) |
| 573 | + /// fn owo(x: &u64) -> *const u8 { |
| 574 | + /// // ⚠️ `&x` is a `&&u64`, so this turns a double pointer into a single pointer |
| 575 | + /// // ⚠️ This pointer is a dangling pointer to a local |
| 576 | + /// &x as *const _ as *const u8 |
| 577 | + /// } |
| 578 | + /// ``` |
| 579 | + /// Use instead: |
| 580 | + /// ```rust |
| 581 | + /// // intent: turn a `&u64` into a `*const u8` that points to the bytes of the u64 (⚠️does not work⚠️) |
| 582 | + /// fn owo(x: &u64) -> *const u8 { |
| 583 | + /// // ⚠️ `&x` is a `&&u64`, so this turns a double pointer into a single pointer |
| 584 | + /// // ⚠️ This pointer is a dangling pointer to a local |
| 585 | + /// &x as *const &u64 as *const u8 |
| 586 | + /// } |
| 587 | + /// ``` |
| 588 | + /// While this is still buggy, the bug is more visible here: you have a `*const &u64`. To actually fix the |
| 589 | + /// underlying issue, use: |
| 590 | + /// ```rust |
| 591 | + /// // turn a `&u64` into a `*const u8` that points to the bytes of the u64 |
| 592 | + /// fn owo(x: &u64) -> *const u8 { |
| 593 | + /// x as *const u64 as *const u8 |
| 594 | + /// // ^ now `x` instead of `&x` |
| 595 | + /// } |
| 596 | + /// ``` |
| 597 | + /// This lint cannot suggest this final code because it's a more broad `restriction` lint that forces the |
| 598 | + /// user to be more specific, and this transformation is not always valid. |
| 599 | + #[clippy::version = "1.70.0"] |
| 600 | + pub AS_UNDERSCORE_PTR, |
| 601 | + restriction, |
| 602 | + "detects `as *{const,mut} _ conversions" |
| 603 | +} |
| 604 | + |
558 | 605 | declare_clippy_lint! {
|
559 | 606 | /// ### What it does
|
560 | 607 | /// Checks for the usage of `&expr as *const T` or
|
@@ -693,6 +740,7 @@ impl_lint_pass!(Casts => [
|
693 | 740 | CAST_ENUM_CONSTRUCTOR,
|
694 | 741 | CAST_ABS_TO_UNSIGNED,
|
695 | 742 | AS_UNDERSCORE,
|
| 743 | + AS_UNDERSCORE_PTR, |
696 | 744 | BORROW_AS_PTR,
|
697 | 745 | CAST_SLICE_FROM_RAW_PARTS,
|
698 | 746 | AS_PTR_CAST_MUT,
|
@@ -741,6 +789,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
741 | 789 | }
|
742 | 790 |
|
743 | 791 | as_underscore::check(cx, expr, cast_to_hir);
|
| 792 | + as_underscore_ptr::check(cx, expr, cast_to_hir); |
744 | 793 |
|
745 | 794 | if self.msrv.meets(msrvs::BORROW_AS_PTR) {
|
746 | 795 | borrow_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
|
|
0 commit comments