@@ -109,7 +109,7 @@ use self::VarKind::*;
109
109
use hir:: def:: * ;
110
110
use ty:: { self , TyCtxt } ;
111
111
use lint;
112
- use util:: nodemap:: NodeMap ;
112
+ use util:: nodemap:: { NodeMap , NodeSet } ;
113
113
114
114
use std:: { fmt, usize} ;
115
115
use std:: io:: prelude:: * ;
@@ -244,7 +244,8 @@ struct CaptureInfo {
244
244
#[ derive( Copy , Clone , Debug ) ]
245
245
struct LocalInfo {
246
246
id : NodeId ,
247
- name : ast:: Name
247
+ name : ast:: Name ,
248
+ is_shorthand : bool ,
248
249
}
249
250
250
251
#[ derive( Copy , Clone , Debug ) ]
@@ -333,6 +334,13 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
333
334
}
334
335
}
335
336
337
+ fn variable_is_shorthand ( & self , var : Variable ) -> bool {
338
+ match self . var_kinds [ var. get ( ) ] {
339
+ Local ( LocalInfo { is_shorthand, .. } ) => is_shorthand,
340
+ Arg ( ..) | CleanExit => false
341
+ }
342
+ }
343
+
336
344
fn set_captures ( & mut self , node_id : NodeId , cs : Vec < CaptureInfo > ) {
337
345
self . capture_info_map . insert ( node_id, Rc :: new ( cs) ) ;
338
346
}
@@ -384,23 +392,41 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
384
392
let name = path1. node ;
385
393
ir. add_live_node_for_node ( p_id, VarDefNode ( sp) ) ;
386
394
ir. add_variable ( Local ( LocalInfo {
387
- id : p_id,
388
- name,
395
+ id : p_id,
396
+ name,
397
+ is_shorthand : false ,
389
398
} ) ) ;
390
399
} ) ;
391
400
intravisit:: walk_local ( ir, local) ;
392
401
}
393
402
394
403
fn visit_arm < ' a , ' tcx > ( ir : & mut IrMaps < ' a , ' tcx > , arm : & ' tcx hir:: Arm ) {
395
404
for pat in & arm. pats {
405
+ // for struct patterns, take note of which fields used shorthand (`x`
406
+ // rather than `x: x`)
407
+ //
408
+ // FIXME: according to the rust-lang-nursery/rustc-guide book and
409
+ // librustc/README.md, `NodeId`s are to be phased out in favor of
410
+ // `HirId`s; however, we need to match the signature of `each_binding`,
411
+ // which uses `NodeIds`.
412
+ let mut shorthand_field_ids = NodeSet ( ) ;
413
+ if let hir:: PatKind :: Struct ( _, ref fields, _) = pat. node {
414
+ for field in fields {
415
+ if field. node . is_shorthand {
416
+ shorthand_field_ids. insert ( field. node . pat . id ) ;
417
+ }
418
+ }
419
+ }
420
+
396
421
pat. each_binding ( |bm, p_id, sp, path1| {
397
422
debug ! ( "adding local variable {} from match with bm {:?}" ,
398
423
p_id, bm) ;
399
424
let name = path1. node ;
400
425
ir. add_live_node_for_node ( p_id, VarDefNode ( sp) ) ;
401
426
ir. add_variable ( Local ( LocalInfo {
402
427
id : p_id,
403
- name,
428
+ name : name,
429
+ is_shorthand : shorthand_field_ids. contains ( & p_id)
404
430
} ) ) ;
405
431
} )
406
432
}
@@ -1483,17 +1509,26 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
1483
1509
self . assigned_on_exit ( ln, var) . is_some ( )
1484
1510
} ;
1485
1511
1512
+ let suggest_underscore_msg = format ! ( "consider using `_{}` instead" ,
1513
+ name) ;
1486
1514
if is_assigned {
1487
- self . ir . tcx . lint_node_note ( lint :: builtin :: UNUSED_VARIABLES , id , sp ,
1488
- & format ! ( "variable `{}` is assigned to, but never used" ,
1489
- name ) ,
1490
- & format ! ( "to avoid this warning, consider using `_{}` instead" ,
1491
- name ) ) ;
1515
+ self . ir . tcx
1516
+ . lint_node_note ( lint :: builtin :: UNUSED_VARIABLES , id , sp ,
1517
+ & format ! ( "variable `{}` is assigned to, but never used" ,
1518
+ name ) ,
1519
+ & suggest_underscore_msg ) ;
1492
1520
} else if name != "self" {
1493
- self . ir . tcx . lint_node_note ( lint:: builtin:: UNUSED_VARIABLES , id, sp,
1494
- & format ! ( "unused variable: `{}`" , name) ,
1495
- & format ! ( "to avoid this warning, consider using `_{}` instead" ,
1496
- name) ) ;
1521
+ let msg = format ! ( "unused variable: `{}`" , name) ;
1522
+ let mut err = self . ir . tcx
1523
+ . struct_span_lint_node ( lint:: builtin:: UNUSED_VARIABLES , id, sp, & msg) ;
1524
+ if self . ir . variable_is_shorthand ( var) {
1525
+ err. span_suggestion ( sp, "try ignoring the field" ,
1526
+ format ! ( "{}: _" , name) ) ;
1527
+ } else {
1528
+ err. span_suggestion_short ( sp, & suggest_underscore_msg,
1529
+ format ! ( "_{}" , name) ) ;
1530
+ }
1531
+ err. emit ( )
1497
1532
}
1498
1533
}
1499
1534
true
0 commit comments