Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement new lint for detecting buggy pointer-to-int casts #81789

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2876,6 +2876,46 @@ declare_lint! {
};
}

declare_lint! {
/// The `invalid_ptr_to_int_cast` lint triggers if a pointer is cast to any integer type other
/// than `usize` or `u64`, since doing so is often a bug.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(invalid_ptr_to_int_cast)]
///
/// fn main() {
/// let x = 100_000_000;
/// let y = u16::max as u32; // the user meant the constant `u16::MAX`, rather than the
/// // function `u16::max`, but this cast is technically permitted,
/// // so will not produce an error
/// println!("{}", x > y); // prints `false` (unexpectedly)
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The example above shows how a user might accidentally cast a function pointer (rather than
/// an integer constant) to an integer type other than `usize` or `u64`. Though this is
/// currently permitted by Rust, there is very little reason to cast a pointer to any integer
/// other than a `usize` or `u64`. Therefore, any instances of such casts are likely to be
/// bugs.
///
/// This lint warns against those cases.
///
/// In the future, we may want to make this a hard error.
///
/// To cast a pointer to an integer type other than `usize` or `u64` without triggering the
/// lint, you can first cast to a `usize` and then to the integer type, e.g. `ptr as usize as
/// u32`.
pub INVALID_PTR_TO_INT_CAST,
Deny,
"detects pointers casts to integer types other than `usize` or `u64`",
}

declare_lint_pass! {
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
Expand Down Expand Up @@ -2960,6 +3000,7 @@ declare_lint_pass! {
LEGACY_DERIVE_HELPERS,
PROC_MACRO_BACK_COMPAT,
OR_PATTERNS_BACK_COMPAT,
INVALID_PTR_TO_INT_CAST,
]
}

Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1946,6 +1946,11 @@ impl<'tcx> TyS<'tcx> {
matches!(self.kind(), FnPtr(_))
}

#[inline]
pub fn is_raw_ptr(&self) -> bool {
matches!(self.kind(), RawPtr(_))
}

#[inline]
pub fn is_impl_trait(&self) -> bool {
matches!(self.kind(), Opaque(..))
Expand Down
Loading