@@ -16,7 +16,6 @@ use rustc_target::abi::Abi;
16
16
use rustc_target:: abi:: { Integer , TagEncoding , Variants } ;
17
17
use rustc_target:: spec:: abi:: Abi as SpecAbi ;
18
18
19
- use if_chain:: if_chain;
20
19
use std:: cmp;
21
20
use std:: iter;
22
21
use std:: ops:: ControlFlow ;
@@ -1456,21 +1455,18 @@ impl InvalidAtomicOrdering {
1456
1455
sym:: AtomicI64 ,
1457
1456
sym:: AtomicI128 ,
1458
1457
] ;
1459
- if_chain ! {
1460
- if let ExprKind :: MethodCall ( ref method_path, args, _) = & expr. kind;
1461
- if recognized_names. contains( & method_path. ident. name) ;
1462
- if let Some ( m_def_id) = cx. typeck_results( ) . type_dependent_def_id( expr. hir_id) ;
1463
- if let Some ( impl_did) = cx. tcx. impl_of_method( m_def_id) ;
1464
- if let Some ( adt) = cx. tcx. type_of( impl_did) . ty_adt_def( ) ;
1458
+ if let ExprKind :: MethodCall ( ref method_path, args, _) = & expr. kind
1459
+ && recognized_names. contains ( & method_path. ident . name )
1460
+ && let Some ( m_def_id) = cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id )
1461
+ && let Some ( impl_did) = cx. tcx . impl_of_method ( m_def_id)
1462
+ && let Some ( adt) = cx. tcx . type_of ( impl_did) . ty_adt_def ( )
1465
1463
// skip extension traits, only lint functions from the standard library
1466
- if cx. tcx. trait_id_of_impl( impl_did) . is_none( ) ;
1467
-
1468
- if let Some ( parent) = cx. tcx. parent( adt. did) ;
1469
- if cx. tcx. is_diagnostic_item( sym:: atomic_mod, parent) ;
1470
- if ATOMIC_TYPES . contains( & cx. tcx. item_name( adt. did) ) ;
1471
- then {
1472
- return Some ( ( method_path. ident. name, args) ) ;
1473
- }
1464
+ && cx. tcx . trait_id_of_impl ( impl_did) . is_none ( )
1465
+ && let Some ( parent) = cx. tcx . parent ( adt. did )
1466
+ && cx. tcx . is_diagnostic_item ( sym:: atomic_mod, parent)
1467
+ && ATOMIC_TYPES . contains ( & cx. tcx . item_name ( adt. did ) )
1468
+ {
1469
+ return Some ( ( method_path. ident . name , args) ) ;
1474
1470
}
1475
1471
None
1476
1472
}
@@ -1499,111 +1495,103 @@ impl InvalidAtomicOrdering {
1499
1495
fn check_atomic_load_store ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
1500
1496
use rustc_hir:: def:: { DefKind , Res } ;
1501
1497
use rustc_hir:: QPath ;
1502
- if_chain ! {
1503
- if let Some ( ( method, args) ) = Self :: inherent_atomic_method_call( cx, expr, & [ sym:: load, sym:: store] ) ;
1504
- if let Some ( ( ordering_arg, invalid_ordering) ) = match method {
1498
+ if let Some ( ( method, args) ) = Self :: inherent_atomic_method_call ( cx, expr, & [ sym:: load, sym:: store] )
1499
+ && let Some ( ( ordering_arg, invalid_ordering) ) = match method {
1505
1500
sym:: load => Some ( ( & args[ 1 ] , sym:: Release ) ) ,
1506
1501
sym:: store => Some ( ( & args[ 2 ] , sym:: Acquire ) ) ,
1507
1502
_ => None ,
1508
- } ;
1509
-
1510
- if let ExprKind :: Path ( QPath :: Resolved ( _, path) ) = ordering_arg. kind;
1511
- if let Res :: Def ( DefKind :: Ctor ( ..) , ctor_id) = path. res;
1512
- if Self :: matches_ordering( cx, ctor_id, & [ invalid_ordering, sym:: AcqRel ] ) ;
1513
- then {
1514
- cx. struct_span_lint( INVALID_ATOMIC_ORDERING , ordering_arg. span, |diag| {
1515
- if method == sym:: load {
1516
- diag. build( "atomic loads cannot have `Release` or `AcqRel` ordering" )
1517
- . help( "consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`" )
1518
- . emit( )
1519
- } else {
1520
- debug_assert_eq!( method, sym:: store) ;
1521
- diag. build( "atomic stores cannot have `Acquire` or `AcqRel` ordering" )
1522
- . help( "consider using ordering modes `Release`, `SeqCst` or `Relaxed`" )
1523
- . emit( ) ;
1524
- }
1525
- } ) ;
1526
1503
}
1504
+ && let ExprKind :: Path ( QPath :: Resolved ( _, path) ) = ordering_arg. kind
1505
+ && let Res :: Def ( DefKind :: Ctor ( ..) , ctor_id) = path. res
1506
+ && Self :: matches_ordering ( cx, ctor_id, & [ invalid_ordering, sym:: AcqRel ] )
1507
+ {
1508
+ cx. struct_span_lint ( INVALID_ATOMIC_ORDERING , ordering_arg. span , |diag| {
1509
+ if method == sym:: load {
1510
+ diag. build ( "atomic loads cannot have `Release` or `AcqRel` ordering" )
1511
+ . help ( "consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`" )
1512
+ . emit ( )
1513
+ } else {
1514
+ debug_assert_eq ! ( method, sym:: store) ;
1515
+ diag. build ( "atomic stores cannot have `Acquire` or `AcqRel` ordering" )
1516
+ . help ( "consider using ordering modes `Release`, `SeqCst` or `Relaxed`" )
1517
+ . emit ( ) ;
1518
+ }
1519
+ } ) ;
1527
1520
}
1528
1521
}
1529
1522
1530
1523
fn check_memory_fence ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
1531
- if_chain ! {
1532
- if let ExprKind :: Call ( ref func, ref args) = expr. kind;
1533
- if let ExprKind :: Path ( ref func_qpath) = func. kind;
1534
- if let Some ( def_id) = cx. qpath_res( func_qpath, func. hir_id) . opt_def_id( ) ;
1535
- if matches!( cx. tcx. get_diagnostic_name( def_id) , Some ( sym:: fence | sym:: compiler_fence) ) ;
1536
- if let ExprKind :: Path ( ref ordering_qpath) = & args[ 0 ] . kind;
1537
- if let Some ( ordering_def_id) = cx. qpath_res( ordering_qpath, args[ 0 ] . hir_id) . opt_def_id( ) ;
1538
- if Self :: matches_ordering( cx, ordering_def_id, & [ sym:: Relaxed ] ) ;
1539
- then {
1540
- cx. struct_span_lint( INVALID_ATOMIC_ORDERING , args[ 0 ] . span, |diag| {
1541
- diag. build( "memory fences cannot have `Relaxed` ordering" )
1542
- . help( "consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`" )
1543
- . emit( ) ;
1544
- } ) ;
1545
- }
1524
+ if let ExprKind :: Call ( ref func, ref args) = expr. kind
1525
+ && let ExprKind :: Path ( ref func_qpath) = func. kind
1526
+ && let Some ( def_id) = cx. qpath_res ( func_qpath, func. hir_id ) . opt_def_id ( )
1527
+ && matches ! ( cx. tcx. get_diagnostic_name( def_id) , Some ( sym:: fence | sym:: compiler_fence) )
1528
+ && let ExprKind :: Path ( ref ordering_qpath) = & args[ 0 ] . kind
1529
+ && let Some ( ordering_def_id) = cx. qpath_res ( ordering_qpath, args[ 0 ] . hir_id ) . opt_def_id ( )
1530
+ && Self :: matches_ordering ( cx, ordering_def_id, & [ sym:: Relaxed ] )
1531
+ {
1532
+ cx. struct_span_lint ( INVALID_ATOMIC_ORDERING , args[ 0 ] . span , |diag| {
1533
+ diag. build ( "memory fences cannot have `Relaxed` ordering" )
1534
+ . help ( "consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`" )
1535
+ . emit ( ) ;
1536
+ } ) ;
1546
1537
}
1547
1538
}
1548
1539
1549
1540
fn check_atomic_compare_exchange ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
1550
- if_chain ! {
1551
- if let Some ( ( method, args) ) = Self :: inherent_atomic_method_call( cx, expr, & [ sym:: fetch_update, sym:: compare_exchange, sym:: compare_exchange_weak] ) ;
1552
- if let Some ( ( success_order_arg, failure_order_arg) ) = match method {
1541
+ if let Some ( ( method, args) ) = Self :: inherent_atomic_method_call ( cx, expr, & [ sym:: fetch_update, sym:: compare_exchange, sym:: compare_exchange_weak] )
1542
+ && let Some ( ( success_order_arg, failure_order_arg) ) = match method {
1553
1543
sym:: fetch_update => Some ( ( & args[ 1 ] , & args[ 2 ] ) ) ,
1554
1544
sym:: compare_exchange | sym:: compare_exchange_weak => Some ( ( & args[ 3 ] , & args[ 4 ] ) ) ,
1555
1545
_ => None ,
1556
- } ;
1557
-
1558
- if let Some ( fail_ordering_def_id) = Self :: opt_ordering_defid( cx, failure_order_arg) ;
1559
- then {
1560
- // Helper type holding on to some checking and error reporting data. Has
1561
- // - (success ordering,
1562
- // - list of failure orderings forbidden by the success order,
1563
- // - suggestion message)
1564
- type OrdLintInfo = ( Symbol , & ' static [ Symbol ] , & ' static str ) ;
1565
- const RELAXED : OrdLintInfo = ( sym:: Relaxed , & [ sym:: SeqCst , sym:: Acquire ] , "ordering mode `Relaxed`" ) ;
1566
- const ACQUIRE : OrdLintInfo = ( sym:: Acquire , & [ sym:: SeqCst ] , "ordering modes `Acquire` or `Relaxed`" ) ;
1567
- const SEQ_CST : OrdLintInfo = ( sym:: SeqCst , & [ ] , "ordering modes `Acquire`, `SeqCst` or `Relaxed`" ) ;
1568
- const RELEASE : OrdLintInfo = ( sym:: Release , RELAXED . 1 , RELAXED . 2 ) ;
1569
- const ACQREL : OrdLintInfo = ( sym:: AcqRel , ACQUIRE . 1 , ACQUIRE . 2 ) ;
1570
- const SEARCH : [ OrdLintInfo ; 5 ] = [ RELAXED , ACQUIRE , SEQ_CST , RELEASE , ACQREL ] ;
1571
-
1572
- let success_lint_info = Self :: opt_ordering_defid( cx, success_order_arg)
1573
- . and_then( |success_ord_def_id| -> Option <OrdLintInfo > {
1574
- SEARCH
1575
- . iter( )
1576
- . copied( )
1577
- . find( |( ordering, ..) | {
1578
- Self :: matches_ordering( cx, success_ord_def_id, & [ * ordering] )
1579
- } )
1580
- } ) ;
1581
- if Self :: matches_ordering( cx, fail_ordering_def_id, & [ sym:: Release , sym:: AcqRel ] ) {
1582
- // If we don't know the success order is, use what we'd suggest
1583
- // if it were maximally permissive.
1584
- let suggested = success_lint_info. unwrap_or( SEQ_CST ) . 2 ;
1546
+ }
1547
+ && let Some ( fail_ordering_def_id) = Self :: opt_ordering_defid ( cx, failure_order_arg)
1548
+ {
1549
+ // Helper type holding on to some checking and error reporting data. Has
1550
+ // - (success ordering,
1551
+ // - list of failure orderings forbidden by the success order,
1552
+ // - suggestion message)
1553
+ type OrdLintInfo = ( Symbol , & ' static [ Symbol ] , & ' static str ) ;
1554
+ const RELAXED : OrdLintInfo = ( sym:: Relaxed , & [ sym:: SeqCst , sym:: Acquire ] , "ordering mode `Relaxed`" ) ;
1555
+ const ACQUIRE : OrdLintInfo = ( sym:: Acquire , & [ sym:: SeqCst ] , "ordering modes `Acquire` or `Relaxed`" ) ;
1556
+ const SEQ_CST : OrdLintInfo = ( sym:: SeqCst , & [ ] , "ordering modes `Acquire`, `SeqCst` or `Relaxed`" ) ;
1557
+ const RELEASE : OrdLintInfo = ( sym:: Release , RELAXED . 1 , RELAXED . 2 ) ;
1558
+ const ACQREL : OrdLintInfo = ( sym:: AcqRel , ACQUIRE . 1 , ACQUIRE . 2 ) ;
1559
+ const SEARCH : [ OrdLintInfo ; 5 ] = [ RELAXED , ACQUIRE , SEQ_CST , RELEASE , ACQREL ] ;
1560
+
1561
+ let success_lint_info = Self :: opt_ordering_defid ( cx, success_order_arg)
1562
+ . and_then ( |success_ord_def_id| -> Option < OrdLintInfo > {
1563
+ SEARCH
1564
+ . iter ( )
1565
+ . copied ( )
1566
+ . find ( |( ordering, ..) | {
1567
+ Self :: matches_ordering ( cx, success_ord_def_id, & [ * ordering] )
1568
+ } )
1569
+ } ) ;
1570
+ if Self :: matches_ordering ( cx, fail_ordering_def_id, & [ sym:: Release , sym:: AcqRel ] ) {
1571
+ // If we don't know the success order is, use what we'd suggest
1572
+ // if it were maximally permissive.
1573
+ let suggested = success_lint_info. unwrap_or ( SEQ_CST ) . 2 ;
1574
+ cx. struct_span_lint ( INVALID_ATOMIC_ORDERING , failure_order_arg. span , |diag| {
1575
+ let msg = format ! (
1576
+ "{}'s failure ordering may not be `Release` or `AcqRel`" ,
1577
+ method,
1578
+ ) ;
1579
+ diag. build ( & msg)
1580
+ . help ( & format ! ( "consider using {} instead" , suggested) )
1581
+ . emit ( ) ;
1582
+ } ) ;
1583
+ } else if let Some ( ( success_ord, bad_ords_given_success, suggested) ) = success_lint_info {
1584
+ if Self :: matches_ordering ( cx, fail_ordering_def_id, bad_ords_given_success) {
1585
1585
cx. struct_span_lint ( INVALID_ATOMIC_ORDERING , failure_order_arg. span , |diag| {
1586
1586
let msg = format ! (
1587
- "{}'s failure ordering may not be `Release` or `AcqRel `" ,
1587
+ "{}'s failure ordering may not be stronger than the success ordering of `{} `" ,
1588
1588
method,
1589
+ success_ord,
1589
1590
) ;
1590
1591
diag. build ( & msg)
1591
1592
. help ( & format ! ( "consider using {} instead" , suggested) )
1592
1593
. emit ( ) ;
1593
1594
} ) ;
1594
- } else if let Some ( ( success_ord, bad_ords_given_success, suggested) ) = success_lint_info {
1595
- if Self :: matches_ordering( cx, fail_ordering_def_id, bad_ords_given_success) {
1596
- cx. struct_span_lint( INVALID_ATOMIC_ORDERING , failure_order_arg. span, |diag| {
1597
- let msg = format!(
1598
- "{}'s failure ordering may not be stronger than the success ordering of `{}`" ,
1599
- method,
1600
- success_ord,
1601
- ) ;
1602
- diag. build( & msg)
1603
- . help( & format!( "consider using {} instead" , suggested) )
1604
- . emit( ) ;
1605
- } ) ;
1606
- }
1607
1595
}
1608
1596
}
1609
1597
}
0 commit comments