@@ -109,7 +109,7 @@ use self::VarKind::*;
109109use hir:: def:: * ;
110110use ty:: { self , TyCtxt } ;
111111use lint;
112- use util:: nodemap:: NodeMap ;
112+ use util:: nodemap:: { NodeMap , NodeSet } ;
113113
114114use std:: { fmt, usize} ;
115115use std:: io:: prelude:: * ;
@@ -244,7 +244,8 @@ struct CaptureInfo {
244244#[ derive( Copy , Clone , Debug ) ]
245245struct LocalInfo {
246246 id : NodeId ,
247- name : ast:: Name
247+ name : ast:: Name ,
248+ is_shorthand : bool ,
248249}
249250
250251#[ derive( Copy , Clone , Debug ) ]
@@ -333,6 +334,13 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
333334 }
334335 }
335336
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+
336344 fn set_captures ( & mut self , node_id : NodeId , cs : Vec < CaptureInfo > ) {
337345 self . capture_info_map . insert ( node_id, Rc :: new ( cs) ) ;
338346 }
@@ -384,23 +392,41 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
384392 let name = path1. node ;
385393 ir. add_live_node_for_node ( p_id, VarDefNode ( sp) ) ;
386394 ir. add_variable ( Local ( LocalInfo {
387- id : p_id,
388- name,
395+ id : p_id,
396+ name,
397+ is_shorthand : false ,
389398 } ) ) ;
390399 } ) ;
391400 intravisit:: walk_local ( ir, local) ;
392401}
393402
394403fn visit_arm < ' a , ' tcx > ( ir : & mut IrMaps < ' a , ' tcx > , arm : & ' tcx hir:: Arm ) {
395404 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+
396421 pat. each_binding ( |bm, p_id, sp, path1| {
397422 debug ! ( "adding local variable {} from match with bm {:?}" ,
398423 p_id, bm) ;
399424 let name = path1. node ;
400425 ir. add_live_node_for_node ( p_id, VarDefNode ( sp) ) ;
401426 ir. add_variable ( Local ( LocalInfo {
402427 id : p_id,
403- name,
428+ name : name,
429+ is_shorthand : shorthand_field_ids. contains ( & p_id)
404430 } ) ) ;
405431 } )
406432 }
@@ -1483,17 +1509,26 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
14831509 self . assigned_on_exit ( ln, var) . is_some ( )
14841510 } ;
14851511
1512+ let suggest_underscore_msg = format ! ( "consider using `_{}` instead" ,
1513+ name) ;
14861514 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 ) ;
14921520 } 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 ( )
14971532 }
14981533 }
14991534 true
0 commit comments