11use clippy_config:: msrvs:: { self , Msrv } ;
2+ use clippy_utils:: consts:: { constant, Constant } ;
23use clippy_utils:: diagnostics:: { span_lint_and_then, span_lint_hir_and_then} ;
34use clippy_utils:: higher:: If ;
45use clippy_utils:: sugg:: Sugg ;
@@ -17,6 +18,7 @@ use rustc_middle::ty::Ty;
1718use rustc_session:: impl_lint_pass;
1819use rustc_span:: symbol:: sym;
1920use rustc_span:: Span ;
21+ use std:: cmp:: Ordering ;
2022use std:: ops:: Deref ;
2123
2224declare_clippy_lint ! {
@@ -80,7 +82,7 @@ declare_clippy_lint! {
8082 /// ```
8183 #[ clippy:: version = "1.66.0" ]
8284 pub MANUAL_CLAMP ,
83- nursery ,
85+ complexity ,
8486 "using a clamp pattern instead of the clamp function"
8587}
8688impl_lint_pass ! ( ManualClamp => [ MANUAL_CLAMP ] ) ;
@@ -103,6 +105,24 @@ struct ClampSuggestion<'tcx> {
103105 hir_with_ignore_attr : Option < HirId > ,
104106}
105107
108+ impl < ' tcx > ClampSuggestion < ' tcx > {
109+ /// This function will return true if and only if you can demonstrate at compile time that min
110+ /// is less than max.
111+ fn min_less_than_max ( & self , cx : & LateContext < ' tcx > ) -> bool {
112+ let max_type = cx. typeck_results ( ) . expr_ty ( self . params . max ) ;
113+ let min_type = cx. typeck_results ( ) . expr_ty ( self . params . min ) ;
114+ if max_type != min_type {
115+ return false ;
116+ }
117+ let max = constant ( cx, cx. typeck_results ( ) , self . params . max ) ;
118+ let min = constant ( cx, cx. typeck_results ( ) , self . params . min ) ;
119+ let cmp = max
120+ . zip ( min)
121+ . and_then ( |( max, min) | Constant :: partial_cmp ( cx. tcx , max_type, & min, & max) ) ;
122+ cmp. is_some_and ( |cmp| cmp != Ordering :: Greater )
123+ }
124+ }
125+
106126#[ derive( Debug ) ]
107127struct InputMinMax < ' tcx > {
108128 input : & ' tcx Expr < ' tcx > ,
@@ -123,7 +143,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualClamp {
123143 . or_else ( || is_match_pattern ( cx, expr) )
124144 . or_else ( || is_if_elseif_pattern ( cx, expr) ) ;
125145 if let Some ( suggestion) = suggestion {
126- emit_suggestion ( cx, & suggestion) ;
146+ if suggestion. min_less_than_max ( cx) {
147+ emit_suggestion ( cx, & suggestion) ;
148+ }
127149 }
128150 }
129151 }
@@ -133,7 +155,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualClamp {
133155 return ;
134156 }
135157 for suggestion in is_two_if_pattern ( cx, block) {
136- emit_suggestion ( cx, & suggestion) ;
158+ if suggestion. min_less_than_max ( cx) {
159+ emit_suggestion ( cx, & suggestion) ;
160+ }
137161 }
138162 }
139163 extract_msrv_attr ! ( LateContext ) ;
0 commit comments