1
1
mod cast_lossless;
2
2
mod cast_possible_truncation;
3
3
mod cast_precision_loss;
4
+ mod cast_sign_loss;
4
5
mod utils;
5
6
6
7
use std:: borrow:: Cow ;
@@ -17,11 +18,10 @@ use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
17
18
use rustc_span:: symbol:: sym;
18
19
use rustc_target:: abi:: LayoutOf ;
19
20
20
- use crate :: consts:: { constant, Constant } ;
21
21
use crate :: utils:: sugg:: Sugg ;
22
22
use crate :: utils:: {
23
- is_hir_ty_cfg_dependant, is_isize_or_usize, meets_msrv, method_chain_args , numeric_literal:: NumericLiteral , sext ,
24
- snippet_opt , snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then,
23
+ is_hir_ty_cfg_dependant, is_isize_or_usize, meets_msrv, numeric_literal:: NumericLiteral , snippet_opt ,
24
+ snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then,
25
25
} ;
26
26
27
27
use utils:: int_ty_to_nbits;
@@ -261,52 +261,6 @@ enum ArchSuffix {
261
261
None ,
262
262
}
263
263
264
- fn check_loss_of_sign ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , op : & Expr < ' _ > , cast_from : Ty < ' _ > , cast_to : Ty < ' _ > ) {
265
- if !cast_from. is_signed ( ) || cast_to. is_signed ( ) {
266
- return ;
267
- }
268
-
269
- // don't lint for positive constants
270
- let const_val = constant ( cx, & cx. typeck_results ( ) , op) ;
271
- if_chain ! {
272
- if let Some ( ( Constant :: Int ( n) , _) ) = const_val;
273
- if let ty:: Int ( ity) = * cast_from. kind( ) ;
274
- if sext( cx. tcx, n, ity) >= 0 ;
275
- then {
276
- return
277
- }
278
- }
279
-
280
- // don't lint for the result of methods that always return non-negative values
281
- if let ExprKind :: MethodCall ( ref path, _, _, _) = op. kind {
282
- let mut method_name = path. ident . name . as_str ( ) ;
283
- let allowed_methods = [ "abs" , "checked_abs" , "rem_euclid" , "checked_rem_euclid" ] ;
284
-
285
- if_chain ! {
286
- if method_name == "unwrap" ;
287
- if let Some ( arglist) = method_chain_args( op, & [ "unwrap" ] ) ;
288
- if let ExprKind :: MethodCall ( ref inner_path, _, _, _) = & arglist[ 0 ] [ 0 ] . kind;
289
- then {
290
- method_name = inner_path. ident. name. as_str( ) ;
291
- }
292
- }
293
-
294
- if allowed_methods. iter ( ) . any ( |& name| method_name == name) {
295
- return ;
296
- }
297
- }
298
-
299
- span_lint (
300
- cx,
301
- CAST_SIGN_LOSS ,
302
- expr. span ,
303
- & format ! (
304
- "casting `{}` to `{}` may lose the sign of the value" ,
305
- cast_from, cast_to
306
- ) ,
307
- ) ;
308
- }
309
-
310
264
fn check_truncation_and_wrapping ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , cast_from : Ty < ' _ > , cast_to : Ty < ' _ > ) {
311
265
let arch_64_suffix = " on targets with 64-bit wide pointers" ;
312
266
let arch_32_suffix = " on targets with 32-bit wide pointers" ;
@@ -490,29 +444,17 @@ fn show_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &st
490
444
fn lint_numeric_casts < ' tcx > (
491
445
cx : & LateContext < ' tcx > ,
492
446
expr : & Expr < ' tcx > ,
493
- cast_expr : & Expr < ' _ > ,
447
+ cast_op : & Expr < ' _ > ,
494
448
cast_from : Ty < ' tcx > ,
495
449
cast_to : Ty < ' tcx > ,
496
450
) {
497
- cast_precision_loss:: check ( cx, expr, cast_from, cast_to) ;
498
- cast_lossless:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
499
451
cast_possible_truncation:: check ( cx, expr, cast_from, cast_to) ;
452
+ cast_precision_loss:: check ( cx, expr, cast_from, cast_to) ;
453
+ cast_lossless:: check ( cx, expr, cast_op, cast_from, cast_to) ;
454
+ cast_sign_loss:: check ( cx, expr, cast_op, cast_from, cast_to) ;
455
+
500
456
match ( cast_from. is_integral ( ) , cast_to. is_integral ( ) ) {
501
- ( false , true ) => {
502
- if !cast_to. is_signed ( ) {
503
- span_lint (
504
- cx,
505
- CAST_SIGN_LOSS ,
506
- expr. span ,
507
- & format ! (
508
- "casting `{}` to `{}` may lose the sign of the value" ,
509
- cast_from, cast_to
510
- ) ,
511
- ) ;
512
- }
513
- } ,
514
457
( true , true ) => {
515
- check_loss_of_sign ( cx, expr, cast_expr, cast_from, cast_to) ;
516
458
check_truncation_and_wrapping ( cx, expr, cast_from, cast_to) ;
517
459
} ,
518
460
( _, _) => { } ,
0 commit comments