Skip to content

Commit 42d538e

Browse files
Jakub Wieczorekalexcrichton
Jakub Wieczorek
authored andcommitted
Fix the unused struct field lint for struct variants
Fixes #14837.
1 parent c17af5d commit 42d538e

File tree

2 files changed

+59
-21
lines changed

2 files changed

+59
-21
lines changed

src/librustc/middle/dead.rs

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ struct MarkSymbolVisitor<'a> {
5555
live_symbols: Box<HashSet<ast::NodeId>>,
5656
}
5757

58+
#[deriving(Clone)]
59+
struct MarkSymbolVisitorContext {
60+
struct_has_extern_repr: bool
61+
}
62+
5863
impl<'a> MarkSymbolVisitor<'a> {
5964
fn new(tcx: &'a ty::ctxt,
6065
worklist: Vec<ast::NodeId>) -> MarkSymbolVisitor<'a> {
@@ -170,48 +175,61 @@ impl<'a> MarkSymbolVisitor<'a> {
170175
}
171176

172177
fn visit_node(&mut self, node: &ast_map::Node) {
178+
let ctxt = MarkSymbolVisitorContext {
179+
struct_has_extern_repr: false
180+
};
173181
match *node {
174182
ast_map::NodeItem(item) => {
175183
match item.node {
176-
ast::ItemStruct(struct_def, _) => {
184+
ast::ItemStruct(..) => {
177185
let has_extern_repr = item.attrs.iter().fold(attr::ReprAny, |acc, attr| {
178186
attr::find_repr_attr(self.tcx.sess.diagnostic(), attr, acc)
179187
}) == attr::ReprExtern;
180-
let live_fields = struct_def.fields.iter().filter(|f| {
181-
has_extern_repr || match f.node.kind {
182-
ast::NamedField(_, ast::Public) => true,
183-
_ => false
184-
}
188+
189+
visit::walk_item(self, &*item, MarkSymbolVisitorContext {
190+
struct_has_extern_repr: has_extern_repr,
191+
..(ctxt)
185192
});
186-
self.live_symbols.extend(live_fields.map(|f| f.node.id));
187-
visit::walk_item(self, &*item, ());
188193
}
189194
ast::ItemFn(..)
190-
| ast::ItemTy(..)
191195
| ast::ItemEnum(..)
196+
| ast::ItemTy(..)
192197
| ast::ItemStatic(..) => {
193-
visit::walk_item(self, &*item, ());
198+
visit::walk_item(self, &*item, ctxt);
194199
}
195200
_ => ()
196201
}
197202
}
198203
ast_map::NodeTraitMethod(trait_method) => {
199-
visit::walk_trait_method(self, &*trait_method, ());
204+
visit::walk_trait_method(self, &*trait_method, ctxt);
200205
}
201206
ast_map::NodeMethod(method) => {
202-
visit::walk_block(self, &*method.body, ());
207+
visit::walk_block(self, &*method.body, ctxt);
203208
}
204209
ast_map::NodeForeignItem(foreign_item) => {
205-
visit::walk_foreign_item(self, &*foreign_item, ());
210+
visit::walk_foreign_item(self, &*foreign_item, ctxt);
206211
}
207212
_ => ()
208213
}
209214
}
210215
}
211216

212-
impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
217+
impl<'a> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a> {
218+
219+
fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident, _: &ast::Generics,
220+
_: ast::NodeId, ctxt: MarkSymbolVisitorContext) {
221+
let live_fields = def.fields.iter().filter(|f| {
222+
ctxt.struct_has_extern_repr || match f.node.kind {
223+
ast::NamedField(_, ast::Public) => true,
224+
_ => false
225+
}
226+
});
227+
self.live_symbols.extend(live_fields.map(|f| f.node.id));
228+
229+
visit::walk_struct_def(self, def, ctxt);
230+
}
213231

214-
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
232+
fn visit_expr(&mut self, expr: &ast::Expr, ctxt: MarkSymbolVisitorContext) {
215233
match expr.node {
216234
ast::ExprMethodCall(..) => {
217235
self.lookup_and_handle_method(expr.id, expr.span);
@@ -222,26 +240,26 @@ impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
222240
_ => ()
223241
}
224242

225-
visit::walk_expr(self, expr, ())
243+
visit::walk_expr(self, expr, ctxt);
226244
}
227245

228-
fn visit_pat(&mut self, pat: &ast::Pat, _: ()) {
246+
fn visit_pat(&mut self, pat: &ast::Pat, ctxt: MarkSymbolVisitorContext) {
229247
match pat.node {
230248
ast::PatStruct(_, ref fields, _) => {
231249
self.handle_field_pattern_match(pat, fields.as_slice());
232250
}
233251
_ => ()
234252
}
235253

236-
visit::walk_pat(self, pat, ())
254+
visit::walk_pat(self, pat, ctxt);
237255
}
238256

239-
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, _: ()) {
257+
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, ctxt: MarkSymbolVisitorContext) {
240258
self.lookup_and_handle_definition(&id);
241-
visit::walk_path(self, path, ());
259+
visit::walk_path(self, path, ctxt);
242260
}
243261

244-
fn visit_item(&mut self, _: &ast::Item, _: ()) {
262+
fn visit_item(&mut self, _: &ast::Item, _: MarkSymbolVisitorContext) {
245263
// Do not recurse into items. These items will be added to the
246264
// worklist and recursed into manually if necessary.
247265
}

src/test/run-pass/issue-14837.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(struct_variant)]
12+
#![deny(warnings)]
13+
14+
pub enum Foo {
15+
Bar {
16+
pub baz: int
17+
}
18+
}
19+
20+
fn main() { }

0 commit comments

Comments
 (0)