diff options
| author | bors <bors@rust-lang.org> | 2017-08-06 18:57:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-08-06 18:57:57 +0000 |
| commit | ba1d065ffa3606b61201ef69fec3ad0bfc5b2f7b (patch) | |
| tree | 9e000dde2eb7a305f471cb6d3cb5609593018d02 | |
| parent | be69520b9ae32c9242207fd5bc97888cd3fc73bf (diff) | |
| parent | f94157eb616d18655809ea60af870e1888476c9a (diff) | |
| download | rust-ba1d065ffa3606b61201ef69fec3ad0bfc5b2f7b.tar.gz rust-ba1d065ffa3606b61201ef69fec3ad0bfc5b2f7b.zip | |
Auto merge of #43397 - GuillaumeGomez:unused-union-field, r=petrochenkov
Don't warn on unused field on union Fixes #43393.
| -rw-r--r-- | src/librustc/middle/dead.rs | 31 | ||||
| -rw-r--r-- | src/test/ui/union-fields.rs | 42 | ||||
| -rw-r--r-- | src/test/ui/union-fields.stderr | 32 |
3 files changed, 102 insertions, 3 deletions
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 2238e464cbc..a525b4e13b7 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -13,7 +13,7 @@ // from live codes are live, and everything else is dead. use hir::map as hir_map; -use hir::{self, PatKind}; +use hir::{self, Item_, PatKind}; use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir::itemlikevisit::ItemLikeVisitor; @@ -189,6 +189,22 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { self.struct_has_extern_repr = had_extern_repr; self.inherited_pub_visibility = had_inherited_pub_visibility; } + + fn mark_as_used_if_union(&mut self, did: DefId, fields: &hir::HirVec<hir::Field>) { + if let Some(node_id) = self.tcx.hir.as_local_node_id(did) { + if let Some(hir_map::NodeItem(item)) = self.tcx.hir.find(node_id) { + if let Item_::ItemUnion(ref variant, _) = item.node { + if variant.fields().len() > 1 { + for field in variant.fields() { + if fields.iter().find(|x| x.name.node == field.name).is_some() { + self.live_symbols.insert(field.id); + } + } + } + } + } + } + } } impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { @@ -231,6 +247,13 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { hir::ExprTupField(ref lhs, idx) => { self.handle_tup_field_access(&lhs, idx.node); } + hir::ExprStruct(_, ref fields, _) => { + if let ty::TypeVariants::TyAdt(ref def, _) = self.tables.expr_ty(expr).sty { + if def.is_union() { + self.mark_as_used_if_union(def.did, fields); + } + } + } _ => () } @@ -561,7 +584,6 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { self.warn_dead_code(field.id, field.span, field.name, "field"); } - intravisit::walk_struct_field(self, field); } @@ -603,6 +625,9 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); let krate = tcx.hir.krate(); let live_symbols = find_live(tcx, access_levels, krate); - let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols }; + let mut visitor = DeadVisitor { + tcx: tcx, + live_symbols: live_symbols, + }; intravisit::walk_crate(&mut visitor, krate); } diff --git a/src/test/ui/union-fields.rs b/src/test/ui/union-fields.rs new file mode 100644 index 00000000000..021f57e3eee --- /dev/null +++ b/src/test/ui/union-fields.rs @@ -0,0 +1,42 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(dead_code)] + +union U1 { + a: u8, // should not be reported + b: u8, // should not be reported + c: u8, // should be reported +} +union U2 { + a: u8, // should be reported + b: u8, // should not be reported + c: u8, // should not be reported +} +union NoDropLike { a: u8 } // should be reported as unused + +union U { + a: u8, // should not be reported + b: u8, // should not be reported + c: u8, // should be reported +} +type A = U; + +fn main() { + let u = U1 { a: 0 }; + let _a = unsafe { u.b }; + + let u = U2 { c: 0 }; + let _b = unsafe { u.b }; + + let _u = NoDropLike { a: 10 }; + let u = A { a: 0 }; + let _b = unsafe { u.b }; +} diff --git a/src/test/ui/union-fields.stderr b/src/test/ui/union-fields.stderr new file mode 100644 index 00000000000..f3a2702d5ae --- /dev/null +++ b/src/test/ui/union-fields.stderr @@ -0,0 +1,32 @@ +error: field is never used: `c` + --> $DIR/union-fields.rs:16:5 + | +16 | c: u8, // should be reported + | ^^^^^ + | +note: lint level defined here + --> $DIR/union-fields.rs:11:9 + | +11 | #![deny(dead_code)] + | ^^^^^^^^^ + +error: field is never used: `a` + --> $DIR/union-fields.rs:19:5 + | +19 | a: u8, // should be reported + | ^^^^^ + +error: field is never used: `a` + --> $DIR/union-fields.rs:23:20 + | +23 | union NoDropLike { a: u8 } // should be reported as unused + | ^^^^^ + +error: field is never used: `c` + --> $DIR/union-fields.rs:28:5 + | +28 | c: u8, // should be reported + | ^^^^^ + +error: aborting due to 4 previous errors + |
