Rename lint into confusing_method_to_numeric_cast
This commit is contained in:
parent
c680419425
commit
06fa0452eb
10 changed files with 172 additions and 44 deletions
|
|
@ -1,12 +1,13 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::match_def_path;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_middle::ty::{self, GenericArg, Ty};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{Symbol, sym};
|
||||
|
||||
use super::PRIMITIVE_METHOD_TO_NUMERIC_CAST;
|
||||
use super::CONFUSING_METHOD_TO_NUMERIC_CAST;
|
||||
|
||||
fn get_primitive_ty_name(ty: Ty<'_>) -> Option<&'static str> {
|
||||
match ty.kind() {
|
||||
|
|
@ -18,6 +19,37 @@ fn get_primitive_ty_name(ty: Ty<'_>) -> Option<&'static str> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_const_name_and_ty_name(
|
||||
cx: &LateContext<'_>,
|
||||
method_name: Symbol,
|
||||
method_def_id: DefId,
|
||||
generics: &[GenericArg<'_>],
|
||||
) -> Option<(&'static str, &'static str)> {
|
||||
let method_name = method_name.as_str();
|
||||
let diagnostic_name = cx.tcx.get_diagnostic_name(method_def_id);
|
||||
|
||||
let ty_name = if diagnostic_name.is_some_and(|diag| diag == sym::cmp_ord_min || diag == sym::cmp_ord_max) {
|
||||
// We get the type on which the `min`/`max` method of the `Ord` trait is implemented.
|
||||
if let [ty] = generics
|
||||
&& let Some(ty) = ty.as_type()
|
||||
{
|
||||
get_primitive_ty_name(ty)?
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
} else if let Some(impl_id) = cx.tcx.impl_of_method(method_def_id)
|
||||
&& let Some(ty_name) = get_primitive_ty_name(cx.tcx.type_of(impl_id).instantiate_identity())
|
||||
&& ["min", "max", "minimum", "maximum", "min_value", "max_value"].contains(&method_name)
|
||||
{
|
||||
ty_name
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let const_name = if method_name.starts_with("max") { "MAX" } else { "MIN" };
|
||||
Some((const_name, ty_name))
|
||||
}
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
|
||||
// We allow casts from any function type to any function type.
|
||||
match cast_to.kind() {
|
||||
|
|
@ -27,28 +59,21 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
|
|||
|
||||
if let ty::FnDef(def_id, generics) = cast_from.kind()
|
||||
&& let Some(method_name) = cx.tcx.opt_item_name(*def_id)
|
||||
&& let method_name = method_name.as_str()
|
||||
&& (method_name == "min" || method_name == "max")
|
||||
// We get the type on which the `min`/`max` method of the `Ord` trait is implemented.
|
||||
&& let [ty] = generics.as_slice()
|
||||
&& let Some(ty) = ty.as_type()
|
||||
// We get its name in case it's a primitive with an associated MIN/MAX constant.
|
||||
&& let Some(ty_name) = get_primitive_ty_name(ty)
|
||||
&& match_def_path(cx, *def_id, &["core", "cmp", "Ord", method_name])
|
||||
&& let Some((const_name, ty_name)) = get_const_name_and_ty_name(cx, method_name, *def_id, generics.as_slice())
|
||||
{
|
||||
let mut applicability = Applicability::MaybeIncorrect;
|
||||
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "..", &mut applicability);
|
||||
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
PRIMITIVE_METHOD_TO_NUMERIC_CAST,
|
||||
CONFUSING_METHOD_TO_NUMERIC_CAST,
|
||||
expr.span,
|
||||
format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
|
||||
|diag| {
|
||||
diag.span_suggestion_verbose(
|
||||
expr.span,
|
||||
"did you mean to use the associated constant?",
|
||||
format!("{ty_name}::{} as {cast_to}", method_name.to_ascii_uppercase()),
|
||||
format!("{ty_name}::{const_name} as {cast_to}"),
|
||||
applicability,
|
||||
);
|
||||
},
|
||||
|
|
@ -14,11 +14,11 @@ mod cast_sign_loss;
|
|||
mod cast_slice_different_sizes;
|
||||
mod cast_slice_from_raw_parts;
|
||||
mod char_lit_as_u8;
|
||||
mod confusing_method_to_numeric_cast;
|
||||
mod fn_to_numeric_cast;
|
||||
mod fn_to_numeric_cast_any;
|
||||
mod fn_to_numeric_cast_with_truncation;
|
||||
mod manual_dangling_ptr;
|
||||
mod primitive_method_to_numeric_cast;
|
||||
mod ptr_as_ptr;
|
||||
mod ptr_cast_constness;
|
||||
mod ref_as_ptr;
|
||||
|
|
@ -808,7 +808,7 @@ declare_clippy_lint! {
|
|||
/// let _ = u16::MAX as usize;
|
||||
/// ```
|
||||
#[clippy::version = "1.86.0"]
|
||||
pub PRIMITIVE_METHOD_TO_NUMERIC_CAST,
|
||||
pub CONFUSING_METHOD_TO_NUMERIC_CAST,
|
||||
suspicious,
|
||||
"casting a primitive method pointer to any integer type"
|
||||
}
|
||||
|
|
@ -850,7 +850,7 @@ impl_lint_pass!(Casts => [
|
|||
REF_AS_PTR,
|
||||
AS_POINTER_UNDERSCORE,
|
||||
MANUAL_DANGLING_PTR,
|
||||
PRIMITIVE_METHOD_TO_NUMERIC_CAST,
|
||||
CONFUSING_METHOD_TO_NUMERIC_CAST,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Casts {
|
||||
|
|
@ -875,7 +875,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
|||
ptr_cast_constness::check(cx, expr, cast_from_expr, cast_from, cast_to, self.msrv);
|
||||
as_ptr_cast_mut::check(cx, expr, cast_from_expr, cast_to);
|
||||
fn_to_numeric_cast_any::check(cx, expr, cast_from_expr, cast_from, cast_to);
|
||||
primitive_method_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
|
||||
confusing_method_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
|
||||
fn_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
|
||||
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_from_expr, cast_from, cast_to);
|
||||
zero_ptr::check(cx, expr, cast_from_expr, cast_to_hir);
|
||||
|
|
|
|||
|
|
@ -64,11 +64,11 @@ pub static LINTS: &[&crate::LintInfo] = &[
|
|||
crate::casts::CAST_SLICE_DIFFERENT_SIZES_INFO,
|
||||
crate::casts::CAST_SLICE_FROM_RAW_PARTS_INFO,
|
||||
crate::casts::CHAR_LIT_AS_U8_INFO,
|
||||
crate::casts::CONFUSING_METHOD_TO_NUMERIC_CAST_INFO,
|
||||
crate::casts::FN_TO_NUMERIC_CAST_INFO,
|
||||
crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO,
|
||||
crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO,
|
||||
crate::casts::MANUAL_DANGLING_PTR_INFO,
|
||||
crate::casts::PRIMITIVE_METHOD_TO_NUMERIC_CAST_INFO,
|
||||
crate::casts::PTR_AS_PTR_INFO,
|
||||
crate::casts::PTR_CAST_CONSTNESS_INFO,
|
||||
crate::casts::REF_AS_PTR_INFO,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue