@@ -15,6 +15,7 @@ use rustc_hir::intravisit::{self, Visitor};
15
15
use rustc_lint:: { LateContext , LateLintPass , Lint , LintContext } ;
16
16
use rustc_middle:: hir:: map:: Map ;
17
17
use rustc_middle:: lint:: in_external_macro;
18
+ use rustc_middle:: ty:: subst:: GenericArgKind ;
18
19
use rustc_middle:: ty:: { self , Predicate , Ty } ;
19
20
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
20
21
use rustc_span:: source_map:: Span ;
@@ -1407,7 +1408,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
1407
1408
let parent = cx. tcx . hir ( ) . get_parent_item ( impl_item. hir_id ) ;
1408
1409
let item = cx. tcx . hir ( ) . expect_item ( parent) ;
1409
1410
let def_id = cx. tcx . hir ( ) . local_def_id ( item. hir_id ) ;
1410
- let ty = cx. tcx . type_of ( def_id) ;
1411
+ let self_ty = cx. tcx . type_of ( def_id) ;
1411
1412
if_chain ! {
1412
1413
if let hir:: ImplItemKind :: Fn ( ref sig, id) = impl_item. kind;
1413
1414
if let Some ( first_arg) = iter_input_pats( & sig. decl, cx. tcx. hir( ) . body( id) ) . next( ) ;
@@ -1429,7 +1430,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
1429
1430
if name == method_name &&
1430
1431
sig. decl. inputs. len( ) == n_args &&
1431
1432
out_type. matches( cx, & sig. decl. output) &&
1432
- self_kind. matches( cx, ty , first_arg_ty) {
1433
+ self_kind. matches( cx, self_ty , first_arg_ty) {
1433
1434
span_lint( cx, SHOULD_IMPLEMENT_TRAIT , impl_item. span, & format!(
1434
1435
"defining a method called `{}` on this type; consider implementing \
1435
1436
the `{}` trait or choosing a less ambiguous name", name, trait_name) ) ;
@@ -1441,7 +1442,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
1441
1442
. iter( )
1442
1443
. find( |( ref conv, _) | conv. check( & name) )
1443
1444
{
1444
- if !self_kinds. iter( ) . any( |k| k. matches( cx, ty , first_arg_ty) ) {
1445
+ if !self_kinds. iter( ) . any( |k| k. matches( cx, self_ty , first_arg_ty) ) {
1445
1446
let lint = if item. vis. node. is_pub( ) {
1446
1447
WRONG_PUB_SELF_CONVENTION
1447
1448
} else {
@@ -1471,8 +1472,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
1471
1472
if let hir:: ImplItemKind :: Fn ( _, _) = impl_item. kind {
1472
1473
let ret_ty = return_ty ( cx, impl_item. hir_id ) ;
1473
1474
1475
+ let contains_self_ty = |ty : Ty < ' tcx > | {
1476
+ ty. walk ( ) . any ( |inner| match inner. unpack ( ) {
1477
+ GenericArgKind :: Type ( inner_ty) => same_tys ( cx, self_ty, inner_ty) ,
1478
+
1479
+ GenericArgKind :: Lifetime ( _) | GenericArgKind :: Const ( _) => false ,
1480
+ } )
1481
+ } ;
1482
+
1474
1483
// walk the return type and check for Self (this does not check associated types)
1475
- if ret_ty . walk ( ) . any ( |inner_type| same_tys ( cx , ty , inner_type ) ) {
1484
+ if contains_self_ty ( ret_ty ) {
1476
1485
return ;
1477
1486
}
1478
1487
@@ -1486,18 +1495,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
1486
1495
let associated_type = binder. skip_binder ( ) ;
1487
1496
1488
1497
// walk the associated type and check for Self
1489
- for inner_type in associated_type. walk ( ) {
1490
- if same_tys ( cx, ty, inner_type) {
1491
- return ;
1492
- }
1498
+ if contains_self_ty ( associated_type) {
1499
+ return ;
1493
1500
}
1494
1501
} ,
1495
1502
( _, _) => { } ,
1496
1503
}
1497
1504
}
1498
1505
}
1499
1506
1500
- if name == "new" && !same_tys ( cx, ret_ty, ty ) {
1507
+ if name == "new" && !same_tys ( cx, ret_ty, self_ty ) {
1501
1508
span_lint (
1502
1509
cx,
1503
1510
NEW_RET_NO_SELF ,
0 commit comments