@@ -538,68 +538,66 @@ impl LateLintPass for Pass {
538
538
}
539
539
}
540
540
541
- fn check_item ( & mut self , cx : & LateContext , item : & hir:: Item ) {
542
- if in_external_macro ( cx, item . span ) {
541
+ fn check_impl_item ( & mut self , cx : & LateContext , implitem : & hir:: ImplItem ) {
542
+ if in_external_macro ( cx, implitem . span ) {
543
543
return ;
544
544
}
545
+ let name = implitem. name ;
546
+ let parent = cx. tcx . map . get_parent ( implitem. id ) ;
547
+ let item = cx. tcx . map . expect_item ( parent) ;
548
+ if_let_chain ! { [
549
+ let hir:: ImplItemKind :: Method ( ref sig, _) = implitem. node,
550
+ let Some ( explicit_self) = sig. decl. inputs. get( 0 ) . and_then( hir:: Arg :: to_self) ,
551
+ let hir:: ItemImpl ( _, _, _, None , _, _) = item. node,
552
+ ] , {
553
+ // check missing trait implementations
554
+ for & ( method_name, n_args, self_kind, out_type, trait_name) in & TRAIT_METHODS {
555
+ if name. as_str( ) == method_name &&
556
+ sig. decl. inputs. len( ) == n_args &&
557
+ out_type. matches( & sig. decl. output) &&
558
+ self_kind. matches( & explicit_self, false ) {
559
+ span_lint( cx, SHOULD_IMPLEMENT_TRAIT , implitem. span, & format!(
560
+ "defining a method called `{}` on this type; consider implementing \
561
+ the `{}` trait or choosing a less ambiguous name", name, trait_name) ) ;
562
+ }
563
+ }
545
564
546
- if let hir:: ItemImpl ( _, _, _, None , _, ref items) = item. node {
547
- for implitem in items {
548
- let name = implitem. name ;
565
+ // check conventions w.r.t. conversion method names and predicates
566
+ let ty = cx. tcx. lookup_item_type( cx. tcx. map. local_def_id( item. id) ) . ty;
567
+ let is_copy = is_copy( cx, ty, item. id) ;
568
+ for & ( ref conv, self_kinds) in & CONVENTIONS {
549
569
if_let_chain! { [
550
- let hir :: ImplItemKind :: Method ( ref sig , _ ) = implitem . node ,
570
+ conv . check ( & name . as_str ( ) ) ,
551
571
let Some ( explicit_self) = sig. decl. inputs. get( 0 ) . and_then( hir:: Arg :: to_self) ,
572
+ !self_kinds. iter( ) . any( |k| k. matches( & explicit_self, is_copy) ) ,
552
573
] , {
553
- // check missing trait implementations
554
- for & ( method_name, n_args, self_kind, out_type, trait_name) in & TRAIT_METHODS {
555
- if name. as_str( ) == method_name &&
556
- sig. decl. inputs. len( ) == n_args &&
557
- out_type. matches( & sig. decl. output) &&
558
- self_kind. matches( & explicit_self, false ) {
559
- span_lint( cx, SHOULD_IMPLEMENT_TRAIT , implitem. span, & format!(
560
- "defining a method called `{}` on this type; consider implementing \
561
- the `{}` trait or choosing a less ambiguous name", name, trait_name) ) ;
562
- }
563
- }
564
-
565
- // check conventions w.r.t. conversion method names and predicates
566
- let ty = cx. tcx. lookup_item_type( cx. tcx. map. local_def_id( item. id) ) . ty;
567
- let is_copy = is_copy( cx, ty, item. id) ;
568
- for & ( ref conv, self_kinds) in & CONVENTIONS {
569
- if_let_chain! { [
570
- conv. check( & name. as_str( ) ) ,
571
- let Some ( explicit_self) = sig. decl. inputs. get( 0 ) . and_then( hir:: Arg :: to_self) ,
572
- !self_kinds. iter( ) . any( |k| k. matches( & explicit_self, is_copy) ) ,
573
- ] , {
574
- let lint = if item. vis == hir:: Visibility :: Public {
575
- WRONG_PUB_SELF_CONVENTION
576
- } else {
577
- WRONG_SELF_CONVENTION
578
- } ;
579
- span_lint( cx,
580
- lint,
581
- explicit_self. span,
582
- & format!( "methods called `{}` usually take {}; consider choosing a less \
583
- ambiguous name",
584
- conv,
585
- & self_kinds. iter( )
586
- . map( |k| k. description( ) )
587
- . collect:: <Vec <_>>( )
588
- . join( " or " ) ) ) ;
589
- } }
590
- }
591
-
592
- let ret_ty = return_ty( cx, implitem. id) ;
593
- if & name. as_str( ) == & "new" &&
594
- !ret_ty. map_or( false , |ret_ty| ret_ty. walk( ) . any( |t| same_tys( cx, t, ty, implitem. id) ) ) {
595
- span_lint( cx,
596
- NEW_RET_NO_SELF ,
597
- explicit_self. span,
598
- "methods called `new` usually return `Self`" ) ;
599
- }
574
+ let lint = if item. vis == hir:: Visibility :: Public {
575
+ WRONG_PUB_SELF_CONVENTION
576
+ } else {
577
+ WRONG_SELF_CONVENTION
578
+ } ;
579
+ span_lint( cx,
580
+ lint,
581
+ explicit_self. span,
582
+ & format!( "methods called `{}` usually take {}; consider choosing a less \
583
+ ambiguous name",
584
+ conv,
585
+ & self_kinds. iter( )
586
+ . map( |k| k. description( ) )
587
+ . collect:: <Vec <_>>( )
588
+ . join( " or " ) ) ) ;
600
589
} }
601
590
}
602
- }
591
+
592
+ let ret_ty = return_ty( cx, implitem. id) ;
593
+ if & name. as_str( ) == & "new" &&
594
+ !ret_ty. map_or( false , |ret_ty| ret_ty. walk( ) . any( |t| same_tys( cx, t, ty, implitem. id) ) ) {
595
+ span_lint( cx,
596
+ NEW_RET_NO_SELF ,
597
+ explicit_self. span,
598
+ "methods called `new` usually return `Self`" ) ;
599
+ }
600
+ } }
603
601
}
604
602
}
605
603
0 commit comments