Skip to content

Commit 46e3304

Browse files
committed
Auto merge of #12884 - y21:issue12881, r=Alexendoo
Only run `suboptimal_flops` on inherent method calls Fixes #12881 `suboptimal_flops` was making the wrong assumption that a `.log()` method call on a float literal must choose the inherent log method that will always have an argument present (in which case `args[0]` indexing would be fine), but that wasn't the case in the linked issue because at the point of the method call, the exact float type hadn't been inferred yet (and method selection can't select inherent methods when the exact float type has not yet been inferred, in which case it falls back to looking for trait impls and chooses the one that didn't have any parameters). This fixes it by actually making sure it's a call to an inherent method (could also fix the linked ICE by simply using fallibly indexing via `.get()`, but this felt like it'd fix the root cause: even if there were one argument, it would still be wrong to emit a warning there because it's not the `log` method the lint was expecting). I'm not sure if we need that extra function be in `clippy_utils` but it feels like it could be useful. changelog: Fixes an ICE in [`suboptimal_flops`]
2 parents 5d568ad + 708ef79 commit 46e3304

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

clippy_lints/src/floating_point_arithmetic.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use clippy_utils::consts::Constant::{Int, F32, F64};
22
use clippy_utils::consts::{constant, constant_simple, Constant};
33
use clippy_utils::diagnostics::span_lint_and_sugg;
44
use clippy_utils::{
5-
eq_expr_value, get_parent_expr, higher, in_constant, is_no_std_crate, numeric_literal, peel_blocks, sugg,
5+
eq_expr_value, get_parent_expr, higher, in_constant, is_inherent_method_call, is_no_std_crate, numeric_literal,
6+
peel_blocks, sugg,
67
};
78
use rustc_errors::Applicability;
89
use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp};
@@ -759,7 +760,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
759760
if let ExprKind::MethodCall(path, receiver, args, _) = &expr.kind {
760761
let recv_ty = cx.typeck_results().expr_ty(receiver);
761762

762-
if recv_ty.is_floating_point() && !is_no_std_crate(cx) {
763+
if recv_ty.is_floating_point() && !is_no_std_crate(cx) && is_inherent_method_call(cx, expr) {
763764
match path.ident.name.as_str() {
764765
"ln" => check_ln1p(cx, expr, receiver),
765766
"log" => check_log_base(cx, expr, receiver, args),

clippy_utils/src/lib.rs

+9
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,15 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str])
321321
.map_or(false, |trt_id| match_def_path(cx, trt_id, path))
322322
}
323323

324+
/// Checks if the given method call expression calls an inherent method.
325+
pub fn is_inherent_method_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
326+
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
327+
cx.tcx.trait_of_item(method_id).is_none()
328+
} else {
329+
false
330+
}
331+
}
332+
324333
/// Checks if a method is defined in an impl of a diagnostic item
325334
pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool {
326335
if let Some(impl_did) = cx.tcx.impl_of_method(def_id) {

tests/ui/floating_point_log.fixed

+15
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,19 @@ fn check_ln1p() {
5555
let _ = (1.0 + x - 2.0).ln();
5656
}
5757

58+
fn issue12881() {
59+
pub trait MyLog {
60+
fn log(&self) -> Self;
61+
}
62+
63+
impl MyLog for f32 {
64+
fn log(&self) -> Self {
65+
4.
66+
}
67+
}
68+
69+
let x = 2.0;
70+
x.log();
71+
}
72+
5873
fn main() {}

tests/ui/floating_point_log.rs

+15
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,19 @@ fn check_ln1p() {
5555
let _ = (1.0 + x - 2.0).ln();
5656
}
5757

58+
fn issue12881() {
59+
pub trait MyLog {
60+
fn log(&self) -> Self;
61+
}
62+
63+
impl MyLog for f32 {
64+
fn log(&self) -> Self {
65+
4.
66+
}
67+
}
68+
69+
let x = 2.0;
70+
x.log();
71+
}
72+
5873
fn main() {}

0 commit comments

Comments
 (0)