@@ -1426,11 +1426,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
14261426 then {
14271427 if cx. access_levels. is_exported( impl_item. hir_id) {
14281428 // check missing trait implementations
1429- for & ( method_name, n_args, self_kind, out_type, trait_name) in & TRAIT_METHODS {
1429+ for & ( method_name, n_args, fn_header , self_kind, out_type, trait_name) in & TRAIT_METHODS {
14301430 if name == method_name &&
1431- sig. decl. inputs. len( ) == n_args &&
1432- out_type. matches( cx, & sig. decl. output) &&
1433- self_kind. matches( cx, self_ty, first_arg_ty) {
1431+ sig. decl. inputs. len( ) == n_args &&
1432+ out_type. matches( cx, & sig. decl. output) &&
1433+ self_kind. matches( cx, self_ty, first_arg_ty) &&
1434+ fn_header_equals( * fn_header, sig. header) {
14341435 span_lint( cx, SHOULD_IMPLEMENT_TRAIT , impl_item. span, & format!(
14351436 "defining a method called `{}` on this type; consider implementing \
14361437 the `{}` trait or choosing a less ambiguous name", name, trait_name) ) ;
@@ -3266,38 +3267,45 @@ const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [
32663267 ( Convention :: StartsWith ( "to_" ) , & [ SelfKind :: Ref ] ) ,
32673268] ;
32683269
3270+ const FN_HEADER : hir:: FnHeader = hir:: FnHeader {
3271+ unsafety : hir:: Unsafety :: Normal ,
3272+ constness : hir:: Constness :: NotConst ,
3273+ asyncness : hir:: IsAsync :: NotAsync ,
3274+ abi : rustc_target:: spec:: abi:: Abi :: Rust ,
3275+ } ;
3276+
32693277#[ rustfmt:: skip]
3270- const TRAIT_METHODS : [ ( & str , usize , SelfKind , OutType , & str ) ; 30 ] = [
3271- ( "add" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Add" ) ,
3272- ( "as_mut" , 1 , SelfKind :: RefMut , OutType :: Ref , "std::convert::AsMut" ) ,
3273- ( "as_ref" , 1 , SelfKind :: Ref , OutType :: Ref , "std::convert::AsRef" ) ,
3274- ( "bitand" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::BitAnd" ) ,
3275- ( "bitor" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::BitOr" ) ,
3276- ( "bitxor" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::BitXor" ) ,
3277- ( "borrow" , 1 , SelfKind :: Ref , OutType :: Ref , "std::borrow::Borrow" ) ,
3278- ( "borrow_mut" , 1 , SelfKind :: RefMut , OutType :: Ref , "std::borrow::BorrowMut" ) ,
3279- ( "clone" , 1 , SelfKind :: Ref , OutType :: Any , "std::clone::Clone" ) ,
3280- ( "cmp" , 2 , SelfKind :: Ref , OutType :: Any , "std::cmp::Ord" ) ,
3281- ( "default" , 0 , SelfKind :: No , OutType :: Any , "std::default::Default" ) ,
3282- ( "deref" , 1 , SelfKind :: Ref , OutType :: Ref , "std::ops::Deref" ) ,
3283- ( "deref_mut" , 1 , SelfKind :: RefMut , OutType :: Ref , "std::ops::DerefMut" ) ,
3284- ( "div" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Div" ) ,
3285- ( "drop" , 1 , SelfKind :: RefMut , OutType :: Unit , "std::ops::Drop" ) ,
3286- ( "eq" , 2 , SelfKind :: Ref , OutType :: Bool , "std::cmp::PartialEq" ) ,
3287- ( "from_iter" , 1 , SelfKind :: No , OutType :: Any , "std::iter::FromIterator" ) ,
3288- ( "from_str" , 1 , SelfKind :: No , OutType :: Any , "std::str::FromStr" ) ,
3289- ( "hash" , 2 , SelfKind :: Ref , OutType :: Unit , "std::hash::Hash" ) ,
3290- ( "index" , 2 , SelfKind :: Ref , OutType :: Ref , "std::ops::Index" ) ,
3291- ( "index_mut" , 2 , SelfKind :: RefMut , OutType :: Ref , "std::ops::IndexMut" ) ,
3292- ( "into_iter" , 1 , SelfKind :: Value , OutType :: Any , "std::iter::IntoIterator" ) ,
3293- ( "mul" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Mul" ) ,
3294- ( "neg" , 1 , SelfKind :: Value , OutType :: Any , "std::ops::Neg" ) ,
3295- ( "next" , 1 , SelfKind :: RefMut , OutType :: Any , "std::iter::Iterator" ) ,
3296- ( "not" , 1 , SelfKind :: Value , OutType :: Any , "std::ops::Not" ) ,
3297- ( "rem" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Rem" ) ,
3298- ( "shl" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Shl" ) ,
3299- ( "shr" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Shr" ) ,
3300- ( "sub" , 2 , SelfKind :: Value , OutType :: Any , "std::ops::Sub" ) ,
3278+ const TRAIT_METHODS : [ ( & str , usize , & hir :: FnHeader , SelfKind , OutType , & str ) ; 30 ] = [
3279+ ( "add" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Add" ) ,
3280+ ( "as_mut" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Ref , "std::convert::AsMut" ) ,
3281+ ( "as_ref" , 1 , & FN_HEADER , SelfKind :: Ref , OutType :: Ref , "std::convert::AsRef" ) ,
3282+ ( "bitand" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::BitAnd" ) ,
3283+ ( "bitor" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::BitOr" ) ,
3284+ ( "bitxor" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::BitXor" ) ,
3285+ ( "borrow" , 1 , & FN_HEADER , SelfKind :: Ref , OutType :: Ref , "std::borrow::Borrow" ) ,
3286+ ( "borrow_mut" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Ref , "std::borrow::BorrowMut" ) ,
3287+ ( "clone" , 1 , & FN_HEADER , SelfKind :: Ref , OutType :: Any , "std::clone::Clone" ) ,
3288+ ( "cmp" , 2 , & FN_HEADER , SelfKind :: Ref , OutType :: Any , "std::cmp::Ord" ) ,
3289+ ( "default" , 0 , & FN_HEADER , SelfKind :: No , OutType :: Any , "std::default::Default" ) ,
3290+ ( "deref" , 1 , & FN_HEADER , SelfKind :: Ref , OutType :: Ref , "std::ops::Deref" ) ,
3291+ ( "deref_mut" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Ref , "std::ops::DerefMut" ) ,
3292+ ( "div" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Div" ) ,
3293+ ( "drop" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Unit , "std::ops::Drop" ) ,
3294+ ( "eq" , 2 , & FN_HEADER , SelfKind :: Ref , OutType :: Bool , "std::cmp::PartialEq" ) ,
3295+ ( "from_iter" , 1 , & FN_HEADER , SelfKind :: No , OutType :: Any , "std::iter::FromIterator" ) ,
3296+ ( "from_str" , 1 , & FN_HEADER , SelfKind :: No , OutType :: Any , "std::str::FromStr" ) ,
3297+ ( "hash" , 2 , & FN_HEADER , SelfKind :: Ref , OutType :: Unit , "std::hash::Hash" ) ,
3298+ ( "index" , 2 , & FN_HEADER , SelfKind :: Ref , OutType :: Ref , "std::ops::Index" ) ,
3299+ ( "index_mut" , 2 , & FN_HEADER , SelfKind :: RefMut , OutType :: Ref , "std::ops::IndexMut" ) ,
3300+ ( "into_iter" , 1 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::iter::IntoIterator" ) ,
3301+ ( "mul" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Mul" ) ,
3302+ ( "neg" , 1 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Neg" ) ,
3303+ ( "next" , 1 , & FN_HEADER , SelfKind :: RefMut , OutType :: Any , "std::iter::Iterator" ) ,
3304+ ( "not" , 1 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Not" ) ,
3305+ ( "rem" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Rem" ) ,
3306+ ( "shl" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Shl" ) ,
3307+ ( "shr" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Shr" ) ,
3308+ ( "sub" , 2 , & FN_HEADER , SelfKind :: Value , OutType :: Any , "std::ops::Sub" ) ,
33013309] ;
33023310
33033311#[ rustfmt:: skip]
@@ -3510,3 +3518,9 @@ fn lint_filetype_is_file(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &
35103518 let help_msg = format ! ( "use `{}FileType::is_dir()` instead" , help_unary) ;
35113519 span_lint_and_help ( cx, FILETYPE_IS_FILE , span, & lint_msg, & help_msg) ;
35123520}
3521+
3522+ fn fn_header_equals ( expected : hir:: FnHeader , actual : hir:: FnHeader ) -> bool {
3523+ expected. constness == actual. constness
3524+ && expected. unsafety == actual. unsafety
3525+ && expected. asyncness == actual. asyncness
3526+ }
0 commit comments