@@ -117,6 +117,7 @@ use std::io::prelude::*;
117
117
use std:: io;
118
118
use std:: rc:: Rc ;
119
119
use syntax:: ast:: { self , NodeId } ;
120
+ use syntax:: ptr:: P ;
120
121
use syntax:: symbol:: keywords;
121
122
use syntax_pos:: Span ;
122
123
@@ -398,72 +399,65 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
398
399
lsets. warn_about_unused_args ( body, entry_ln) ;
399
400
}
400
401
401
- fn visit_local < ' a , ' tcx > ( ir : & mut IrMaps < ' a , ' tcx > , local : & ' tcx hir:: Local ) {
402
- local. pat . each_binding ( |_, p_id, sp, path1| {
403
- debug ! ( "adding local variable {}" , p_id) ;
402
+ fn add_from_pat < ' a , ' tcx > ( ir : & mut IrMaps < ' a , ' tcx > , pat : & P < hir:: Pat > ) {
403
+ // For struct patterns, take note of which fields used shorthand
404
+ // (`x` rather than `x: x`).
405
+ //
406
+ // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
407
+ // phased out in favor of `HirId`s; however, we need to match the signature of
408
+ // `each_binding`, which uses `NodeIds`.
409
+ let mut shorthand_field_ids = NodeSet ( ) ;
410
+ let mut pats = VecDeque :: new ( ) ;
411
+ pats. push_back ( pat) ;
412
+ while let Some ( pat) = pats. pop_front ( ) {
413
+ use hir:: PatKind :: * ;
414
+ match pat. node {
415
+ Binding ( _, _, _, ref inner_pat) => {
416
+ pats. extend ( inner_pat. iter ( ) ) ;
417
+ }
418
+ Struct ( _, ref fields, _) => {
419
+ for field in fields {
420
+ if field. node . is_shorthand {
421
+ shorthand_field_ids. insert ( field. node . pat . id ) ;
422
+ }
423
+ }
424
+ }
425
+ Ref ( ref inner_pat, _) |
426
+ Box ( ref inner_pat) => {
427
+ pats. push_back ( inner_pat) ;
428
+ }
429
+ TupleStruct ( _, ref inner_pats, _) |
430
+ Tuple ( ref inner_pats, _) => {
431
+ pats. extend ( inner_pats. iter ( ) ) ;
432
+ }
433
+ Slice ( ref pre_pats, ref inner_pat, ref post_pats) => {
434
+ pats. extend ( pre_pats. iter ( ) ) ;
435
+ pats. extend ( inner_pat. iter ( ) ) ;
436
+ pats. extend ( post_pats. iter ( ) ) ;
437
+ }
438
+ _ => { }
439
+ }
440
+ }
441
+
442
+ pat. each_binding ( |_bm, p_id, _sp, path1| {
404
443
let name = path1. node ;
405
- ir. add_live_node_for_node ( p_id, VarDefNode ( sp ) ) ;
444
+ ir. add_live_node_for_node ( p_id, VarDefNode ( path1 . span ) ) ;
406
445
ir. add_variable ( Local ( LocalInfo {
407
446
id : p_id,
408
447
name,
409
- is_shorthand : false ,
448
+ is_shorthand : shorthand_field_ids . contains ( & p_id )
410
449
} ) ) ;
411
450
} ) ;
451
+ }
452
+
453
+ fn visit_local < ' a , ' tcx > ( ir : & mut IrMaps < ' a , ' tcx > , local : & ' tcx hir:: Local ) {
454
+ add_from_pat ( ir, & local. pat ) ;
412
455
intravisit:: walk_local ( ir, local) ;
413
456
}
414
457
415
458
fn visit_arm < ' a , ' tcx > ( ir : & mut IrMaps < ' a , ' tcx > , arm : & ' tcx hir:: Arm ) {
416
- for mut pat in & arm. pats {
417
- // For struct patterns, take note of which fields used shorthand
418
- // (`x` rather than `x: x`).
419
- //
420
- // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
421
- // phased out in favor of `HirId`s; however, we need to match the signature of
422
- // `each_binding`, which uses `NodeIds`.
423
- let mut shorthand_field_ids = NodeSet ( ) ;
424
- let mut pats = VecDeque :: new ( ) ;
425
- pats. push_back ( pat) ;
426
- while let Some ( pat) = pats. pop_front ( ) {
427
- use hir:: PatKind :: * ;
428
- match pat. node {
429
- Binding ( _, _, _, ref inner_pat) => {
430
- pats. extend ( inner_pat. iter ( ) ) ;
431
- }
432
- Struct ( _, ref fields, _) => {
433
- for field in fields {
434
- if field. node . is_shorthand {
435
- shorthand_field_ids. insert ( field. node . pat . id ) ;
436
- }
437
- }
438
- }
439
- Ref ( ref inner_pat, _) |
440
- Box ( ref inner_pat) => {
441
- pats. push_back ( inner_pat) ;
442
- }
443
- TupleStruct ( _, ref inner_pats, _) |
444
- Tuple ( ref inner_pats, _) => {
445
- pats. extend ( inner_pats. iter ( ) ) ;
446
- }
447
- Slice ( ref pre_pats, ref inner_pat, ref post_pats) => {
448
- pats. extend ( pre_pats. iter ( ) ) ;
449
- pats. extend ( inner_pat. iter ( ) ) ;
450
- pats. extend ( post_pats. iter ( ) ) ;
451
- }
452
- _ => { }
453
- }
454
- }
455
-
456
- pat. each_binding ( |bm, p_id, _sp, path1| {
457
- debug ! ( "adding local variable {} from match with bm {:?}" ,
458
- p_id, bm) ;
459
- let name = path1. node ;
460
- ir. add_live_node_for_node ( p_id, VarDefNode ( path1. span ) ) ;
461
- ir. add_variable ( Local ( LocalInfo {
462
- id : p_id,
463
- name : name,
464
- is_shorthand : shorthand_field_ids. contains ( & p_id)
465
- } ) ) ;
466
- } )
459
+ for pat in & arm. pats {
460
+ add_from_pat ( ir, pat) ;
467
461
}
468
462
intravisit:: walk_arm ( ir, arm) ;
469
463
}
0 commit comments