@@ -422,6 +422,7 @@ fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
422
422
struct DeadVisitor < ' a , ' tcx : ' a > {
423
423
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
424
424
live_symbols : Box < FxHashSet < ast:: NodeId > > ,
425
+ need_check_next_union_field : bool ,
425
426
}
426
427
427
428
impl < ' a , ' tcx > DeadVisitor < ' a , ' tcx > {
@@ -537,6 +538,16 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
537
538
}
538
539
}
539
540
541
+ fn visit_variant_data ( & mut self ,
542
+ s : & ' tcx hir:: VariantData ,
543
+ _: ast:: Name ,
544
+ _: & ' tcx hir:: Generics ,
545
+ _parent_id : ast:: NodeId ,
546
+ _: syntax_pos:: Span ) {
547
+ self . need_check_next_union_field = true ;
548
+ intravisit:: walk_struct_def ( self , s)
549
+ }
550
+
540
551
fn visit_variant ( & mut self ,
541
552
variant : & ' tcx hir:: Variant ,
542
553
g : & ' tcx hir:: Generics ,
@@ -557,23 +568,24 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
557
568
}
558
569
559
570
fn visit_struct_field ( & mut self , field : & ' tcx hir:: StructField ) {
560
- if self . should_warn_about_field ( & field) {
561
- let did = self . tcx . hir . get_parent_did ( field. id ) ;
562
- if if let Some ( node_id) = self . tcx . hir . as_local_node_id ( did) {
563
- match self . tcx . hir . find ( node_id) {
564
- Some ( hir_map:: NodeItem ( item) ) => match item. node {
565
- Item_ :: ItemUnion ( _, _) => false ,
566
- _ => true ,
567
- } ,
568
- _ => true ,
569
- }
570
- } else {
571
- true
572
- } {
571
+ if self . need_check_next_union_field {
572
+ if self . should_warn_about_field ( & field) {
573
573
self . warn_dead_code ( field. id , field. span , field. name , "field" ) ;
574
+ } else {
575
+ let did = self . tcx . hir . get_parent_did ( field. id ) ;
576
+ if let Some ( node_id) = self . tcx . hir . as_local_node_id ( did) {
577
+ match self . tcx . hir . find ( node_id) {
578
+ Some ( hir_map:: NodeItem ( item) ) => match item. node {
579
+ // If this is an union's field, it means all previous fields
580
+ // have been used as well so no need to check further.
581
+ Item_ :: ItemUnion ( _, _) => self . need_check_next_union_field = false ,
582
+ _ => { }
583
+ } ,
584
+ _ => { }
585
+ }
586
+ }
574
587
}
575
588
}
576
-
577
589
intravisit:: walk_struct_field ( self , field) ;
578
590
}
579
591
@@ -615,6 +627,10 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
615
627
let access_levels = & tcx. privacy_access_levels ( LOCAL_CRATE ) ;
616
628
let krate = tcx. hir . krate ( ) ;
617
629
let live_symbols = find_live ( tcx, access_levels, krate) ;
618
- let mut visitor = DeadVisitor { tcx : tcx, live_symbols : live_symbols } ;
630
+ let mut visitor = DeadVisitor {
631
+ tcx : tcx,
632
+ live_symbols : live_symbols,
633
+ need_check_next_union_field : true ,
634
+ } ;
619
635
intravisit:: walk_crate ( & mut visitor, krate) ;
620
636
}
0 commit comments