@@ -4,7 +4,7 @@ use itertools::Itertools;
4
4
use rustc_const_eval:: util:: { call_kind, CallDesugaringKind } ;
5
5
use rustc_errors:: { Applicability , Diagnostic } ;
6
6
use rustc_hir as hir;
7
- use rustc_hir:: def:: Namespace ;
7
+ use rustc_hir:: def:: { CtorKind , Namespace } ;
8
8
use rustc_hir:: GeneratorKind ;
9
9
use rustc_infer:: infer:: TyCtxtInferExt ;
10
10
use rustc_middle:: mir:: tcx:: PlaceTy ;
@@ -16,7 +16,7 @@ use rustc_middle::ty::print::Print;
16
16
use rustc_middle:: ty:: { self , DefIdTree , Instance , Ty , TyCtxt } ;
17
17
use rustc_mir_dataflow:: move_paths:: { InitLocation , LookupResult } ;
18
18
use rustc_span:: def_id:: LocalDefId ;
19
- use rustc_span:: { symbol:: sym, Span , DUMMY_SP } ;
19
+ use rustc_span:: { symbol:: sym, Span , Symbol , DUMMY_SP } ;
20
20
use rustc_target:: abi:: VariantIdx ;
21
21
use rustc_trait_selection:: traits:: type_known_to_meet_bound_modulo_regions;
22
22
@@ -43,7 +43,15 @@ pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionError
43
43
pub ( crate ) use region_name:: { RegionName , RegionNameSource } ;
44
44
pub ( crate ) use rustc_const_eval:: util:: CallKind ;
45
45
46
- pub ( super ) struct IncludingDowncast ( pub ( super ) bool ) ;
46
+ pub ( super ) struct DescribePlaceOpt {
47
+ pub including_downcast : bool ,
48
+
49
+ /// Enable/Disable tuple fields.
50
+ /// For example `x` tuple. if it's `true` `x.0`. Otherwise `x`
51
+ pub including_tuple_field : bool ,
52
+ }
53
+
54
+ pub ( super ) struct IncludingTupleField ( pub ( super ) bool ) ;
47
55
48
56
impl < ' cx , ' tcx > MirBorrowckCtxt < ' cx , ' tcx > {
49
57
/// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
@@ -164,7 +172,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
164
172
/// End-user visible description of `place` if one can be found.
165
173
/// If the place is a temporary for instance, `None` will be returned.
166
174
pub ( super ) fn describe_place ( & self , place_ref : PlaceRef < ' tcx > ) -> Option < String > {
167
- self . describe_place_with_options ( place_ref, IncludingDowncast ( false ) )
175
+ self . describe_place_with_options (
176
+ place_ref,
177
+ DescribePlaceOpt { including_downcast : false , including_tuple_field : true } ,
178
+ )
168
179
}
169
180
170
181
/// End-user visible description of `place` if one can be found. If the place is a temporary
@@ -174,7 +185,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
174
185
pub ( super ) fn describe_place_with_options (
175
186
& self ,
176
187
place : PlaceRef < ' tcx > ,
177
- including_downcast : IncludingDowncast ,
188
+ opt : DescribePlaceOpt ,
178
189
) -> Option < String > {
179
190
let local = place. local ;
180
191
let mut autoderef_index = None ;
@@ -224,7 +235,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
224
235
}
225
236
}
226
237
}
227
- ProjectionElem :: Downcast ( ..) if including_downcast . 0 => return None ,
238
+ ProjectionElem :: Downcast ( ..) if opt . including_downcast => return None ,
228
239
ProjectionElem :: Downcast ( ..) => ( ) ,
229
240
ProjectionElem :: Field ( field, _ty) => {
230
241
// FIXME(project-rfc_2229#36): print capture precisely here.
@@ -238,9 +249,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
238
249
let field_name = self . describe_field (
239
250
PlaceRef { local, projection : place. projection . split_at ( index) . 0 } ,
240
251
* field,
252
+ IncludingTupleField ( opt. including_tuple_field ) ,
241
253
) ;
242
- buf. push ( '.' ) ;
243
- buf. push_str ( & field_name) ;
254
+ if let Some ( field_name_str) = field_name {
255
+ buf. push ( '.' ) ;
256
+ buf. push_str ( & field_name_str) ;
257
+ }
244
258
}
245
259
}
246
260
ProjectionElem :: Index ( index) => {
@@ -261,6 +275,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
261
275
ok. ok ( ) . map ( |_| buf)
262
276
}
263
277
278
+ fn describe_name ( & self , place : PlaceRef < ' tcx > ) -> Option < Symbol > {
279
+ for elem in place. projection . into_iter ( ) {
280
+ match elem {
281
+ ProjectionElem :: Downcast ( Some ( name) , _) => {
282
+ return Some ( * name) ;
283
+ }
284
+ _ => { }
285
+ }
286
+ }
287
+ None
288
+ }
289
+
264
290
/// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
265
291
/// a name, or its name was generated by the compiler, then `Err` is returned
266
292
fn append_local_to_string ( & self , local : Local , buf : & mut String ) -> Result < ( ) , ( ) > {
@@ -275,7 +301,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
275
301
}
276
302
277
303
/// End-user visible description of the `field`nth field of `base`
278
- fn describe_field ( & self , place : PlaceRef < ' tcx > , field : Field ) -> String {
304
+ fn describe_field (
305
+ & self ,
306
+ place : PlaceRef < ' tcx > ,
307
+ field : Field ,
308
+ including_tuple_field : IncludingTupleField ,
309
+ ) -> Option < String > {
279
310
let place_ty = match place {
280
311
PlaceRef { local, projection : [ ] } => PlaceTy :: from_ty ( self . body . local_decls [ local] . ty ) ,
281
312
PlaceRef { local, projection : [ proj_base @ .., elem] } => match elem {
@@ -289,7 +320,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
289
320
ProjectionElem :: Field ( _, field_type) => PlaceTy :: from_ty ( * field_type) ,
290
321
} ,
291
322
} ;
292
- self . describe_field_from_ty ( place_ty. ty , field, place_ty. variant_index )
323
+ self . describe_field_from_ty (
324
+ place_ty. ty ,
325
+ field,
326
+ place_ty. variant_index ,
327
+ including_tuple_field,
328
+ )
293
329
}
294
330
295
331
/// End-user visible description of the `field_index`nth field of `ty`
@@ -298,10 +334,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
298
334
ty : Ty < ' _ > ,
299
335
field : Field ,
300
336
variant_index : Option < VariantIdx > ,
301
- ) -> String {
337
+ including_tuple_field : IncludingTupleField ,
338
+ ) -> Option < String > {
302
339
if ty. is_box ( ) {
303
340
// If the type is a box, the field is described from the boxed type
304
- self . describe_field_from_ty ( ty. boxed_ty ( ) , field, variant_index)
341
+ self . describe_field_from_ty ( ty. boxed_ty ( ) , field, variant_index, including_tuple_field )
305
342
} else {
306
343
match * ty. kind ( ) {
307
344
ty:: Adt ( def, _) => {
@@ -311,14 +348,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
311
348
} else {
312
349
def. non_enum_variant ( )
313
350
} ;
314
- variant. fields [ field. index ( ) ] . name . to_string ( )
351
+ if !including_tuple_field. 0 && variant. ctor_kind == CtorKind :: Fn {
352
+ return None ;
353
+ }
354
+ Some ( variant. fields [ field. index ( ) ] . name . to_string ( ) )
315
355
}
316
- ty:: Tuple ( _) => field. index ( ) . to_string ( ) ,
356
+ ty:: Tuple ( _) => Some ( field. index ( ) . to_string ( ) ) ,
317
357
ty:: Ref ( _, ty, _) | ty:: RawPtr ( ty:: TypeAndMut { ty, .. } ) => {
318
- self . describe_field_from_ty ( ty, field, variant_index)
358
+ self . describe_field_from_ty ( ty, field, variant_index, including_tuple_field )
319
359
}
320
360
ty:: Array ( ty, _) | ty:: Slice ( ty) => {
321
- self . describe_field_from_ty ( ty, field, variant_index)
361
+ self . describe_field_from_ty ( ty, field, variant_index, including_tuple_field )
322
362
}
323
363
ty:: Closure ( def_id, _) | ty:: Generator ( def_id, _, _) => {
324
364
// We won't be borrowck'ing here if the closure came from another crate,
@@ -335,7 +375,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
335
375
. unwrap ( )
336
376
. get_root_variable ( ) ;
337
377
338
- self . infcx . tcx . hir ( ) . name ( var_id) . to_string ( )
378
+ Some ( self . infcx . tcx . hir ( ) . name ( var_id) . to_string ( ) )
339
379
}
340
380
_ => {
341
381
// Might need a revision when the fields in trait RFC is implemented
0 commit comments