|
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,47 @@ 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 | + /// struct UwU; |
| 573 | + /// impl UwU { |
| 574 | + /// // intent: turn a `&UwU` into a `*const u8` that points to the same data |
| 575 | + /// fn as_ptr(&self) -> *const u8 { |
| 576 | + /// // ⚠️ `&self` is a `&&UwU`, so this turns a double pointer into a single pointer |
| 577 | + /// // ⚠️ This pointer is a dangling pointer to a local |
| 578 | + /// &self as *const _ as *const u8 |
| 579 | + /// } |
| 580 | + /// } |
| 581 | + /// ``` |
| 582 | + /// Use instead: |
| 583 | + /// ```rust |
| 584 | + /// struct UwU; |
| 585 | + /// impl UwU { |
| 586 | + /// // intent: turn a `&UwU` into a `*const u8` that points to the same data |
| 587 | + /// fn as_ptr(&self) -> *const u8 { |
| 588 | + /// // ⚠️ This pointer is still a dangling pointer to a local |
| 589 | + /// // ⚠️ But now the error is explicit in the type |
| 590 | + /// &self as *const &UwU as *const u8 |
| 591 | + /// } |
| 592 | + /// } |
| 593 | + /// ``` |
| 594 | + #[clippy::version = "1.70.0"] |
| 595 | + pub AS_UNDERSCORE_PTR, |
| 596 | + pedantic, |
| 597 | + "detects `as *{const,mut} _ conversions" |
| 598 | +} |
| 599 | + |
558 | 600 | declare_clippy_lint! {
|
559 | 601 | /// ### What it does
|
560 | 602 | /// Checks for the usage of `&expr as *const T` or
|
@@ -693,6 +735,7 @@ impl_lint_pass!(Casts => [
|
693 | 735 | CAST_ENUM_CONSTRUCTOR,
|
694 | 736 | CAST_ABS_TO_UNSIGNED,
|
695 | 737 | AS_UNDERSCORE,
|
| 738 | + AS_UNDERSCORE_PTR, |
696 | 739 | BORROW_AS_PTR,
|
697 | 740 | CAST_SLICE_FROM_RAW_PARTS,
|
698 | 741 | AS_PTR_CAST_MUT,
|
@@ -741,6 +784,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
741 | 784 | }
|
742 | 785 |
|
743 | 786 | as_underscore::check(cx, expr, cast_to_hir);
|
| 787 | + as_underscore_ptr::check(cx, expr, cast_to_hir); |
744 | 788 |
|
745 | 789 | if self.msrv.meets(msrvs::BORROW_AS_PTR) {
|
746 | 790 | borrow_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
|
|
0 commit comments