@@ -4,7 +4,7 @@ use itertools::Itertools;
44use rustc_const_eval:: util:: { call_kind, CallDesugaringKind } ;
55use rustc_errors:: { Applicability , Diagnostic } ;
66use rustc_hir as hir;
7- use rustc_hir:: def:: Namespace ;
7+ use rustc_hir:: def:: { CtorKind , Namespace } ;
88use rustc_hir:: GeneratorKind ;
99use rustc_infer:: infer:: TyCtxtInferExt ;
1010use rustc_middle:: mir:: tcx:: PlaceTy ;
@@ -16,7 +16,7 @@ use rustc_middle::ty::print::Print;
1616use rustc_middle:: ty:: { self , DefIdTree , Instance , Ty , TyCtxt } ;
1717use rustc_mir_dataflow:: move_paths:: { InitLocation , LookupResult } ;
1818use rustc_span:: def_id:: LocalDefId ;
19- use rustc_span:: { symbol:: sym, Span , DUMMY_SP } ;
19+ use rustc_span:: { symbol:: sym, Span , Symbol , DUMMY_SP } ;
2020use rustc_target:: abi:: VariantIdx ;
2121use rustc_trait_selection:: traits:: type_known_to_meet_bound_modulo_regions;
2222
@@ -43,7 +43,15 @@ pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionError
4343pub ( crate ) use region_name:: { RegionName , RegionNameSource } ;
4444pub ( crate ) use rustc_const_eval:: util:: CallKind ;
4545
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 ) ;
4755
4856impl < ' cx , ' tcx > MirBorrowckCtxt < ' cx , ' tcx > {
4957 /// 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> {
164172 /// End-user visible description of `place` if one can be found.
165173 /// If the place is a temporary for instance, `None` will be returned.
166174 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+ )
168179 }
169180
170181 /// 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> {
174185 pub ( super ) fn describe_place_with_options (
175186 & self ,
176187 place : PlaceRef < ' tcx > ,
177- including_downcast : IncludingDowncast ,
188+ opt : DescribePlaceOpt ,
178189 ) -> Option < String > {
179190 let local = place. local ;
180191 let mut autoderef_index = None ;
@@ -224,7 +235,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
224235 }
225236 }
226237 }
227- ProjectionElem :: Downcast ( ..) if including_downcast . 0 => return None ,
238+ ProjectionElem :: Downcast ( ..) if opt . including_downcast => return None ,
228239 ProjectionElem :: Downcast ( ..) => ( ) ,
229240 ProjectionElem :: Field ( field, _ty) => {
230241 // FIXME(project-rfc_2229#36): print capture precisely here.
@@ -238,9 +249,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
238249 let field_name = self . describe_field (
239250 PlaceRef { local, projection : place. projection . split_at ( index) . 0 } ,
240251 * field,
252+ IncludingTupleField ( opt. including_tuple_field ) ,
241253 ) ;
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+ }
244258 }
245259 }
246260 ProjectionElem :: Index ( index) => {
@@ -261,6 +275,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
261275 ok. ok ( ) . map ( |_| buf)
262276 }
263277
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+
264290 /// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
265291 /// a name, or its name was generated by the compiler, then `Err` is returned
266292 fn append_local_to_string ( & self , local : Local , buf : & mut String ) -> Result < ( ) , ( ) > {
@@ -275,7 +301,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
275301 }
276302
277303 /// 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 > {
279310 let place_ty = match place {
280311 PlaceRef { local, projection : [ ] } => PlaceTy :: from_ty ( self . body . local_decls [ local] . ty ) ,
281312 PlaceRef { local, projection : [ proj_base @ .., elem] } => match elem {
@@ -289,7 +320,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
289320 ProjectionElem :: Field ( _, field_type) => PlaceTy :: from_ty ( * field_type) ,
290321 } ,
291322 } ;
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+ )
293329 }
294330
295331 /// End-user visible description of the `field_index`nth field of `ty`
@@ -298,10 +334,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
298334 ty : Ty < ' _ > ,
299335 field : Field ,
300336 variant_index : Option < VariantIdx > ,
301- ) -> String {
337+ including_tuple_field : IncludingTupleField ,
338+ ) -> Option < String > {
302339 if ty. is_box ( ) {
303340 // 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 )
305342 } else {
306343 match * ty. kind ( ) {
307344 ty:: Adt ( def, _) => {
@@ -311,14 +348,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
311348 } else {
312349 def. non_enum_variant ( )
313350 } ;
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 ( ) )
315355 }
316- ty:: Tuple ( _) => field. index ( ) . to_string ( ) ,
356+ ty:: Tuple ( _) => Some ( field. index ( ) . to_string ( ) ) ,
317357 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 )
319359 }
320360 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 )
322362 }
323363 ty:: Closure ( def_id, _) | ty:: Generator ( def_id, _, _) => {
324364 // We won't be borrowck'ing here if the closure came from another crate,
@@ -335,7 +375,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
335375 . unwrap ( )
336376 . get_root_variable ( ) ;
337377
338- self . infcx . tcx . hir ( ) . name ( var_id) . to_string ( )
378+ Some ( self . infcx . tcx . hir ( ) . name ( var_id) . to_string ( ) )
339379 }
340380 _ => {
341381 // Might need a revision when the fields in trait RFC is implemented
0 commit comments