Move BorrowAsPtr into Casts lint pass
This commit is contained in:
@@ -1,99 +0,0 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
|
||||||
use clippy_utils::is_no_std_crate;
|
|
||||||
use clippy_utils::source::snippet_opt;
|
|
||||||
use clippy_utils::{meets_msrv, msrvs};
|
|
||||||
use if_chain::if_chain;
|
|
||||||
use rustc_errors::Applicability;
|
|
||||||
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, TyKind};
|
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
|
||||||
use rustc_semver::RustcVersion;
|
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|
||||||
|
|
||||||
declare_clippy_lint! {
|
|
||||||
/// ### What it does
|
|
||||||
/// Checks for the usage of `&expr as *const T` or
|
|
||||||
/// `&mut expr as *mut T`, and suggest using `ptr::addr_of` or
|
|
||||||
/// `ptr::addr_of_mut` instead.
|
|
||||||
///
|
|
||||||
/// ### Why is this bad?
|
|
||||||
/// This would improve readability and avoid creating a reference
|
|
||||||
/// that points to an uninitialized value or unaligned place.
|
|
||||||
/// Read the `ptr::addr_of` docs for more information.
|
|
||||||
///
|
|
||||||
/// ### Example
|
|
||||||
/// ```rust
|
|
||||||
/// let val = 1;
|
|
||||||
/// let p = &val as *const i32;
|
|
||||||
///
|
|
||||||
/// let mut val_mut = 1;
|
|
||||||
/// let p_mut = &mut val_mut as *mut i32;
|
|
||||||
/// ```
|
|
||||||
/// Use instead:
|
|
||||||
/// ```rust
|
|
||||||
/// let val = 1;
|
|
||||||
/// let p = std::ptr::addr_of!(val);
|
|
||||||
///
|
|
||||||
/// let mut val_mut = 1;
|
|
||||||
/// let p_mut = std::ptr::addr_of_mut!(val_mut);
|
|
||||||
/// ```
|
|
||||||
#[clippy::version = "1.60.0"]
|
|
||||||
pub BORROW_AS_PTR,
|
|
||||||
pedantic,
|
|
||||||
"borrowing just to cast to a raw pointer"
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_lint_pass!(BorrowAsPtr => [BORROW_AS_PTR]);
|
|
||||||
|
|
||||||
pub struct BorrowAsPtr {
|
|
||||||
msrv: Option<RustcVersion>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BorrowAsPtr {
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
|
||||||
Self { msrv }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for BorrowAsPtr {
|
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
|
||||||
if !meets_msrv(self.msrv, msrvs::BORROW_AS_PTR) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if expr.span.from_expansion() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if_chain! {
|
|
||||||
if let ExprKind::Cast(left_expr, ty) = &expr.kind;
|
|
||||||
if let TyKind::Ptr(_) = ty.kind;
|
|
||||||
if let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = &left_expr.kind;
|
|
||||||
|
|
||||||
then {
|
|
||||||
let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
|
|
||||||
let macro_name = match mutability {
|
|
||||||
Mutability::Not => "addr_of",
|
|
||||||
Mutability::Mut => "addr_of_mut",
|
|
||||||
};
|
|
||||||
|
|
||||||
span_lint_and_sugg(
|
|
||||||
cx,
|
|
||||||
BORROW_AS_PTR,
|
|
||||||
expr.span,
|
|
||||||
"borrow as raw pointer",
|
|
||||||
"try",
|
|
||||||
format!(
|
|
||||||
"{}::ptr::{}!({})",
|
|
||||||
core_or_std,
|
|
||||||
macro_name,
|
|
||||||
snippet_opt(cx, e.span).unwrap()
|
|
||||||
),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extract_msrv_attr!(LateContext);
|
|
||||||
}
|
|
||||||
37
clippy_lints/src/casts/borrow_as_ptr.rs
Normal file
37
clippy_lints/src/casts/borrow_as_ptr.rs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
|
use clippy_utils::is_no_std_crate;
|
||||||
|
use clippy_utils::source::snippet_with_context;
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};
|
||||||
|
use rustc_lint::LateContext;
|
||||||
|
|
||||||
|
use super::BORROW_AS_PTR;
|
||||||
|
|
||||||
|
pub(super) fn check<'tcx>(
|
||||||
|
cx: &LateContext<'tcx>,
|
||||||
|
expr: &'tcx Expr<'_>,
|
||||||
|
cast_expr: &'tcx Expr<'_>,
|
||||||
|
cast_to: &'tcx Ty<'_>,
|
||||||
|
) {
|
||||||
|
if matches!(cast_to.kind, TyKind::Ptr(_))
|
||||||
|
&& let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind
|
||||||
|
{
|
||||||
|
let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
|
||||||
|
let macro_name = match mutability {
|
||||||
|
Mutability::Not => "addr_of",
|
||||||
|
Mutability::Mut => "addr_of_mut",
|
||||||
|
};
|
||||||
|
let mut app = Applicability::MachineApplicable;
|
||||||
|
let snip = snippet_with_context(cx, e.span, cast_expr.span.ctxt(), "..", &mut app).0;
|
||||||
|
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
BORROW_AS_PTR,
|
||||||
|
expr.span,
|
||||||
|
"borrow as raw pointer",
|
||||||
|
"try",
|
||||||
|
format!("{}::ptr::{}!({})", core_or_std, macro_name, snip),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
mod as_underscore;
|
mod as_underscore;
|
||||||
|
mod borrow_as_ptr;
|
||||||
mod cast_abs_to_unsigned;
|
mod cast_abs_to_unsigned;
|
||||||
mod cast_enum_constructor;
|
mod cast_enum_constructor;
|
||||||
mod cast_lossless;
|
mod cast_lossless;
|
||||||
@@ -17,7 +18,7 @@ mod ptr_as_ptr;
|
|||||||
mod unnecessary_cast;
|
mod unnecessary_cast;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use clippy_utils::is_hir_ty_cfg_dependant;
|
use clippy_utils::{is_hir_ty_cfg_dependant, meets_msrv, msrvs};
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
@@ -535,6 +536,39 @@ declare_clippy_lint! {
|
|||||||
"detects `as _` conversion"
|
"detects `as _` conversion"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Checks for the usage of `&expr as *const T` or
|
||||||
|
/// `&mut expr as *mut T`, and suggest using `ptr::addr_of` or
|
||||||
|
/// `ptr::addr_of_mut` instead.
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
/// This would improve readability and avoid creating a reference
|
||||||
|
/// that points to an uninitialized value or unaligned place.
|
||||||
|
/// Read the `ptr::addr_of` docs for more information.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// let val = 1;
|
||||||
|
/// let p = &val as *const i32;
|
||||||
|
///
|
||||||
|
/// let mut val_mut = 1;
|
||||||
|
/// let p_mut = &mut val_mut as *mut i32;
|
||||||
|
/// ```
|
||||||
|
/// Use instead:
|
||||||
|
/// ```rust
|
||||||
|
/// let val = 1;
|
||||||
|
/// let p = std::ptr::addr_of!(val);
|
||||||
|
///
|
||||||
|
/// let mut val_mut = 1;
|
||||||
|
/// let p_mut = std::ptr::addr_of_mut!(val_mut);
|
||||||
|
/// ```
|
||||||
|
#[clippy::version = "1.60.0"]
|
||||||
|
pub BORROW_AS_PTR,
|
||||||
|
pedantic,
|
||||||
|
"borrowing just to cast to a raw pointer"
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Casts {
|
pub struct Casts {
|
||||||
msrv: Option<RustcVersion>,
|
msrv: Option<RustcVersion>,
|
||||||
}
|
}
|
||||||
@@ -565,6 +599,7 @@ impl_lint_pass!(Casts => [
|
|||||||
CAST_ENUM_CONSTRUCTOR,
|
CAST_ENUM_CONSTRUCTOR,
|
||||||
CAST_ABS_TO_UNSIGNED,
|
CAST_ABS_TO_UNSIGNED,
|
||||||
AS_UNDERSCORE,
|
AS_UNDERSCORE,
|
||||||
|
BORROW_AS_PTR,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for Casts {
|
impl<'tcx> LateLintPass<'tcx> for Casts {
|
||||||
@@ -607,6 +642,10 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
as_underscore::check(cx, expr, cast_to_hir);
|
as_underscore::check(cx, expr, cast_to_hir);
|
||||||
|
|
||||||
|
if meets_msrv(self.msrv, msrvs::BORROW_AS_PTR) {
|
||||||
|
borrow_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cast_ref_to_mut::check(cx, expr);
|
cast_ref_to_mut::check(cx, expr);
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ store.register_lints(&[
|
|||||||
bool_assert_comparison::BOOL_ASSERT_COMPARISON,
|
bool_assert_comparison::BOOL_ASSERT_COMPARISON,
|
||||||
booleans::NONMINIMAL_BOOL,
|
booleans::NONMINIMAL_BOOL,
|
||||||
booleans::OVERLY_COMPLEX_BOOL_EXPR,
|
booleans::OVERLY_COMPLEX_BOOL_EXPR,
|
||||||
borrow_as_ptr::BORROW_AS_PTR,
|
|
||||||
borrow_deref_ref::BORROW_DEREF_REF,
|
borrow_deref_ref::BORROW_DEREF_REF,
|
||||||
bytecount::NAIVE_BYTECOUNT,
|
bytecount::NAIVE_BYTECOUNT,
|
||||||
bytes_count_to_len::BYTES_COUNT_TO_LEN,
|
bytes_count_to_len::BYTES_COUNT_TO_LEN,
|
||||||
@@ -69,6 +68,7 @@ store.register_lints(&[
|
|||||||
cargo::WILDCARD_DEPENDENCIES,
|
cargo::WILDCARD_DEPENDENCIES,
|
||||||
case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
|
case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
|
||||||
casts::AS_UNDERSCORE,
|
casts::AS_UNDERSCORE,
|
||||||
|
casts::BORROW_AS_PTR,
|
||||||
casts::CAST_ABS_TO_UNSIGNED,
|
casts::CAST_ABS_TO_UNSIGNED,
|
||||||
casts::CAST_ENUM_CONSTRUCTOR,
|
casts::CAST_ENUM_CONSTRUCTOR,
|
||||||
casts::CAST_ENUM_TRUNCATION,
|
casts::CAST_ENUM_TRUNCATION,
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
|
store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
|
||||||
LintId::of(attrs::INLINE_ALWAYS),
|
LintId::of(attrs::INLINE_ALWAYS),
|
||||||
LintId::of(borrow_as_ptr::BORROW_AS_PTR),
|
|
||||||
LintId::of(bytecount::NAIVE_BYTECOUNT),
|
LintId::of(bytecount::NAIVE_BYTECOUNT),
|
||||||
LintId::of(case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS),
|
LintId::of(case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS),
|
||||||
|
LintId::of(casts::BORROW_AS_PTR),
|
||||||
LintId::of(casts::CAST_LOSSLESS),
|
LintId::of(casts::CAST_LOSSLESS),
|
||||||
LintId::of(casts::CAST_POSSIBLE_TRUNCATION),
|
LintId::of(casts::CAST_POSSIBLE_TRUNCATION),
|
||||||
LintId::of(casts::CAST_POSSIBLE_WRAP),
|
LintId::of(casts::CAST_POSSIBLE_WRAP),
|
||||||
|
|||||||
@@ -179,7 +179,6 @@ mod await_holding_invalid;
|
|||||||
mod blocks_in_if_conditions;
|
mod blocks_in_if_conditions;
|
||||||
mod bool_assert_comparison;
|
mod bool_assert_comparison;
|
||||||
mod booleans;
|
mod booleans;
|
||||||
mod borrow_as_ptr;
|
|
||||||
mod borrow_deref_ref;
|
mod borrow_deref_ref;
|
||||||
mod bytecount;
|
mod bytecount;
|
||||||
mod bytes_count_to_len;
|
mod bytes_count_to_len;
|
||||||
@@ -893,7 +892,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
store.register_late_pass(|| Box::new(return_self_not_must_use::ReturnSelfNotMustUse));
|
store.register_late_pass(|| Box::new(return_self_not_must_use::ReturnSelfNotMustUse));
|
||||||
store.register_late_pass(|| Box::new(init_numbered_fields::NumberedFields));
|
store.register_late_pass(|| Box::new(init_numbered_fields::NumberedFields));
|
||||||
store.register_early_pass(|| Box::new(single_char_lifetime_names::SingleCharLifetimeNames));
|
store.register_early_pass(|| Box::new(single_char_lifetime_names::SingleCharLifetimeNames));
|
||||||
store.register_late_pass(move || Box::new(borrow_as_ptr::BorrowAsPtr::new(msrv)));
|
|
||||||
store.register_late_pass(move || Box::new(manual_bits::ManualBits::new(msrv)));
|
store.register_late_pass(move || Box::new(manual_bits::ManualBits::new(msrv)));
|
||||||
store.register_late_pass(|| Box::new(default_union_representation::DefaultUnionRepresentation));
|
store.register_late_pass(|| Box::new(default_union_representation::DefaultUnionRepresentation));
|
||||||
store.register_early_pass(|| Box::new(doc_link_with_quotes::DocLinkWithQuotes));
|
store.register_early_pass(|| Box::new(doc_link_with_quotes::DocLinkWithQuotes));
|
||||||
|
|||||||
Reference in New Issue
Block a user