1
1
use clippy_utils:: consts:: Constant :: { Int , F32 , F64 } ;
2
- use clippy_utils:: consts:: { constant , constant_simple , Constant } ;
2
+ use clippy_utils:: consts:: { ConstEvalCtxt , Constant } ;
3
3
use clippy_utils:: diagnostics:: span_lint_and_sugg;
4
4
use clippy_utils:: {
5
5
eq_expr_value, get_parent_expr, higher, in_constant, is_inherent_method_call, is_no_std_crate, numeric_literal,
@@ -112,7 +112,7 @@ declare_lint_pass!(FloatingPointArithmetic => [
112
112
// Returns the specialized log method for a given base if base is constant
113
113
// and is one of 2, 10 and e
114
114
fn get_specialized_log_method ( cx : & LateContext < ' _ > , base : & Expr < ' _ > ) -> Option < & ' static str > {
115
- if let Some ( value) = constant ( cx, cx . typeck_results ( ) , base) {
115
+ if let Some ( value) = ConstEvalCtxt :: new ( cx) . eval ( base) {
116
116
if F32 ( 2.0 ) == value || F64 ( 2.0 ) == value {
117
117
return Some ( "log2" ) ;
118
118
} else if F32 ( 10.0 ) == value || F64 ( 10.0 ) == value {
@@ -182,10 +182,8 @@ fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) {
182
182
rhs,
183
183
) = receiver. kind
184
184
{
185
- let recv = match (
186
- constant ( cx, cx. typeck_results ( ) , lhs) ,
187
- constant ( cx, cx. typeck_results ( ) , rhs) ,
188
- ) {
185
+ let ecx = ConstEvalCtxt :: new ( cx) ;
186
+ let recv = match ( ecx. eval ( lhs) , ecx. eval ( rhs) ) {
189
187
( Some ( value) , _) if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value => rhs,
190
188
( _, Some ( value) ) if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value => lhs,
191
189
_ => return ,
@@ -230,7 +228,7 @@ fn get_integer_from_float_constant(value: &Constant<'_>) -> Option<i32> {
230
228
231
229
fn check_powf ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , receiver : & Expr < ' _ > , args : & [ Expr < ' _ > ] ) {
232
230
// Check receiver
233
- if let Some ( value) = constant ( cx, cx . typeck_results ( ) , receiver) {
231
+ if let Some ( value) = ConstEvalCtxt :: new ( cx) . eval ( receiver) {
234
232
if let Some ( method) = if F32 ( f32_consts:: E ) == value || F64 ( f64_consts:: E ) == value {
235
233
Some ( "exp" )
236
234
} else if F32 ( 2.0 ) == value || F64 ( 2.0 ) == value {
@@ -251,7 +249,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args:
251
249
}
252
250
253
251
// Check argument
254
- if let Some ( value) = constant ( cx, cx . typeck_results ( ) , & args[ 0 ] ) {
252
+ if let Some ( value) = ConstEvalCtxt :: new ( cx) . eval ( & args[ 0 ] ) {
255
253
let ( lint, help, suggestion) = if F32 ( 1.0 / 2.0 ) == value || F64 ( 1.0 / 2.0 ) == value {
256
254
(
257
255
SUBOPTIMAL_FLOPS ,
@@ -291,7 +289,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args:
291
289
}
292
290
293
291
fn check_powi ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , receiver : & Expr < ' _ > , args : & [ Expr < ' _ > ] ) {
294
- if let Some ( value) = constant ( cx, cx . typeck_results ( ) , & args[ 0 ] ) {
292
+ if let Some ( value) = ConstEvalCtxt :: new ( cx) . eval ( & args[ 0 ] ) {
295
293
if value == Int ( 2 ) {
296
294
if let Some ( parent) = get_parent_expr ( cx, expr) {
297
295
if let Some ( grandparent) = get_parent_expr ( cx, parent) {
@@ -397,8 +395,9 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option<String> {
397
395
) = & add_rhs. kind
398
396
&& lmethod_name. as_str ( ) == "powi"
399
397
&& rmethod_name. as_str ( ) == "powi"
400
- && let Some ( lvalue) = constant ( cx, cx. typeck_results ( ) , largs_1)
401
- && let Some ( rvalue) = constant ( cx, cx. typeck_results ( ) , rargs_1)
398
+ && let ecx = ConstEvalCtxt :: new ( cx)
399
+ && let Some ( lvalue) = ecx. eval ( largs_1)
400
+ && let Some ( rvalue) = ecx. eval ( rargs_1)
402
401
&& Int ( 2 ) == lvalue
403
402
&& Int ( 2 ) == rvalue
404
403
{
@@ -438,7 +437,7 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) {
438
437
rhs,
439
438
) = expr. kind
440
439
&& cx. typeck_results ( ) . expr_ty ( lhs) . is_floating_point ( )
441
- && let Some ( value) = constant ( cx, cx . typeck_results ( ) , rhs)
440
+ && let Some ( value) = ConstEvalCtxt :: new ( cx) . eval ( rhs)
442
441
&& ( F32 ( 1.0 ) == value || F64 ( 1.0 ) == value)
443
442
&& let ExprKind :: MethodCall ( path, self_arg, ..) = & lhs. kind
444
443
&& cx. typeck_results ( ) . expr_ty ( self_arg) . is_floating_point ( )
@@ -552,7 +551,7 @@ fn is_testing_negative(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -
552
551
553
552
/// Returns true iff expr is some zero literal
554
553
fn is_zero ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
555
- match constant_simple ( cx, cx . typeck_results ( ) , expr) {
554
+ match ConstEvalCtxt :: new ( cx) . eval_simple ( expr) {
556
555
Some ( Int ( i) ) => i == 0 ,
557
556
Some ( F32 ( f) ) => f == 0.0 ,
558
557
Some ( F64 ( f) ) => f == 0.0 ,
@@ -696,8 +695,9 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) {
696
695
mul_lhs,
697
696
mul_rhs,
698
697
) = & div_lhs. kind
699
- && let Some ( rvalue) = constant ( cx, cx. typeck_results ( ) , div_rhs)
700
- && let Some ( lvalue) = constant ( cx, cx. typeck_results ( ) , mul_rhs)
698
+ && let ecx = ConstEvalCtxt :: new ( cx)
699
+ && let Some ( rvalue) = ecx. eval ( div_rhs)
700
+ && let Some ( lvalue) = ecx. eval ( mul_rhs)
701
701
{
702
702
// TODO: also check for constant values near PI/180 or 180/PI
703
703
if ( F32 ( f32_consts:: PI ) == rvalue || F64 ( f64_consts:: PI ) == rvalue)
0 commit comments