@@ -1426,11 +1426,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
1426
1426
then {
1427
1427
if cx. access_levels. is_exported( impl_item. hir_id) {
1428
1428
// 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 {
1430
1430
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) {
1434
1435
span_lint( cx, SHOULD_IMPLEMENT_TRAIT , impl_item. span, & format!(
1435
1436
"defining a method called `{}` on this type; consider implementing \
1436
1437
the `{}` trait or choosing a less ambiguous name", name, trait_name) ) ;
@@ -3266,38 +3267,45 @@ const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [
3266
3267
( Convention :: StartsWith ( "to_" ) , & [ SelfKind :: Ref ] ) ,
3267
3268
] ;
3268
3269
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
+
3269
3277
#[ 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" ) ,
3301
3309
] ;
3302
3310
3303
3311
#[ rustfmt:: skip]
@@ -3510,3 +3518,9 @@ fn lint_filetype_is_file(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &
3510
3518
let help_msg = format ! ( "use `{}FileType::is_dir()` instead" , help_unary) ;
3511
3519
span_lint_and_help ( cx, FILETYPE_IS_FILE , span, & lint_msg, & help_msg) ;
3512
3520
}
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