@@ -189,6 +189,24 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
189189 self . struct_has_extern_repr = had_extern_repr;
190190 self . inherited_pub_visibility = had_inherited_pub_visibility;
191191 }
192+
193+ fn mark_as_used_if_union ( & mut self , did : DefId ) {
194+ if let Some ( node_id) = self . tcx . hir . as_local_node_id ( did) {
195+ match self . tcx . hir . find ( node_id) {
196+ Some ( hir_map:: NodeItem ( item) ) => match item. node {
197+ Item_ :: ItemUnion ( ref variant, _) => {
198+ if variant. fields ( ) . len ( ) > 1 {
199+ for field in variant. fields ( ) {
200+ self . live_symbols . insert ( field. id ) ;
201+ }
202+ }
203+ }
204+ _ => { }
205+ } ,
206+ _ => { }
207+ }
208+ }
209+ }
192210}
193211
194212impl < ' a , ' tcx > Visitor < ' tcx > for MarkSymbolVisitor < ' a , ' tcx > {
@@ -221,6 +239,11 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
221239 hir:: ExprPath ( ref qpath @ hir:: QPath :: TypeRelative ( ..) ) => {
222240 let def = self . tables . qpath_def ( qpath, expr. id ) ;
223241 self . handle_definition ( def) ;
242+ self . mark_as_used_if_union ( def. def_id ( ) ) ;
243+ }
244+ hir:: ExprPath ( ref qpath @ hir:: QPath :: Resolved ( ..) ) => {
245+ let def = self . tables . qpath_def ( qpath, expr. id ) ;
246+ self . mark_as_used_if_union ( def. def_id ( ) ) ;
224247 }
225248 hir:: ExprMethodCall ( ..) => {
226249 self . lookup_and_handle_method ( expr. id ) ;
@@ -422,7 +445,6 @@ fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
422445struct DeadVisitor < ' a , ' tcx : ' a > {
423446 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
424447 live_symbols : Box < FxHashSet < ast:: NodeId > > ,
425- need_check_next_union_field : bool ,
426448}
427449
428450impl < ' a , ' tcx > DeadVisitor < ' a , ' tcx > {
@@ -538,16 +560,6 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
538560 }
539561 }
540562
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-
551563 fn visit_variant ( & mut self ,
552564 variant : & ' tcx hir:: Variant ,
553565 g : & ' tcx hir:: Generics ,
@@ -568,23 +580,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
568580 }
569581
570582 fn visit_struct_field ( & mut self , field : & ' tcx hir:: StructField ) {
571- if self . need_check_next_union_field {
572- if self . should_warn_about_field ( & field) {
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- }
587- }
583+ if self . should_warn_about_field ( & field) {
584+ self . warn_dead_code ( field. id , field. span ,
585+ field. name , "field" ) ;
588586 }
589587 intravisit:: walk_struct_field ( self , field) ;
590588 }
@@ -630,7 +628,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
630628 let mut visitor = DeadVisitor {
631629 tcx : tcx,
632630 live_symbols : live_symbols,
633- need_check_next_union_field : true ,
634631 } ;
635632 intravisit:: walk_crate ( & mut visitor, krate) ;
636633}
0 commit comments