@@ -15,6 +15,7 @@ use ty::{self, Region};
15
15
use infer:: region_inference:: RegionResolutionError :: * ;
16
16
use infer:: region_inference:: RegionResolutionError ;
17
17
use hir:: map as hir_map;
18
+ use hir:: def_id:: DefId ;
18
19
19
20
impl < ' a , ' gcx , ' tcx > InferCtxt < ' a , ' gcx , ' tcx > {
20
21
// This method walks the Type of the function body arguments using
@@ -24,13 +25,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
24
25
// Currently only the case where the function declaration consists of
25
26
// one named region and one anonymous region is handled.
26
27
// Consider the example `fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32`
27
- // Here, we would return the hir::Arg for y, and we return the type &'a
28
+ // Here, we would return the hir::Arg for y, we return the type &'a
28
29
// i32, which is the type of y but with the anonymous region replaced
29
- // with 'a.
30
+ // with 'a and also the corresponding bound region .
30
31
fn find_arg_with_anonymous_region ( & self ,
31
32
anon_region : Region < ' tcx > ,
32
33
named_region : Region < ' tcx > )
33
- -> Option < ( & hir:: Arg , ty:: Ty < ' tcx > ) > {
34
+ -> Option < ( & hir:: Arg , ty:: Ty < ' tcx > , ty :: BoundRegion ) > {
34
35
35
36
match * anon_region {
36
37
ty:: ReFree ( ref free_region) => {
@@ -55,7 +56,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
55
56
r
56
57
} ) ;
57
58
if found_anon_region {
58
- return Some ( ( arg, new_arg_ty) ) ;
59
+ return Some ( ( arg, new_arg_ty, free_region . bound_region ) ) ;
59
60
} else {
60
61
None
61
62
}
@@ -85,15 +86,36 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
85
86
// only introduced anonymous regions in parameters) as well as a
86
87
// version new_ty of its type where the anonymous region is replaced
87
88
// with the named one.
88
- let ( named, ( arg, new_ty) ) =
89
- if self . is_named_region ( sub) && self . is_suitable_anonymous_region ( sup) {
90
- ( sub, self . find_arg_with_anonymous_region ( sup, sub) . unwrap ( ) )
91
- } else if self . is_named_region ( sup) && self . is_suitable_anonymous_region ( sub) {
92
- ( sup, self . find_arg_with_anonymous_region ( sub, sup) . unwrap ( ) )
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 ( ) )
93
99
} else {
94
100
return false ; // inapplicable
95
101
} ;
96
102
103
+ // Here, we check for the case where the anonymous region
104
+ // is in the return type.
105
+ // FIXME(#42703) - Need to handle certain cases here.
106
+ let ret_ty = self . tcx . type_of ( scope_def_id) ;
107
+ match ret_ty. sty {
108
+ ty:: TyFnDef ( _, _, sig) => {
109
+ let late_bound_regions = self . tcx
110
+ . collect_referenced_late_bound_regions ( & sig. output ( ) ) ;
111
+ if late_bound_regions. iter ( ) . any ( |r| * r == br) {
112
+ return false ;
113
+ } else {
114
+ }
115
+ }
116
+ _ => { }
117
+ }
118
+
97
119
if let Some ( simple_name) = arg. pat . simple_name ( ) {
98
120
struct_span_err ! ( self . tcx. sess,
99
121
span,
@@ -122,7 +144,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
122
144
}
123
145
124
146
// This method returns whether the given Region is Anonymous
125
- pub fn is_suitable_anonymous_region ( & self , region : Region < ' tcx > ) -> bool {
147
+ // and returns the DefId corresponding to the region.
148
+ pub fn is_suitable_anonymous_region ( & self , region : Region < ' tcx > ) -> Option < DefId > {
126
149
127
150
match * region {
128
151
ty:: ReFree ( ref free_region) => {
@@ -147,20 +170,20 @@ associated_item(anonymous_region_binding_scope).container.id()).is_some() {
147
170
// since the signature must match the trait.
148
171
//
149
172
// FIXME(#42706) -- in some cases, we could do better here.
150
- return false ; // None;
173
+ return None ;
151
174
}
152
175
else { }
153
176
154
177
}
155
- _ => return false , // inapplicable
178
+ _ => return None , // inapplicable
156
179
// we target only top-level functions
157
180
}
158
- return true ;
181
+ return Some ( anonymous_region_binding_scope ) ;
159
182
}
160
- _ => false ,
183
+ _ => None ,
161
184
}
162
185
}
163
- _ => false ,
186
+ _ => None ,
164
187
}
165
188
}
166
189
}
0 commit comments