1
1
use crate :: rustc:: hir;
2
2
use crate :: rustc:: hir:: def:: Def ;
3
- use crate :: rustc:: hir:: intravisit:: { walk_expr, NestedVisitorMap , Visitor } ;
4
3
use crate :: rustc:: lint:: { in_external_macro, LateContext , LateLintPass , Lint , LintArray , LintContext , LintPass } ;
5
4
use crate :: rustc:: ty:: { self , Ty } ;
6
5
use crate :: rustc:: { declare_tool_lint, lint_array} ;
@@ -9,7 +8,6 @@ use crate::syntax::ast;
9
8
use crate :: syntax:: source_map:: { BytePos , Span } ;
10
9
use crate :: utils:: paths;
11
10
use crate :: utils:: sugg;
12
- use crate :: utils:: usage:: mutated_variables;
13
11
use crate :: utils:: {
14
12
get_arg_name, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, is_self, is_self_ty,
15
13
iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type,
@@ -22,6 +20,8 @@ use std::borrow::Cow;
22
20
use std:: fmt;
23
21
use std:: iter;
24
22
23
+ mod unnecessary_filter_map;
24
+
25
25
#[ derive( Clone ) ]
26
26
pub struct Pass ;
27
27
@@ -1424,144 +1424,6 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr, fold_args:
1424
1424
} ;
1425
1425
}
1426
1426
1427
- mod unnecessary_filter_map {
1428
- use super :: * ;
1429
-
1430
- pub ( super ) fn lint ( cx : & LateContext < ' _ , ' _ > , expr : & hir:: Expr , args : & [ hir:: Expr ] ) {
1431
-
1432
- if !match_trait_method ( cx, expr, & paths:: ITERATOR ) {
1433
- return ;
1434
- }
1435
-
1436
- if let hir:: ExprKind :: Closure ( _, _, body_id, ..) = args[ 1 ] . node {
1437
-
1438
- let body = cx. tcx . hir . body ( body_id) ;
1439
- let arg_id = body. arguments [ 0 ] . pat . id ;
1440
- let mutates_arg = match mutated_variables ( & body. value , cx) {
1441
- Some ( used_mutably) => used_mutably. contains ( & arg_id) ,
1442
- None => true ,
1443
- } ;
1444
-
1445
- let ( mut found_mapping, mut found_filtering) = check_expression ( & cx, arg_id, & body. value ) ;
1446
-
1447
- let mut return_visitor = ReturnVisitor :: new ( & cx, arg_id) ;
1448
- return_visitor. visit_expr ( & body. value ) ;
1449
- found_mapping |= return_visitor. found_mapping ;
1450
- found_filtering |= return_visitor. found_filtering ;
1451
-
1452
- if !found_filtering {
1453
- span_lint (
1454
- cx,
1455
- UNNECESSARY_FILTER_MAP ,
1456
- expr. span ,
1457
- "this `.filter_map` can be written more simply using `.map`" ,
1458
- ) ;
1459
- return ;
1460
- }
1461
-
1462
- if !found_mapping && !mutates_arg {
1463
- span_lint (
1464
- cx,
1465
- UNNECESSARY_FILTER_MAP ,
1466
- expr. span ,
1467
- "this `.filter_map` can be written more simply using `.filter`" ,
1468
- ) ;
1469
- return ;
1470
- }
1471
- }
1472
- }
1473
-
1474
- // returns (found_mapping, found_filtering)
1475
- fn check_expression < ' a , ' tcx : ' a > ( cx : & ' a LateContext < ' a , ' tcx > , arg_id : ast:: NodeId , expr : & ' tcx hir:: Expr ) -> ( bool , bool ) {
1476
- match & expr. node {
1477
- hir:: ExprKind :: Call ( ref func, ref args) => {
1478
- if_chain ! {
1479
- if let hir:: ExprKind :: Path ( ref path) = func. node;
1480
- then {
1481
- if match_qpath( path, & paths:: OPTION_SOME ) {
1482
- if_chain! {
1483
- if let hir:: ExprKind :: Path ( path) = & args[ 0 ] . node;
1484
- if let Def :: Local ( ref local) = cx. tables. qpath_def( path, args[ 0 ] . hir_id) ;
1485
- then {
1486
- if arg_id == * local {
1487
- return ( false , false )
1488
- }
1489
- }
1490
- }
1491
- return ( true , false ) ;
1492
- } else {
1493
- // We don't know. It might do anything.
1494
- return ( true , true ) ;
1495
- }
1496
- }
1497
- }
1498
- ( true , true )
1499
- } ,
1500
- hir:: ExprKind :: Block ( ref block, _) => {
1501
- if let Some ( expr) = & block. expr {
1502
- check_expression ( cx, arg_id, & expr)
1503
- } else {
1504
- ( false , false )
1505
- }
1506
- } ,
1507
- // There must be an else_arm or there will be a type error
1508
- hir:: ExprKind :: If ( _, ref if_arm, Some ( ref else_arm) ) => {
1509
- let if_check = check_expression ( cx, arg_id, if_arm) ;
1510
- let else_check = check_expression ( cx, arg_id, else_arm) ;
1511
- ( if_check. 0 | else_check. 0 , if_check. 1 | else_check. 1 )
1512
- } ,
1513
- hir:: ExprKind :: Match ( _, ref arms, _) => {
1514
- let mut found_mapping = false ;
1515
- let mut found_filtering = false ;
1516
- for arm in arms {
1517
- let ( m, f) = check_expression ( cx, arg_id, & arm. body ) ;
1518
- found_mapping |= m;
1519
- found_filtering |= f;
1520
- }
1521
- ( found_mapping, found_filtering)
1522
- } ,
1523
- hir:: ExprKind :: Path ( path) if match_qpath ( path, & paths:: OPTION_NONE ) => ( false , true ) ,
1524
- _ => ( true , true )
1525
- }
1526
- }
1527
-
1528
- struct ReturnVisitor < ' a , ' tcx : ' a > {
1529
- cx : & ' a LateContext < ' a , ' tcx > ,
1530
- arg_id : ast:: NodeId ,
1531
- // Found a non-None return that isn't Some(input)
1532
- found_mapping : bool ,
1533
- // Found a return that isn't Some
1534
- found_filtering : bool ,
1535
- }
1536
-
1537
- impl < ' a , ' tcx : ' a > ReturnVisitor < ' a , ' tcx > {
1538
- fn new ( cx : & ' a LateContext < ' a , ' tcx > , arg_id : ast:: NodeId ) -> ReturnVisitor < ' a , ' tcx > {
1539
- ReturnVisitor {
1540
- cx,
1541
- arg_id,
1542
- found_mapping : false ,
1543
- found_filtering : false ,
1544
- }
1545
- }
1546
- }
1547
-
1548
- impl < ' a , ' tcx > Visitor < ' tcx > for ReturnVisitor < ' a , ' tcx > {
1549
- fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr ) {
1550
- if let hir:: ExprKind :: Ret ( Some ( expr) ) = & expr. node {
1551
- let ( found_mapping, found_filtering) = check_expression ( self . cx , self . arg_id , expr) ;
1552
- self . found_mapping |= found_mapping;
1553
- self . found_filtering |= found_filtering;
1554
- } else {
1555
- walk_expr ( self , expr) ;
1556
- }
1557
- }
1558
-
1559
- fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' tcx > {
1560
- NestedVisitorMap :: None
1561
- }
1562
- }
1563
- }
1564
-
1565
1427
fn lint_iter_nth ( cx : & LateContext < ' _ , ' _ > , expr : & hir:: Expr , iter_args : & [ hir:: Expr ] , is_mut : bool ) {
1566
1428
let mut_str = if is_mut { "_mut" } else { "" } ;
1567
1429
let caller_type = if derefs_to_slice ( cx, & iter_args[ 0 ] , cx. tables . expr_ty ( & iter_args[ 0 ] ) ) . is_some ( ) {
0 commit comments