@@ -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;
@@ -837,17 +839,43 @@ declare_clippy_lint! {
837
839
"explicit self-assignment"
838
840
}
839
841
842
+ declare_clippy_lint ! {
843
+ /// ### What it does
844
+ /// Checks for manual implementation of `midpoint`.
845
+ ///
846
+ /// ### Why is this bad?
847
+ /// Using `(x + y) / 2` might cause an overflow on the intermediate
848
+ /// addition result.
849
+ ///
850
+ /// ### Example
851
+ /// ```no_run
852
+ /// # let a: u32 = 0;
853
+ /// let c = (a + 10) / 2;
854
+ /// ```
855
+ /// Use instead:
856
+ /// ```no_run
857
+ /// # let a: u32 = 0;
858
+ /// let c = u32::midpoint(a, 10);
859
+ /// ```
860
+ #[ clippy:: version = "1.85.0" ]
861
+ pub MANUAL_MIDPOINT ,
862
+ correctness,
863
+ "manual implementation of `midpoint`"
864
+ }
865
+
840
866
pub struct Operators {
841
867
arithmetic_context : numeric_arithmetic:: Context ,
842
868
verbose_bit_mask_threshold : u64 ,
843
869
modulo_arithmetic_allow_comparison_to_zero : bool ,
870
+ msrv : Msrv ,
844
871
}
845
872
impl Operators {
846
873
pub fn new ( conf : & ' static Conf ) -> Self {
847
874
Self {
848
875
arithmetic_context : numeric_arithmetic:: Context :: default ( ) ,
849
876
verbose_bit_mask_threshold : conf. verbose_bit_mask_threshold ,
850
877
modulo_arithmetic_allow_comparison_to_zero : conf. allow_comparison_to_zero ,
878
+ msrv : conf. msrv . clone ( ) ,
851
879
}
852
880
}
853
881
}
@@ -879,6 +907,7 @@ impl_lint_pass!(Operators => [
879
907
NEEDLESS_BITWISE_BOOL ,
880
908
PTR_EQ ,
881
909
SELF_ASSIGNMENT ,
910
+ MANUAL_MIDPOINT ,
882
911
] ) ;
883
912
884
913
impl < ' tcx > LateLintPass < ' tcx > for Operators {
@@ -896,6 +925,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
896
925
identity_op:: check ( cx, e, op. node , lhs, rhs) ;
897
926
needless_bitwise_bool:: check ( cx, e, op. node , lhs, rhs) ;
898
927
ptr_eq:: check ( cx, e, op. node , lhs, rhs) ;
928
+ manual_midpoint:: check ( cx, e, op. node , lhs, rhs, & self . msrv ) ;
899
929
}
900
930
self . arithmetic_context . check_binary ( cx, e, op. node , lhs, rhs) ;
901
931
bit_mask:: check ( cx, e, op. node , lhs, rhs) ;
@@ -946,6 +976,8 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
946
976
fn check_body_post ( & mut self , cx : & LateContext < ' tcx > , b : & Body < ' _ > ) {
947
977
self . arithmetic_context . body_post ( cx, b) ;
948
978
}
979
+
980
+ extract_msrv_attr ! ( LateContext ) ;
949
981
}
950
982
951
983
fn macro_with_not_op ( e : & Expr < ' _ > ) -> bool {
0 commit comments