Skip to content

Commit 9bb8f88

Browse files
committed
auto merge of #14696 : jakub-/rust/dead-struct-fields, r=alexcrichton
This uncovered some dead code, most notably in middle/liveness.rs, which I think suggests there must be something fishy with that part of the code. The #[allow(dead_code)] annotations on some of the fields I am not super happy about but as I understand, marker type may disappear at some point.
2 parents 0ee6a8e + 8e34f64 commit 9bb8f88

40 files changed

+223
-148
lines changed

src/libglob/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ use std::string::String;
4444
* pattern - see the `glob` function for more details.
4545
*/
4646
pub struct Paths {
47-
root: Path,
4847
dir_patterns: Vec<Pattern>,
4948
require_dir: bool,
5049
options: MatchOptions,
@@ -108,7 +107,6 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths {
108107
// FIXME: How do we want to handle verbatim paths? I'm inclined to return nothing,
109108
// since we can't very well find all UNC shares with a 1-letter server name.
110109
return Paths {
111-
root: root,
112110
dir_patterns: Vec::new(),
113111
require_dir: false,
114112
options: options,
@@ -134,7 +132,6 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths {
134132
}
135133

136134
Paths {
137-
root: root,
138135
dir_patterns: dir_patterns,
139136
require_dir: require_dir,
140137
options: options,

src/libgreen/context.rs

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ extern {
143143
// stacks are disabled.
144144

145145
#[cfg(target_arch = "x86")]
146+
#[repr(C)]
146147
struct Registers {
147148
eax: u32, ebx: u32, ecx: u32, edx: u32,
148149
ebp: u32, esi: u32, edi: u32, esp: u32,

src/libnative/io/c_win32.rs

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub static FIONBIO: libc::c_long = 0x8004667e;
2020
static FD_SETSIZE: uint = 64;
2121
pub static MSG_DONTWAIT: libc::c_int = 0;
2222

23+
#[repr(C)]
2324
pub struct WSADATA {
2425
pub wVersion: libc::WORD,
2526
pub wHighVersion: libc::WORD,
@@ -32,6 +33,7 @@ pub struct WSADATA {
3233

3334
pub type LPWSADATA = *mut WSADATA;
3435

36+
#[repr(C)]
3537
pub struct fd_set {
3638
fd_count: libc::c_uint,
3739
fd_array: [libc::SOCKET, ..FD_SETSIZE],

src/libnative/io/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,13 @@ fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
152152
/// Implementation of rt::rtio's IoFactory trait to generate handles to the
153153
/// native I/O functionality.
154154
pub struct IoFactory {
155-
cannot_construct_outside_of_this_module: ()
155+
_cannot_construct_outside_of_this_module: ()
156156
}
157157

158158
impl IoFactory {
159159
pub fn new() -> IoFactory {
160160
net::init();
161-
IoFactory { cannot_construct_outside_of_this_module: () }
161+
IoFactory { _cannot_construct_outside_of_this_module: () }
162162
}
163163
}
164164

src/libnative/io/net.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,10 @@ pub struct TcpStream {
254254

255255
struct Inner {
256256
fd: sock_t,
257-
lock: mutex::NativeMutex,
257+
258+
// Unused on Linux, where this lock is not necessary.
259+
#[allow(dead_code)]
260+
lock: mutex::NativeMutex
258261
}
259262

260263
pub struct Guard<'a> {

src/libnative/io/pipe_unix.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
5858

5959
struct Inner {
6060
fd: fd_t,
61-
lock: mutex::NativeMutex,
61+
62+
// Unused on Linux, where this lock is not necessary.
63+
#[allow(dead_code)]
64+
lock: mutex::NativeMutex
6265
}
6366

6467
impl Inner {

src/librand/distributions/gamma.rs

-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ struct GammaSmallShape {
8181
/// See `Gamma` for sampling from a Gamma distribution with general
8282
/// shape parameters.
8383
struct GammaLargeShape {
84-
shape: f64,
8584
scale: f64,
8685
c: f64,
8786
d: f64
@@ -118,7 +117,6 @@ impl GammaLargeShape {
118117
fn new_raw(shape: f64, scale: f64) -> GammaLargeShape {
119118
let d = shape - 1. / 3.;
120119
GammaLargeShape {
121-
shape: shape,
122120
scale: scale,
123121
c: 1. / (9. * d).sqrt(),
124122
d: d

src/librustc/front/std_inject.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,7 @@ fn inject_crates_ref(sess: &Session, krate: ast::Crate) -> ast::Crate {
130130
fold.fold_crate(krate)
131131
}
132132

133-
struct PreludeInjector<'a> {
134-
sess: &'a Session,
135-
}
133+
struct PreludeInjector<'a>;
136134

137135

138136
impl<'a> fold::Folder for PreludeInjector<'a> {
@@ -223,9 +221,7 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
223221
}
224222
}
225223

226-
fn inject_prelude(sess: &Session, krate: ast::Crate) -> ast::Crate {
227-
let mut fold = PreludeInjector {
228-
sess: sess,
229-
};
224+
fn inject_prelude(_: &Session, krate: ast::Crate) -> ast::Crate {
225+
let mut fold = PreludeInjector;
230226
fold.fold_crate(krate)
231227
}

src/librustc/metadata/loader.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub struct Library {
8686
}
8787

8888
pub struct ArchiveMetadata {
89-
archive: ArchiveRO,
89+
_archive: ArchiveRO,
9090
// See comments in ArchiveMetadata::new for why this is static
9191
data: &'static [u8],
9292
}
@@ -487,7 +487,7 @@ impl ArchiveMetadata {
487487
unsafe { mem::transmute(data) }
488488
};
489489
Some(ArchiveMetadata {
490-
archive: ar,
490+
_archive: ar,
491491
data: data,
492492
})
493493
}

src/librustc/metadata/tyencode.rs

-4
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ pub struct ctxt<'a> {
4242
// Extra parameters are for converting to/from def_ids in the string rep.
4343
// Whatever format you choose should not contain pipe characters.
4444
pub struct ty_abbrev {
45-
pos: uint,
46-
len: uint,
4745
s: String
4846
}
4947

@@ -68,8 +66,6 @@ pub fn enc_ty(w: &mut MemWriter, cx: &ctxt, t: ty::t) {
6866
if abbrev_len < len {
6967
// I.e. it's actually an abbreviation.
7068
cx.abbrevs.borrow_mut().insert(t, ty_abbrev {
71-
pos: pos as uint,
72-
len: len as uint,
7369
s: format!("\\#{:x}:{:x}\\#", pos, len)
7470
});
7571
}

src/librustc/middle/borrowck/gather_loans/lifetime.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
2929
cause: euv::LoanCause,
3030
cmt: mc::cmt,
3131
loan_region: ty::Region,
32-
loan_kind: ty::BorrowKind)
32+
_: ty::BorrowKind)
3333
-> Result<(),()> {
3434
debug!("guarantee_lifetime(cmt={}, loan_region={})",
3535
cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
@@ -38,7 +38,6 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
3838
span: span,
3939
cause: cause,
4040
loan_region: loan_region,
41-
loan_kind: loan_kind,
4241
cmt_original: cmt.clone()};
4342
ctxt.check(&cmt, None)
4443
}
@@ -55,7 +54,6 @@ struct GuaranteeLifetimeContext<'a> {
5554
span: Span,
5655
cause: euv::LoanCause,
5756
loan_region: ty::Region,
58-
loan_kind: ty::BorrowKind,
5957
cmt_original: mc::cmt
6058
}
6159

src/librustc/middle/borrowck/gather_loans/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ impl<'a> GatherLoanCtxt<'a> {
310310
Loan {
311311
index: self.all_loans.len(),
312312
loan_path: loan_path,
313-
cmt: cmt,
314313
kind: req_kind,
315314
gen_scope: gen_scope,
316315
kill_scope: kill_scope,
@@ -481,8 +480,7 @@ impl<'a> GatherLoanCtxt<'a> {
481480
/// This visitor walks static initializer's expressions and makes
482481
/// sure the loans being taken are sound.
483482
struct StaticInitializerCtxt<'a> {
484-
bccx: &'a BorrowckCtxt<'a>,
485-
item_ub: ast::NodeId,
483+
bccx: &'a BorrowckCtxt<'a>
486484
}
487485

488486
impl<'a> visit::Visitor<()> for StaticInitializerCtxt<'a> {
@@ -509,8 +507,7 @@ pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::E
509507
debug!("gather_loans_in_static_initializer(expr={})", expr.repr(bccx.tcx));
510508

511509
let mut sicx = StaticInitializerCtxt {
512-
bccx: bccx,
513-
item_ub: expr.id,
510+
bccx: bccx
514511
};
515512

516513
sicx.visit_expr(expr, ());

src/librustc/middle/borrowck/gather_loans/restrictions.rs

-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
3636
bccx: bccx,
3737
span: span,
3838
cause: cause,
39-
cmt_original: cmt.clone(),
4039
loan_region: loan_region,
4140
};
4241

@@ -49,7 +48,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
4948
struct RestrictionsContext<'a> {
5049
bccx: &'a BorrowckCtxt<'a>,
5150
span: Span,
52-
cmt_original: mc::cmt,
5351
loan_region: ty::Region,
5452
cause: euv::LoanCause,
5553
}

src/librustc/middle/borrowck/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ pub enum PartialTotal {
180180
pub struct Loan {
181181
index: uint,
182182
loan_path: Rc<LoanPath>,
183-
cmt: mc::cmt,
184183
kind: ty::BorrowKind,
185184
restrictions: Vec<Restriction>,
186185
gen_scope: ast::NodeId,

src/librustc/middle/dead.rs

+79-2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,32 @@ impl<'a> MarkSymbolVisitor<'a> {
124124
}
125125
}
126126

127+
fn handle_field_access(&mut self, lhs: &ast::Expr, name: &ast::Ident) {
128+
match ty::get(ty::expr_ty_adjusted(self.tcx, lhs)).sty {
129+
ty::ty_struct(id, _) => {
130+
let fields = ty::lookup_struct_fields(self.tcx, id);
131+
let field_id = fields.iter()
132+
.find(|field| field.name == name.name).unwrap().id;
133+
self.live_symbols.insert(field_id.node);
134+
},
135+
_ => ()
136+
}
137+
}
138+
139+
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[ast::FieldPat]) {
140+
match self.tcx.def_map.borrow().get(&lhs.id) {
141+
&def::DefStruct(id) | &def::DefVariant(_, id, _) => {
142+
let fields = ty::lookup_struct_fields(self.tcx, id);
143+
for pat in pats.iter() {
144+
let field_id = fields.iter()
145+
.find(|field| field.name == pat.ident.name).unwrap().id;
146+
self.live_symbols.insert(field_id.node);
147+
}
148+
}
149+
_ => ()
150+
}
151+
}
152+
127153
fn mark_live_symbols(&mut self) {
128154
let mut scanned = HashSet::new();
129155
while self.worklist.len() > 0 {
@@ -147,10 +173,22 @@ impl<'a> MarkSymbolVisitor<'a> {
147173
match *node {
148174
ast_map::NodeItem(item) => {
149175
match item.node {
176+
ast::ItemStruct(struct_def, _) => {
177+
let has_extern_repr = item.attrs.iter().fold(attr::ReprAny, |acc, attr| {
178+
attr::find_repr_attr(self.tcx.sess.diagnostic(), attr, acc)
179+
}) == 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+
}
185+
});
186+
self.live_symbols.extend(live_fields.map(|f| f.node.id));
187+
visit::walk_item(self, item, ());
188+
}
150189
ast::ItemFn(..)
151190
| ast::ItemTy(..)
152191
| ast::ItemEnum(..)
153-
| ast::ItemStruct(..)
154192
| ast::ItemStatic(..) => {
155193
visit::walk_item(self, item, ());
156194
}
@@ -178,18 +216,32 @@ impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
178216
ast::ExprMethodCall(..) => {
179217
self.lookup_and_handle_method(expr.id, expr.span);
180218
}
219+
ast::ExprField(ref lhs, ref ident, _) => {
220+
self.handle_field_access(*lhs, ident);
221+
}
181222
_ => ()
182223
}
183224

184225
visit::walk_expr(self, expr, ())
185226
}
186227

228+
fn visit_pat(&mut self, pat: &ast::Pat, _: ()) {
229+
match pat.node {
230+
ast::PatStruct(_, ref fields, _) => {
231+
self.handle_field_pattern_match(pat, fields.as_slice());
232+
}
233+
_ => ()
234+
}
235+
236+
visit::walk_pat(self, pat, ())
237+
}
238+
187239
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, _: ()) {
188240
self.lookup_and_handle_definition(&id);
189241
visit::walk_path(self, path, ());
190242
}
191243

192-
fn visit_item(&mut self, _item: &ast::Item, _: ()) {
244+
fn visit_item(&mut self, _: &ast::Item, _: ()) {
193245
// Do not recurse into items. These items will be added to the
194246
// worklist and recursed into manually if necessary.
195247
}
@@ -317,6 +369,23 @@ struct DeadVisitor<'a> {
317369
}
318370

319371
impl<'a> DeadVisitor<'a> {
372+
fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
373+
let (is_named, has_leading_underscore) = match node.ident() {
374+
Some(ref ident) => (true, token::get_ident(*ident).get()[0] == ('_' as u8)),
375+
_ => (false, false)
376+
};
377+
let field_type = ty::node_id_to_type(self.tcx, node.id);
378+
let is_marker_field = match ty::ty_to_def_id(field_type) {
379+
Some(def_id) => self.tcx.lang_items.items().any(|(_, item)| *item == Some(def_id)),
380+
_ => false
381+
};
382+
is_named
383+
&& !self.symbol_is_live(node.id, None)
384+
&& !has_leading_underscore
385+
&& !is_marker_field
386+
&& !has_allow_dead_code_or_lang_attr(node.attrs.as_slice())
387+
}
388+
320389
// id := node id of an item's definition.
321390
// ctor_id := `Some` if the item is a struct_ctor (tuple struct),
322391
// `None` otherwise.
@@ -399,6 +468,14 @@ impl<'a> Visitor<()> for DeadVisitor<'a> {
399468
visit::walk_block(self, block, ());
400469
}
401470

471+
fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
472+
if self.should_warn_about_field(&field.node) {
473+
self.warn_dead_code(field.node.id, field.span, field.node.ident().unwrap());
474+
}
475+
476+
visit::walk_struct_field(self, field, ());
477+
}
478+
402479
// Overwrite so that we don't warn the trait method itself.
403480
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
404481
match *trait_method {

0 commit comments

Comments
 (0)