11use clippy_utils:: consts:: Constant :: { Int , F32 , F64 } ;
2- use clippy_utils:: consts:: { constant , constant_simple , Constant } ;
2+ use clippy_utils:: consts:: { ConstEvalCtxt , Constant } ;
33use clippy_utils:: diagnostics:: span_lint_and_sugg;
44use clippy_utils:: {
55 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 => [
112112// Returns the specialized log method for a given base if base is constant
113113// and is one of 2, 10 and e
114114fn 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) {
116116 if F32 ( 2.0 ) == value || F64 ( 2.0 ) == value {
117117 return Some ( "log2" ) ;
118118 } else if F32 ( 10.0 ) == value || F64 ( 10.0 ) == value {
@@ -182,10 +182,8 @@ fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) {
182182 rhs,
183183 ) = receiver. kind
184184 {
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) ) {
189187 ( Some ( value) , _) if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value => rhs,
190188 ( _, Some ( value) ) if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value => lhs,
191189 _ => return ,
@@ -230,7 +228,7 @@ fn get_integer_from_float_constant(value: &Constant<'_>) -> Option<i32> {
230228
231229fn check_powf ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , receiver : & Expr < ' _ > , args : & [ Expr < ' _ > ] ) {
232230 // Check receiver
233- if let Some ( value) = constant ( cx, cx . typeck_results ( ) , receiver) {
231+ if let Some ( value) = ConstEvalCtxt :: new ( cx) . eval ( receiver) {
234232 if let Some ( method) = if F32 ( f32_consts:: E ) == value || F64 ( f64_consts:: E ) == value {
235233 Some ( "exp" )
236234 } else if F32 ( 2.0 ) == value || F64 ( 2.0 ) == value {
@@ -251,7 +249,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args:
251249 }
252250
253251 // 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 ] ) {
255253 let ( lint, help, suggestion) = if F32 ( 1.0 / 2.0 ) == value || F64 ( 1.0 / 2.0 ) == value {
256254 (
257255 SUBOPTIMAL_FLOPS ,
@@ -291,7 +289,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args:
291289}
292290
293291fn 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 ] ) {
295293 if value == Int ( 2 ) {
296294 if let Some ( parent) = get_parent_expr ( cx, expr) {
297295 if let Some ( grandparent) = get_parent_expr ( cx, parent) {
@@ -397,8 +395,9 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option<String> {
397395 ) = & add_rhs. kind
398396 && lmethod_name. as_str ( ) == "powi"
399397 && 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)
402401 && Int ( 2 ) == lvalue
403402 && Int ( 2 ) == rvalue
404403 {
@@ -438,7 +437,7 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) {
438437 rhs,
439438 ) = expr. kind
440439 && 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)
442441 && ( F32 ( 1.0 ) == value || F64 ( 1.0 ) == value)
443442 && let ExprKind :: MethodCall ( path, self_arg, ..) = & lhs. kind
444443 && cx. typeck_results ( ) . expr_ty ( self_arg) . is_floating_point ( )
@@ -552,7 +551,7 @@ fn is_testing_negative(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -
552551
553552/// Returns true iff expr is some zero literal
554553fn is_zero ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
555- match constant_simple ( cx, cx . typeck_results ( ) , expr) {
554+ match ConstEvalCtxt :: new ( cx) . eval_simple ( expr) {
556555 Some ( Int ( i) ) => i == 0 ,
557556 Some ( F32 ( f) ) => f == 0.0 ,
558557 Some ( F64 ( f) ) => f == 0.0 ,
@@ -696,8 +695,9 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) {
696695 mul_lhs,
697696 mul_rhs,
698697 ) = & 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)
701701 {
702702 // TODO: also check for constant values near PI/180 or 180/PI
703703 if ( F32 ( f32_consts:: PI ) == rvalue || F64 ( f64_consts:: PI ) == rvalue)
0 commit comments