@@ -1453,11 +1453,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
1453
1453
then {
1454
1454
if cx. access_levels. is_exported( impl_item. hir_id) {
1455
1455
// 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 {
1457
1457
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) {
1461
1462
span_lint( cx, SHOULD_IMPLEMENT_TRAIT , impl_item. span, & format!(
1462
1463
"defining a method called `{}` on this type; consider implementing \
1463
1464
the `{}` trait or choosing a less ambiguous name", name, trait_name) ) ;
@@ -3352,38 +3353,45 @@ const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [
3352
3353
( Convention :: StartsWith ( "to_" ) , & [ SelfKind :: Ref ] ) ,
3353
3354
] ;
3354
3355
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
+
3355
3363
#[ 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" ) ,
3387
3395
] ;
3388
3396
3389
3397
#[ rustfmt:: skip]
@@ -3596,3 +3604,9 @@ fn lint_filetype_is_file(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &
3596
3604
let help_msg = format ! ( "use `{}FileType::is_dir()` instead" , help_unary) ;
3597
3605
span_lint_and_help ( cx, FILETYPE_IS_FILE , span, & lint_msg, & help_msg) ;
3598
3606
}
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