@@ -7,14 +7,15 @@ use rustc_hir as hir;
77use rustc_hir:: def:: Res ;
88use rustc_lint:: LateContext ;
99use rustc_middle:: ty:: layout:: LayoutOf ;
10+ use rustc_span:: Symbol ;
1011
1112pub fn check (
1213 cx : & LateContext < ' _ > ,
1314 expr : & hir:: Expr < ' _ > ,
1415 arith_lhs : & hir:: Expr < ' _ > ,
1516 arith_rhs : & hir:: Expr < ' _ > ,
1617 unwrap_arg : & hir:: Expr < ' _ > ,
17- arith : & str ,
18+ arith : Symbol ,
1819) {
1920 let ty = cx. typeck_results ( ) . expr_ty ( arith_lhs) ;
2021 if !ty. is_integral ( ) {
@@ -25,42 +26,76 @@ pub fn check(
2526 return ;
2627 } ;
2728
29+ let Some ( checked_arith) = CheckedArith :: new ( arith) else {
30+ return ;
31+ } ;
32+
2833 if ty. is_signed ( ) {
2934 use self :: MinMax :: { Max , Min } ;
3035 use self :: Sign :: { Neg , Pos } ;
36+ use CheckedArith :: { Add , Sub } ;
3137
3238 let Some ( sign) = lit_sign ( arith_rhs) else {
3339 return ;
3440 } ;
3541
36- match ( arith , sign, mm) {
37- ( "add" , Pos , Max ) | ( "add" , Neg , Min ) | ( "sub" , Neg , Max ) | ( "sub" , Pos , Min ) => ( ) ,
42+ match ( & checked_arith , sign, mm) {
43+ ( Add , Pos , Max ) | ( Add , Neg , Min ) | ( Sub , Neg , Max ) | ( Sub , Pos , Min ) => ( ) ,
3844 // "mul" is omitted because lhs can be negative.
3945 _ => return ,
4046 }
4147 } else {
42- match ( mm, arith) {
43- ( MinMax :: Max , "add" | "mul" ) | ( MinMax :: Min , "sub" ) => ( ) ,
48+ use self :: MinMax :: { Max , Min } ;
49+ use CheckedArith :: { Add , Mul , Sub } ;
50+ match ( mm, & checked_arith) {
51+ ( Max , Add | Mul ) | ( Min , Sub ) => ( ) ,
4452 _ => return ,
4553 }
4654 }
4755
4856 let mut applicability = Applicability :: MachineApplicable ;
57+ let saturating_arith = checked_arith. as_saturating ( ) ;
4958 span_lint_and_sugg (
5059 cx,
5160 super :: MANUAL_SATURATING_ARITHMETIC ,
5261 expr. span ,
5362 "manual saturating arithmetic" ,
54- format ! ( "consider using `saturating_{arith }`" ) ,
63+ format ! ( "consider using `{saturating_arith }`" ) ,
5564 format ! (
56- "{}.saturating_{arith }({})" ,
65+ "{}.{saturating_arith }({})" ,
5766 snippet_with_applicability( cx, arith_lhs. span, ".." , & mut applicability) ,
5867 snippet_with_applicability( cx, arith_rhs. span, ".." , & mut applicability) ,
5968 ) ,
6069 applicability,
6170 ) ;
6271}
6372
73+ enum CheckedArith {
74+ Add ,
75+ Sub ,
76+ Mul ,
77+ }
78+
79+ impl CheckedArith {
80+ fn new ( sym : Symbol ) -> Option < Self > {
81+ let res = match sym {
82+ sym:: checked_add => Self :: Add ,
83+ sym:: checked_sub => Self :: Sub ,
84+ sym:: checked_mul => Self :: Mul ,
85+ _ => return None ,
86+ } ;
87+ Some ( res)
88+ }
89+
90+ fn as_saturating ( & self ) -> & ' static str {
91+ match self {
92+ Self :: Add => "saturating_add" ,
93+ Self :: Sub => "saturating_sub" ,
94+ Self :: Mul => "saturating_mul" ,
95+ }
96+ }
97+ }
98+
6499#[ derive( PartialEq , Eq ) ]
65100enum MinMax {
66101 Min ,
0 commit comments