@@ -1453,11 +1453,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
14531453 then {
14541454 if cx. access_levels. is_exported( impl_item. hir_id) {
14551455 // check missing trait implementations
1456- for & ( method_name, n_args, self_kind, out_type, trait_name) in & TRAIT_METHODS {
1456+ for & ( method_name, n_args, fn_header , self_kind, out_type, trait_name) in & TRAIT_METHODS {
14571457 if name == method_name &&
1458- sig. decl. inputs. len( ) == n_args &&
1459- out_type. matches( cx, & sig. decl. output) &&
1460- self_kind. matches( cx, self_ty, first_arg_ty) {
1458+ sig. decl. inputs. len( ) == n_args &&
1459+ out_type. matches( cx, & sig. decl. output) &&
1460+ self_kind. matches( cx, self_ty, first_arg_ty) &&
1461+ fn_header_equals( * fn_header, sig. header) {
14611462 span_lint( cx, SHOULD_IMPLEMENT_TRAIT , impl_item. span, & format!(
14621463 "defining a method called `{}` on this type; consider implementing \
14631464 the `{}` trait or choosing a less ambiguous name", name, trait_name) ) ;
@@ -3352,38 +3353,45 @@ const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [
33523353 ( Convention :: StartsWith ( "to_" ) , & [ SelfKind :: Ref ] ) ,
33533354] ;
33543355
3356+ const FN_HEADER : hir:: FnHeader = hir:: FnHeader {
3357+ unsafety : hir:: Unsafety :: Normal ,
3358+ constness : hir:: Constness :: NotConst ,
3359+ asyncness : hir:: IsAsync :: NotAsync ,
3360+ abi : rustc_target:: spec:: abi:: Abi :: Rust ,
3361+ } ;
3362+
33553363#[ rustfmt:: skip]
3356- const TRAIT_METHODS : [ ( & str , usize , SelfKind , OutType , & str ) ; 30 ] = [
3357- ( "add" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Add" ) ,
3358- ( "as_mut" , 1 , SelfKind :: RefMut , OutType :: Ref , "std::convert::AsMut" ) ,
3359- ( "as_ref" , 1 , SelfKind :: Ref , OutType :: Ref , "std::convert::AsRef" ) ,
3360- ( "bitand" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::BitAnd" ) ,
3361- ( "bitor" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::BitOr" ) ,
3362- ( "bitxor" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::BitXor" ) ,
3363- ( "borrow" , 1 , SelfKind :: Ref , OutType :: Ref , "std::borrow::Borrow" ) ,
3364- ( "borrow_mut" , 1 , SelfKind :: RefMut , OutType :: Ref , "std::borrow::BorrowMut" ) ,
3365- ( "clone" , 1 , SelfKind :: Ref , OutType :: Any , "std::clone::Clone" ) ,
3366- ( "cmp" , 2 , SelfKind :: Ref , OutType :: Any , "std::cmp::Ord" ) ,
3367- ( "default" , 0 , SelfKind :: No , OutType :: Any , "std::default::Default" ) ,
3368- ( "deref" , 1 , SelfKind :: Ref , OutType :: Ref , "std::ops::Deref" ) ,
3369- ( "deref_mut" , 1 , SelfKind :: RefMut , OutType :: Ref , "std::ops::DerefMut" ) ,
3370- ( "div" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Div" ) ,
3371- ( "drop" , 1 , SelfKind :: RefMut , OutType :: Unit , "std::ops::Drop" ) ,
3372- ( "eq" , 2 , SelfKind :: Ref , OutType :: Bool , "std::cmp::PartialEq" ) ,
3373- ( "from_iter" , 1 , SelfKind :: No , OutType :: Any , "std::iter::FromIterator" ) ,
3374- ( "from_str" , 1 , SelfKind :: No , OutType :: Any , "std::str::FromStr" ) ,
3375- ( "hash" , 2 , SelfKind :: Ref , OutType :: Unit , "std::hash::Hash" ) ,
3376- ( "index" , 2 , SelfKind :: Ref , OutType :: Ref , "std::ops::Index" ) ,
3377- ( "index_mut" , 2 , SelfKind :: RefMut , OutType :: Ref , "std::ops::IndexMut" ) ,
3378- ( "into_iter" , 1 , SelfKind :: Value , OutType :: Any , "std::iter::IntoIterator" ) ,
3379- ( "mul" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Mul" ) ,
3380- ( "neg" , 1 , SelfKind :: Value , OutType :: Any , "std::ops::Neg" ) ,
3381- ( "next" , 1 , SelfKind :: RefMut , OutType :: Any , "std::iter::Iterator" ) ,
3382- ( "not" , 1 , SelfKind :: Value , OutType :: Any , "std::ops::Not" ) ,
3383- ( "rem" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Rem" ) ,
3384- ( "shl" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Shl" ) ,
3385- ( "shr" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Shr" ) ,
3386- ( "sub" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Sub" ) ,
3364+ const TRAIT_METHODS : [ ( & str , usize , & hir :: FnHeader , SelfKind , OutType , & str ) ; 30 ] = [
3365+ ( "add" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Add" ) ,
3366+ ( "as_mut" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Ref , "std::convert::AsMut" ) ,
3367+ ( "as_ref" , 1 , & FN_HEADER , SelfKind :: Ref , OutType :: Ref , "std::convert::AsRef" ) ,
3368+ ( "bitand" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::BitAnd" ) ,
3369+ ( "bitor" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::BitOr" ) ,
3370+ ( "bitxor" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::BitXor" ) ,
3371+ ( "borrow" , 1 , & FN_HEADER , SelfKind :: Ref , OutType :: Ref , "std::borrow::Borrow" ) ,
3372+ ( "borrow_mut" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Ref , "std::borrow::BorrowMut" ) ,
3373+ ( "clone" , 1 , & FN_HEADER , SelfKind :: Ref , OutType :: Any , "std::clone::Clone" ) ,
3374+ ( "cmp" , 2 , & FN_HEADER , SelfKind :: Ref , OutType :: Any , "std::cmp::Ord" ) ,
3375+ ( "default" , 0 , & FN_HEADER , SelfKind :: No , OutType :: Any , "std::default::Default" ) ,
3376+ ( "deref" , 1 , & FN_HEADER , SelfKind :: Ref , OutType :: Ref , "std::ops::Deref" ) ,
3377+ ( "deref_mut" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Ref , "std::ops::DerefMut" ) ,
3378+ ( "div" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Div" ) ,
3379+ ( "drop" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Unit , "std::ops::Drop" ) ,
3380+ ( "eq" , 2 , & FN_HEADER , SelfKind :: Ref , OutType :: Bool , "std::cmp::PartialEq" ) ,
3381+ ( "from_iter" , 1 , & FN_HEADER , SelfKind :: No , OutType :: Any , "std::iter::FromIterator" ) ,
3382+ ( "from_str" , 1 , & FN_HEADER , SelfKind :: No , OutType :: Any , "std::str::FromStr" ) ,
3383+ ( "hash" , 2 , & FN_HEADER , SelfKind :: Ref , OutType :: Unit , "std::hash::Hash" ) ,
3384+ ( "index" , 2 , & FN_HEADER , SelfKind :: Ref , OutType :: Ref , "std::ops::Index" ) ,
3385+ ( "index_mut" , 2 , & FN_HEADER , SelfKind :: RefMut , OutType :: Ref , "std::ops::IndexMut" ) ,
3386+ ( "into_iter" , 1 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::iter::IntoIterator" ) ,
3387+ ( "mul" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Mul" ) ,
3388+ ( "neg" , 1 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Neg" ) ,
3389+ ( "next" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Any , "std::iter::Iterator" ) ,
3390+ ( "not" , 1 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Not" ) ,
3391+ ( "rem" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Rem" ) ,
3392+ ( "shl" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Shl" ) ,
3393+ ( "shr" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Shr" ) ,
3394+ ( "sub" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Sub" ) ,
33873395] ;
33883396
33893397#[ rustfmt:: skip]
@@ -3596,3 +3604,9 @@ fn lint_filetype_is_file(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &
35963604 let help_msg = format ! ( "use `{}FileType::is_dir()` instead" , help_unary) ;
35973605 span_lint_and_help ( cx, FILETYPE_IS_FILE , span, & lint_msg, & help_msg) ;
35983606}
3607+
3608+ fn fn_header_equals ( expected : hir:: FnHeader , actual : hir:: FnHeader ) -> bool {
3609+ expected. constness == actual. constness
3610+ && expected. unsafety == actual. unsafety
3611+ && expected. asyncness == actual. asyncness
3612+ }
0 commit comments