@@ -27,19 +27,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
27
27
// Consider the example `fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32`
28
28
// Here, we would return the hir::Arg for y, we return the type &'a
29
29
// i32, which is the type of y but with the anonymous region replaced
30
- // with 'a and also the corresponding bound region.
31
- fn find_arg_with_anonymous_region ( & self ,
32
- anon_region : Region < ' tcx > ,
33
- named_region : Region < ' tcx > )
34
- -> Option < ( & hir:: Arg , ty:: Ty < ' tcx > , ty:: BoundRegion ) > {
30
+ // with 'a, the corresponding bound region and is_first which is true if
31
+ // the hir::Arg is the first argument in the function declaration.
32
+ fn find_arg_with_anonymous_region
33
+ ( & self ,
34
+ anon_region : Region < ' tcx > ,
35
+ named_region : Region < ' tcx > )
36
+ -> Option < ( & hir:: Arg , ty:: Ty < ' tcx > , ty:: BoundRegion , bool ) > {
35
37
36
38
match * anon_region {
37
39
ty:: ReFree ( ref free_region) => {
38
40
39
41
let id = free_region. scope ;
40
42
let node_id = self . tcx . hir . as_local_node_id ( id) . unwrap ( ) ;
41
43
let body_id = self . tcx . hir . maybe_body_owned_by ( node_id) . unwrap ( ) ;
42
-
44
+ let mut is_first = false ;
43
45
let body = self . tcx . hir . body ( body_id) ;
44
46
body. arguments
45
47
. iter ( )
@@ -56,7 +58,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
56
58
r
57
59
} ) ;
58
60
if found_anon_region {
59
- return Some ( ( arg, new_arg_ty, free_region. bound_region ) ) ;
61
+ if body. arguments . iter ( ) . nth ( 0 ) == Some ( & arg) {
62
+ is_first = true ;
63
+ }
64
+ return Some ( ( arg,
65
+ new_arg_ty,
66
+ free_region. bound_region ,
67
+ is_first) ) ;
60
68
} else {
61
69
None
62
70
}
@@ -86,19 +94,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
86
94
// only introduced anonymous regions in parameters) as well as a
87
95
// version new_ty of its type where the anonymous region is replaced
88
96
// with the named one.
89
- let ( named, ( arg, new_ty, br) , scope_def_id) =
90
- if self . is_named_region ( sub) && self . is_suitable_anonymous_region ( sup) . is_some ( ) {
91
- ( sub,
92
- self . find_arg_with_anonymous_region ( sup, sub) . unwrap ( ) ,
93
- self . is_suitable_anonymous_region ( sup) . unwrap ( ) )
94
- } else if self . is_named_region ( sup ) &&
95
- self . is_suitable_anonymous_region ( sub) . is_some ( ) {
96
- ( sup,
97
- self . find_arg_with_anonymous_region ( sub, sup) . unwrap ( ) ,
98
- self . is_suitable_anonymous_region ( sub) . unwrap ( ) )
99
- } else {
100
- return false ; // inapplicable
101
- } ;
97
+ let ( named, ( arg, new_ty, br, is_first ) , scope_def_id) = if
98
+ self . is_named_region ( sub) && self . is_suitable_anonymous_region ( sup) . is_some ( ) {
99
+ ( sub,
100
+ self . find_arg_with_anonymous_region ( sup, sub) . unwrap ( ) ,
101
+ self . is_suitable_anonymous_region ( sup) . unwrap ( ) )
102
+ } else if
103
+ self . is_named_region ( sup ) && self . is_suitable_anonymous_region ( sub) . is_some ( ) {
104
+ ( sup,
105
+ self . find_arg_with_anonymous_region ( sub, sup) . unwrap ( ) ,
106
+ self . is_suitable_anonymous_region ( sub) . unwrap ( ) )
107
+ } else {
108
+ return false ; // inapplicable
109
+ } ;
102
110
103
111
// Here, we check for the case where the anonymous region
104
112
// is in the return type.
@@ -116,6 +124,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
116
124
_ => { }
117
125
}
118
126
127
+ // Here we check for the case where anonymous region
128
+ // corresponds to self and if yes, we display E0312.
129
+ // FIXME(#42700) - Need to format self properly to
130
+ // enable E0611 for it.
131
+ if is_first &&
132
+ self . tcx
133
+ . opt_associated_item ( scope_def_id)
134
+ . map ( |i| i. method_has_self_argument )
135
+ . unwrap_or ( false ) {
136
+ return false ;
137
+ }
138
+
119
139
if let Some ( simple_name) = arg. pat . simple_name ( ) {
120
140
struct_span_err ! ( self . tcx. sess,
121
141
span,
0 commit comments