@@ -270,6 +270,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
270
270
None
271
271
}
272
272
273
+ fn is_hir_id_from_struct_pattern_shorthand_field ( & self , hir_id : hir:: HirId , sp : Span ) -> bool {
274
+ let cm = self . sess ( ) . source_map ( ) ;
275
+ let parent_id = self . tcx . hir ( ) . get_parent_node_by_hir_id ( hir_id) ;
276
+ if let Some ( parent) = self . tcx . hir ( ) . find_by_hir_id ( parent_id) {
277
+ // Account for fields
278
+ if let Node :: Expr ( hir:: Expr {
279
+ node : hir:: ExprKind :: Struct ( _, fields, ..) , ..
280
+ } ) = parent {
281
+ if let Ok ( src) = cm. span_to_snippet ( sp) {
282
+ for field in fields {
283
+ if field. ident . as_str ( ) == src. as_str ( ) && field. is_shorthand {
284
+ return true ;
285
+ }
286
+ }
287
+ }
288
+ }
289
+ }
290
+ false
291
+ }
292
+
273
293
/// This function is used to determine potential "simple" improvements or users' errors and
274
294
/// provide them useful help. For example:
275
295
///
@@ -299,6 +319,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
299
319
return None ;
300
320
}
301
321
322
+ let is_struct_pat_shorthand_field = self . is_hir_id_from_struct_pattern_shorthand_field (
323
+ expr. hir_id ,
324
+ sp,
325
+ ) ;
326
+
302
327
match ( & expected. sty , & checked_ty. sty ) {
303
328
( & ty:: Ref ( _, exp, _) , & ty:: Ref ( _, check, _) ) => match ( & exp. sty , & check. sty ) {
304
329
( & ty:: Str , & ty:: Array ( arr, _) ) |
@@ -337,12 +362,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
337
362
// bar(&x); // error, expected &mut
338
363
// ```
339
364
let ref_ty = match mutability {
340
- hir:: Mutability :: MutMutable => self . tcx . mk_mut_ref (
341
- self . tcx . mk_region ( ty:: ReStatic ) ,
342
- checked_ty ) ,
343
- hir:: Mutability :: MutImmutable => self . tcx . mk_imm_ref (
344
- self . tcx . mk_region ( ty:: ReStatic ) ,
345
- checked_ty ) ,
365
+ hir:: Mutability :: MutMutable => {
366
+ self . tcx . mk_mut_ref ( self . tcx . mk_region ( ty:: ReStatic ) , checked_ty )
367
+ }
368
+ hir:: Mutability :: MutImmutable => {
369
+ self . tcx . mk_imm_ref ( self . tcx . mk_region ( ty:: ReStatic ) , checked_ty )
370
+ }
346
371
} ;
347
372
if self . can_coerce ( ref_ty, expected) {
348
373
if let Ok ( src) = cm. span_to_snippet ( sp) {
@@ -363,14 +388,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
363
388
if let Some ( sugg) = self . can_use_as_ref ( expr) {
364
389
return Some ( sugg) ;
365
390
}
391
+ let field_name = if is_struct_pat_shorthand_field {
392
+ format ! ( "{}: " , sugg_expr)
393
+ } else {
394
+ String :: new ( )
395
+ } ;
366
396
return Some ( match mutability {
367
- hir:: Mutability :: MutMutable => {
368
- ( sp, "consider mutably borrowing here" , format ! ( "&mut {}" ,
369
- sugg_expr) )
370
- }
371
- hir:: Mutability :: MutImmutable => {
372
- ( sp, "consider borrowing here" , format ! ( "&{}" , sugg_expr) )
373
- }
397
+ hir:: Mutability :: MutMutable => (
398
+ sp,
399
+ "consider mutably borrowing here" ,
400
+ format ! ( "{}&mut {}" , field_name, sugg_expr) ,
401
+ ) ,
402
+ hir:: Mutability :: MutImmutable => (
403
+ sp,
404
+ "consider borrowing here" ,
405
+ format ! ( "{}&{}" , field_name, sugg_expr) ,
406
+ ) ,
374
407
} ) ;
375
408
}
376
409
}
@@ -411,12 +444,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
411
444
checked,
412
445
sp) {
413
446
// do not suggest if the span comes from a macro (#52783)
414
- if let ( Ok ( code) ,
415
- true ) = ( cm. span_to_snippet ( sp) , sp == expr. span ) {
447
+ if let ( Ok ( code) , true ) = (
448
+ cm. span_to_snippet ( sp) ,
449
+ sp == expr. span ,
450
+ ) {
416
451
return Some ( (
417
452
sp,
418
453
"consider dereferencing the borrow" ,
419
- format ! ( "*{}" , code) ,
454
+ if is_struct_pat_shorthand_field {
455
+ format ! ( "{}: *{}" , code, code)
456
+ } else {
457
+ format ! ( "*{}" , code)
458
+ } ,
420
459
) ) ;
421
460
}
422
461
}
0 commit comments