@@ -12,6 +12,7 @@ use borrow_check::nll::region_infer::RegionInferenceContext;
12
12
use borrow_check:: nll:: ToRegionVid ;
13
13
use rustc:: hir;
14
14
use rustc:: hir:: def_id:: DefId ;
15
+ use rustc:: infer:: InferCtxt ;
15
16
use rustc:: mir:: Mir ;
16
17
use rustc:: ty:: subst:: { Substs , UnpackedKind } ;
17
18
use rustc:: ty:: { self , RegionVid , Ty , TyCtxt } ;
@@ -48,7 +49,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
48
49
/// and then return the name `'1` for us to use.
49
50
crate fn give_region_a_name (
50
51
& self ,
51
- tcx : TyCtxt < ' _ , ' _ , ' tcx > ,
52
+ infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
52
53
mir : & Mir < ' tcx > ,
53
54
mir_def_id : DefId ,
54
55
fr : RegionVid ,
@@ -59,17 +60,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
59
60
60
61
assert ! ( self . universal_regions. is_universal_region( fr) ) ;
61
62
62
- self . give_name_from_error_region ( tcx, mir_def_id, fr, counter, diag)
63
+ self . give_name_from_error_region ( infcx . tcx , mir_def_id, fr, counter, diag)
63
64
. or_else ( || {
64
65
self . give_name_if_anonymous_region_appears_in_arguments (
65
- tcx , mir, mir_def_id, fr, counter, diag)
66
+ infcx , mir, mir_def_id, fr, counter, diag)
66
67
} )
67
68
. or_else ( || {
68
69
self . give_name_if_anonymous_region_appears_in_upvars (
69
- tcx, mir, fr, counter, diag)
70
+ infcx . tcx , mir, fr, counter, diag)
70
71
} )
71
72
. or_else ( || {
72
- self . give_name_if_anonymous_region_appears_in_output ( tcx, mir, fr, counter, diag)
73
+ self . give_name_if_anonymous_region_appears_in_output (
74
+ infcx. tcx , mir, fr, counter, diag)
73
75
} )
74
76
. unwrap_or_else ( || span_bug ! ( mir. span, "can't make a name for free region {:?}" , fr) )
75
77
}
@@ -130,20 +132,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
130
132
/// ```
131
133
fn give_name_if_anonymous_region_appears_in_arguments (
132
134
& self ,
133
- tcx : TyCtxt < ' _ , ' _ , ' tcx > ,
135
+ infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
134
136
mir : & Mir < ' tcx > ,
135
137
mir_def_id : DefId ,
136
138
fr : RegionVid ,
137
139
counter : & mut usize ,
138
140
diag : & mut DiagnosticBuilder < ' _ > ,
139
141
) -> Option < InternedString > {
140
142
let implicit_inputs = self . universal_regions . defining_ty . implicit_inputs ( ) ;
141
- let argument_index = self . get_argument_index_for_region ( tcx, fr) ?;
143
+ let argument_index = self . get_argument_index_for_region ( infcx . tcx , fr) ?;
142
144
143
145
let arg_ty =
144
146
self . universal_regions . unnormalized_input_tys [ implicit_inputs + argument_index] ;
145
147
if let Some ( region_name) = self . give_name_if_we_can_match_hir_ty_from_argument (
146
- tcx ,
148
+ infcx ,
147
149
mir_def_id,
148
150
fr,
149
151
arg_ty,
@@ -169,25 +171,31 @@ impl<'tcx> RegionInferenceContext<'tcx> {
169
171
170
172
fn give_name_if_we_can_match_hir_ty_from_argument (
171
173
& self ,
172
- tcx : TyCtxt < ' _ , ' _ , ' tcx > ,
174
+ infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
173
175
mir_def_id : DefId ,
174
176
needle_fr : RegionVid ,
175
177
argument_ty : Ty < ' tcx > ,
176
178
argument_index : usize ,
177
179
counter : & mut usize ,
178
180
diag : & mut DiagnosticBuilder < ' _ > ,
179
181
) -> Option < InternedString > {
180
- let mir_node_id = tcx. hir . as_local_node_id ( mir_def_id) ?;
181
- let fn_decl = tcx. hir . fn_decl ( mir_node_id) ?;
182
+ let mir_node_id = infcx . tcx . hir . as_local_node_id ( mir_def_id) ?;
183
+ let fn_decl = infcx . tcx . hir . fn_decl ( mir_node_id) ?;
182
184
let argument_hir_ty: & hir:: Ty = & fn_decl. inputs [ argument_index] ;
183
185
match argument_hir_ty. node {
184
186
// This indicates a variable with no type annotation, like
185
187
// `|x|`... in that case, we can't highlight the type but
186
188
// must highlight the variable.
187
- hir:: TyKind :: Infer => None ,
189
+ hir:: TyKind :: Infer => self . give_name_if_we_cannot_match_hir_ty (
190
+ infcx,
191
+ argument_ty,
192
+ argument_hir_ty,
193
+ counter,
194
+ diag,
195
+ ) ,
188
196
189
197
_ => self . give_name_if_we_can_match_hir_ty (
190
- tcx,
198
+ infcx . tcx ,
191
199
needle_fr,
192
200
argument_ty,
193
201
argument_hir_ty,
@@ -197,6 +205,40 @@ impl<'tcx> RegionInferenceContext<'tcx> {
197
205
}
198
206
}
199
207
208
+ /// Attempts to highlight the specific part of a type in an argument
209
+ /// that has no type annotation.
210
+ /// For example, we might produce an annotation like this:
211
+ ///
212
+ /// ```
213
+ /// | foo(|a, b| b)
214
+ /// | - -
215
+ /// | | |
216
+ /// | | has type `&'1 u32`
217
+ /// | has type `&'2 u32`
218
+ /// ```
219
+ fn give_name_if_we_cannot_match_hir_ty (
220
+ & self ,
221
+ infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
222
+ argument_ty : Ty < ' tcx > ,
223
+ argument_hir_ty : & hir:: Ty ,
224
+ counter : & mut usize ,
225
+ diag : & mut DiagnosticBuilder < ' _ > ,
226
+ ) -> Option < InternedString > {
227
+ let mut type_name = infcx. extract_type_name ( & argument_ty) ;
228
+
229
+ type_name. find ( "&" ) . map ( |index| {
230
+ let region_name = self . synthesize_region_name ( counter) . as_str ( ) ;
231
+ type_name. insert_str ( index + 1 , & format ! ( "{} " , region_name) ) ;
232
+
233
+ diag. span_label (
234
+ argument_hir_ty. span ,
235
+ format ! ( "has type `{}`" , type_name) ,
236
+ ) ;
237
+
238
+ region_name. as_interned_str ( )
239
+ } )
240
+ }
241
+
200
242
/// Attempts to highlight the specific part of a type annotation
201
243
/// that contains the anonymous reference we want to give a name
202
244
/// to. For example, we might produce an annotation like this:
0 commit comments