@@ -11,6 +11,7 @@ mod float_cmp;
11
11
mod float_equality_without_abs;
12
12
mod identity_op;
13
13
mod integer_division;
14
+ mod manual_midpoint;
14
15
mod misrefactored_assign_op;
15
16
mod modulo_arithmetic;
16
17
mod modulo_one;
@@ -24,6 +25,7 @@ mod verbose_bit_mask;
24
25
pub ( crate ) mod arithmetic_side_effects;
25
26
26
27
use clippy_config:: Conf ;
28
+ use clippy_utils:: msrvs:: Msrv ;
27
29
use rustc_hir:: { Body , Expr , ExprKind , UnOp } ;
28
30
use rustc_lint:: { LateContext , LateLintPass } ;
29
31
use rustc_session:: impl_lint_pass;
@@ -834,17 +836,43 @@ declare_clippy_lint! {
834
836
"explicit self-assignment"
835
837
}
836
838
839
+ declare_clippy_lint ! {
840
+ /// ### What it does
841
+ /// Checks for manual implementation of `midpoint`.
842
+ ///
843
+ /// ### Why is this bad?
844
+ /// Using `(x + y) / 2` might cause an overflow on the intermediate
845
+ /// addition result.
846
+ ///
847
+ /// ### Example
848
+ /// ```no_run
849
+ /// # let a: u32 = 0;
850
+ /// let c = (a + 10) / 2;
851
+ /// ```
852
+ /// Use instead:
853
+ /// ```no_run
854
+ /// # let a: u32 = 0;
855
+ /// let c = u32::midpoint(a, 10);
856
+ /// ```
857
+ #[ clippy:: version = "1.87.0" ]
858
+ pub MANUAL_MIDPOINT ,
859
+ pedantic,
860
+ "manual implementation of `midpoint` which can overflow"
861
+ }
862
+
837
863
pub struct Operators {
838
864
arithmetic_context : numeric_arithmetic:: Context ,
839
865
verbose_bit_mask_threshold : u64 ,
840
866
modulo_arithmetic_allow_comparison_to_zero : bool ,
867
+ msrv : Msrv ,
841
868
}
842
869
impl Operators {
843
870
pub fn new ( conf : & ' static Conf ) -> Self {
844
871
Self {
845
872
arithmetic_context : numeric_arithmetic:: Context :: default ( ) ,
846
873
verbose_bit_mask_threshold : conf. verbose_bit_mask_threshold ,
847
874
modulo_arithmetic_allow_comparison_to_zero : conf. allow_comparison_to_zero ,
875
+ msrv : conf. msrv . clone ( ) ,
848
876
}
849
877
}
850
878
}
@@ -876,6 +904,7 @@ impl_lint_pass!(Operators => [
876
904
NEEDLESS_BITWISE_BOOL ,
877
905
PTR_EQ ,
878
906
SELF_ASSIGNMENT ,
907
+ MANUAL_MIDPOINT ,
879
908
] ) ;
880
909
881
910
impl < ' tcx > LateLintPass < ' tcx > for Operators {
@@ -893,6 +922,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
893
922
identity_op:: check ( cx, e, op. node , lhs, rhs) ;
894
923
needless_bitwise_bool:: check ( cx, e, op. node , lhs, rhs) ;
895
924
ptr_eq:: check ( cx, e, op. node , lhs, rhs) ;
925
+ manual_midpoint:: check ( cx, e, op. node , lhs, rhs, & self . msrv ) ;
896
926
}
897
927
self . arithmetic_context . check_binary ( cx, e, op. node , lhs, rhs) ;
898
928
bit_mask:: check ( cx, e, op. node , lhs, rhs) ;
@@ -943,6 +973,8 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
943
973
fn check_body_post ( & mut self , cx : & LateContext < ' tcx > , b : & Body < ' _ > ) {
944
974
self . arithmetic_context . body_post ( cx, b) ;
945
975
}
976
+
977
+ extract_msrv_attr ! ( LateContext ) ;
946
978
}
947
979
948
980
fn macro_with_not_op ( e : & Expr < ' _ > ) -> bool {
0 commit comments