|
13 | 13 | // from live codes are live, and everything else is dead. |
14 | 14 |
|
15 | 15 | use hir::map as hir_map; |
16 | | -use hir::{self, PatKind}; |
| 16 | +use hir::{self, Item_, PatKind}; |
17 | 17 | use hir::intravisit::{self, Visitor, NestedVisitorMap}; |
18 | 18 | use hir::itemlikevisit::ItemLikeVisitor; |
19 | 19 |
|
@@ -189,6 +189,22 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { |
189 | 189 | self.struct_has_extern_repr = had_extern_repr; |
190 | 190 | self.inherited_pub_visibility = had_inherited_pub_visibility; |
191 | 191 | } |
| 192 | + |
| 193 | + fn mark_as_used_if_union(&mut self, did: DefId, fields: &hir::HirVec<hir::Field>) { |
| 194 | + if let Some(node_id) = self.tcx.hir.as_local_node_id(did) { |
| 195 | + if let Some(hir_map::NodeItem(item)) = self.tcx.hir.find(node_id) { |
| 196 | + if let Item_::ItemUnion(ref variant, _) = item.node { |
| 197 | + if variant.fields().len() > 1 { |
| 198 | + for field in variant.fields() { |
| 199 | + if fields.iter().find(|x| x.name.node == field.name).is_some() { |
| 200 | + self.live_symbols.insert(field.id); |
| 201 | + } |
| 202 | + } |
| 203 | + } |
| 204 | + } |
| 205 | + } |
| 206 | + } |
| 207 | + } |
192 | 208 | } |
193 | 209 |
|
194 | 210 | impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { |
@@ -231,6 +247,13 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { |
231 | 247 | hir::ExprTupField(ref lhs, idx) => { |
232 | 248 | self.handle_tup_field_access(&lhs, idx.node); |
233 | 249 | } |
| 250 | + hir::ExprStruct(_, ref fields, _) => { |
| 251 | + if let ty::TypeVariants::TyAdt(ref def, _) = self.tables.expr_ty(expr).sty { |
| 252 | + if def.is_union() { |
| 253 | + self.mark_as_used_if_union(def.did, fields); |
| 254 | + } |
| 255 | + } |
| 256 | + } |
234 | 257 | _ => () |
235 | 258 | } |
236 | 259 |
|
@@ -561,7 +584,6 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { |
561 | 584 | self.warn_dead_code(field.id, field.span, |
562 | 585 | field.name, "field"); |
563 | 586 | } |
564 | | - |
565 | 587 | intravisit::walk_struct_field(self, field); |
566 | 588 | } |
567 | 589 |
|
@@ -603,6 +625,9 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { |
603 | 625 | let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); |
604 | 626 | let krate = tcx.hir.krate(); |
605 | 627 | let live_symbols = find_live(tcx, access_levels, krate); |
606 | | - let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols }; |
| 628 | + let mut visitor = DeadVisitor { |
| 629 | + tcx: tcx, |
| 630 | + live_symbols: live_symbols, |
| 631 | + }; |
607 | 632 | intravisit::walk_crate(&mut visitor, krate); |
608 | 633 | } |
0 commit comments