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.
This commit is contained in:
bors 2014-06-10 09:49:29 -07:00
commit 9bb8f88d3a
40 changed files with 223 additions and 148 deletions

View File

@ -44,7 +44,6 @@ use std::string::String;
* pattern - see the `glob` function for more details. * pattern - see the `glob` function for more details.
*/ */
pub struct Paths { pub struct Paths {
root: Path,
dir_patterns: Vec<Pattern>, dir_patterns: Vec<Pattern>,
require_dir: bool, require_dir: bool,
options: MatchOptions, options: MatchOptions,
@ -108,7 +107,6 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths {
// FIXME: How do we want to handle verbatim paths? I'm inclined to return nothing, // FIXME: How do we want to handle verbatim paths? I'm inclined to return nothing,
// since we can't very well find all UNC shares with a 1-letter server name. // since we can't very well find all UNC shares with a 1-letter server name.
return Paths { return Paths {
root: root,
dir_patterns: Vec::new(), dir_patterns: Vec::new(),
require_dir: false, require_dir: false,
options: options, options: options,
@ -134,7 +132,6 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths {
} }
Paths { Paths {
root: root,
dir_patterns: dir_patterns, dir_patterns: dir_patterns,
require_dir: require_dir, require_dir: require_dir,
options: options, options: options,

View File

@ -143,6 +143,7 @@ extern {
// stacks are disabled. // stacks are disabled.
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
#[repr(C)]
struct Registers { struct Registers {
eax: u32, ebx: u32, ecx: u32, edx: u32, eax: u32, ebx: u32, ecx: u32, edx: u32,
ebp: u32, esi: u32, edi: u32, esp: u32, ebp: u32, esi: u32, edi: u32, esp: u32,

View File

@ -20,6 +20,7 @@ pub static FIONBIO: libc::c_long = 0x8004667e;
static FD_SETSIZE: uint = 64; static FD_SETSIZE: uint = 64;
pub static MSG_DONTWAIT: libc::c_int = 0; pub static MSG_DONTWAIT: libc::c_int = 0;
#[repr(C)]
pub struct WSADATA { pub struct WSADATA {
pub wVersion: libc::WORD, pub wVersion: libc::WORD,
pub wHighVersion: libc::WORD, pub wHighVersion: libc::WORD,
@ -32,6 +33,7 @@ pub struct WSADATA {
pub type LPWSADATA = *mut WSADATA; pub type LPWSADATA = *mut WSADATA;
#[repr(C)]
pub struct fd_set { pub struct fd_set {
fd_count: libc::c_uint, fd_count: libc::c_uint,
fd_array: [libc::SOCKET, ..FD_SETSIZE], fd_array: [libc::SOCKET, ..FD_SETSIZE],

View File

@ -152,13 +152,13 @@ fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
/// Implementation of rt::rtio's IoFactory trait to generate handles to the /// Implementation of rt::rtio's IoFactory trait to generate handles to the
/// native I/O functionality. /// native I/O functionality.
pub struct IoFactory { pub struct IoFactory {
cannot_construct_outside_of_this_module: () _cannot_construct_outside_of_this_module: ()
} }
impl IoFactory { impl IoFactory {
pub fn new() -> IoFactory { pub fn new() -> IoFactory {
net::init(); net::init();
IoFactory { cannot_construct_outside_of_this_module: () } IoFactory { _cannot_construct_outside_of_this_module: () }
} }
} }

View File

@ -254,7 +254,10 @@ pub struct TcpStream {
struct Inner { struct Inner {
fd: sock_t, fd: sock_t,
lock: mutex::NativeMutex,
// Unused on Linux, where this lock is not necessary.
#[allow(dead_code)]
lock: mutex::NativeMutex
} }
pub struct Guard<'a> { pub struct Guard<'a> {

View File

@ -58,7 +58,10 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
struct Inner { struct Inner {
fd: fd_t, fd: fd_t,
lock: mutex::NativeMutex,
// Unused on Linux, where this lock is not necessary.
#[allow(dead_code)]
lock: mutex::NativeMutex
} }
impl Inner { impl Inner {

View File

@ -81,7 +81,6 @@ struct GammaSmallShape {
/// See `Gamma` for sampling from a Gamma distribution with general /// See `Gamma` for sampling from a Gamma distribution with general
/// shape parameters. /// shape parameters.
struct GammaLargeShape { struct GammaLargeShape {
shape: f64,
scale: f64, scale: f64,
c: f64, c: f64,
d: f64 d: f64
@ -118,7 +117,6 @@ impl GammaLargeShape {
fn new_raw(shape: f64, scale: f64) -> GammaLargeShape { fn new_raw(shape: f64, scale: f64) -> GammaLargeShape {
let d = shape - 1. / 3.; let d = shape - 1. / 3.;
GammaLargeShape { GammaLargeShape {
shape: shape,
scale: scale, scale: scale,
c: 1. / (9. * d).sqrt(), c: 1. / (9. * d).sqrt(),
d: d d: d

View File

@ -130,9 +130,7 @@ fn inject_crates_ref(sess: &Session, krate: ast::Crate) -> ast::Crate {
fold.fold_crate(krate) fold.fold_crate(krate)
} }
struct PreludeInjector<'a> { struct PreludeInjector<'a>;
sess: &'a Session,
}
impl<'a> fold::Folder for PreludeInjector<'a> { impl<'a> fold::Folder for PreludeInjector<'a> {
@ -223,9 +221,7 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
} }
} }
fn inject_prelude(sess: &Session, krate: ast::Crate) -> ast::Crate { fn inject_prelude(_: &Session, krate: ast::Crate) -> ast::Crate {
let mut fold = PreludeInjector { let mut fold = PreludeInjector;
sess: sess,
};
fold.fold_crate(krate) fold.fold_crate(krate)
} }

View File

@ -86,7 +86,7 @@ pub struct Library {
} }
pub struct ArchiveMetadata { pub struct ArchiveMetadata {
archive: ArchiveRO, _archive: ArchiveRO,
// See comments in ArchiveMetadata::new for why this is static // See comments in ArchiveMetadata::new for why this is static
data: &'static [u8], data: &'static [u8],
} }
@ -487,7 +487,7 @@ impl ArchiveMetadata {
unsafe { mem::transmute(data) } unsafe { mem::transmute(data) }
}; };
Some(ArchiveMetadata { Some(ArchiveMetadata {
archive: ar, _archive: ar,
data: data, data: data,
}) })
} }

View File

@ -42,8 +42,6 @@ pub struct ctxt<'a> {
// Extra parameters are for converting to/from def_ids in the string rep. // Extra parameters are for converting to/from def_ids in the string rep.
// Whatever format you choose should not contain pipe characters. // Whatever format you choose should not contain pipe characters.
pub struct ty_abbrev { pub struct ty_abbrev {
pos: uint,
len: uint,
s: String s: String
} }
@ -68,8 +66,6 @@ pub fn enc_ty(w: &mut MemWriter, cx: &ctxt, t: ty::t) {
if abbrev_len < len { if abbrev_len < len {
// I.e. it's actually an abbreviation. // I.e. it's actually an abbreviation.
cx.abbrevs.borrow_mut().insert(t, ty_abbrev { cx.abbrevs.borrow_mut().insert(t, ty_abbrev {
pos: pos as uint,
len: len as uint,
s: format!("\\#{:x}:{:x}\\#", pos, len) s: format!("\\#{:x}:{:x}\\#", pos, len)
}); });
} }

View File

@ -29,7 +29,7 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
cause: euv::LoanCause, cause: euv::LoanCause,
cmt: mc::cmt, cmt: mc::cmt,
loan_region: ty::Region, loan_region: ty::Region,
loan_kind: ty::BorrowKind) _: ty::BorrowKind)
-> Result<(),()> { -> Result<(),()> {
debug!("guarantee_lifetime(cmt={}, loan_region={})", debug!("guarantee_lifetime(cmt={}, loan_region={})",
cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx)); cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
@ -38,7 +38,6 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
span: span, span: span,
cause: cause, cause: cause,
loan_region: loan_region, loan_region: loan_region,
loan_kind: loan_kind,
cmt_original: cmt.clone()}; cmt_original: cmt.clone()};
ctxt.check(&cmt, None) ctxt.check(&cmt, None)
} }
@ -55,7 +54,6 @@ struct GuaranteeLifetimeContext<'a> {
span: Span, span: Span,
cause: euv::LoanCause, cause: euv::LoanCause,
loan_region: ty::Region, loan_region: ty::Region,
loan_kind: ty::BorrowKind,
cmt_original: mc::cmt cmt_original: mc::cmt
} }

View File

@ -310,7 +310,6 @@ impl<'a> GatherLoanCtxt<'a> {
Loan { Loan {
index: self.all_loans.len(), index: self.all_loans.len(),
loan_path: loan_path, loan_path: loan_path,
cmt: cmt,
kind: req_kind, kind: req_kind,
gen_scope: gen_scope, gen_scope: gen_scope,
kill_scope: kill_scope, kill_scope: kill_scope,
@ -481,8 +480,7 @@ impl<'a> GatherLoanCtxt<'a> {
/// This visitor walks static initializer's expressions and makes /// This visitor walks static initializer's expressions and makes
/// sure the loans being taken are sound. /// sure the loans being taken are sound.
struct StaticInitializerCtxt<'a> { struct StaticInitializerCtxt<'a> {
bccx: &'a BorrowckCtxt<'a>, bccx: &'a BorrowckCtxt<'a>
item_ub: ast::NodeId,
} }
impl<'a> visit::Visitor<()> for StaticInitializerCtxt<'a> { impl<'a> visit::Visitor<()> for StaticInitializerCtxt<'a> {
@ -509,8 +507,7 @@ pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::E
debug!("gather_loans_in_static_initializer(expr={})", expr.repr(bccx.tcx)); debug!("gather_loans_in_static_initializer(expr={})", expr.repr(bccx.tcx));
let mut sicx = StaticInitializerCtxt { let mut sicx = StaticInitializerCtxt {
bccx: bccx, bccx: bccx
item_ub: expr.id,
}; };
sicx.visit_expr(expr, ()); sicx.visit_expr(expr, ());

View File

@ -36,7 +36,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
bccx: bccx, bccx: bccx,
span: span, span: span,
cause: cause, cause: cause,
cmt_original: cmt.clone(),
loan_region: loan_region, loan_region: loan_region,
}; };
@ -49,7 +48,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
struct RestrictionsContext<'a> { struct RestrictionsContext<'a> {
bccx: &'a BorrowckCtxt<'a>, bccx: &'a BorrowckCtxt<'a>,
span: Span, span: Span,
cmt_original: mc::cmt,
loan_region: ty::Region, loan_region: ty::Region,
cause: euv::LoanCause, cause: euv::LoanCause,
} }

View File

@ -180,7 +180,6 @@ pub enum PartialTotal {
pub struct Loan { pub struct Loan {
index: uint, index: uint,
loan_path: Rc<LoanPath>, loan_path: Rc<LoanPath>,
cmt: mc::cmt,
kind: ty::BorrowKind, kind: ty::BorrowKind,
restrictions: Vec<Restriction>, restrictions: Vec<Restriction>,
gen_scope: ast::NodeId, gen_scope: ast::NodeId,

View File

@ -124,6 +124,32 @@ impl<'a> MarkSymbolVisitor<'a> {
} }
} }
fn handle_field_access(&mut self, lhs: &ast::Expr, name: &ast::Ident) {
match ty::get(ty::expr_ty_adjusted(self.tcx, lhs)).sty {
ty::ty_struct(id, _) => {
let fields = ty::lookup_struct_fields(self.tcx, id);
let field_id = fields.iter()
.find(|field| field.name == name.name).unwrap().id;
self.live_symbols.insert(field_id.node);
},
_ => ()
}
}
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[ast::FieldPat]) {
match self.tcx.def_map.borrow().get(&lhs.id) {
&def::DefStruct(id) | &def::DefVariant(_, id, _) => {
let fields = ty::lookup_struct_fields(self.tcx, id);
for pat in pats.iter() {
let field_id = fields.iter()
.find(|field| field.name == pat.ident.name).unwrap().id;
self.live_symbols.insert(field_id.node);
}
}
_ => ()
}
}
fn mark_live_symbols(&mut self) { fn mark_live_symbols(&mut self) {
let mut scanned = HashSet::new(); let mut scanned = HashSet::new();
while self.worklist.len() > 0 { while self.worklist.len() > 0 {
@ -147,10 +173,22 @@ impl<'a> MarkSymbolVisitor<'a> {
match *node { match *node {
ast_map::NodeItem(item) => { ast_map::NodeItem(item) => {
match item.node { match item.node {
ast::ItemStruct(struct_def, _) => {
let has_extern_repr = item.attrs.iter().fold(attr::ReprAny, |acc, attr| {
attr::find_repr_attr(self.tcx.sess.diagnostic(), attr, acc)
}) == attr::ReprExtern;
let live_fields = struct_def.fields.iter().filter(|f| {
has_extern_repr || match f.node.kind {
ast::NamedField(_, ast::Public) => true,
_ => false
}
});
self.live_symbols.extend(live_fields.map(|f| f.node.id));
visit::walk_item(self, item, ());
}
ast::ItemFn(..) ast::ItemFn(..)
| ast::ItemTy(..) | ast::ItemTy(..)
| ast::ItemEnum(..) | ast::ItemEnum(..)
| ast::ItemStruct(..)
| ast::ItemStatic(..) => { | ast::ItemStatic(..) => {
visit::walk_item(self, item, ()); visit::walk_item(self, item, ());
} }
@ -178,18 +216,32 @@ impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
ast::ExprMethodCall(..) => { ast::ExprMethodCall(..) => {
self.lookup_and_handle_method(expr.id, expr.span); self.lookup_and_handle_method(expr.id, expr.span);
} }
ast::ExprField(ref lhs, ref ident, _) => {
self.handle_field_access(*lhs, ident);
}
_ => () _ => ()
} }
visit::walk_expr(self, expr, ()) visit::walk_expr(self, expr, ())
} }
fn visit_pat(&mut self, pat: &ast::Pat, _: ()) {
match pat.node {
ast::PatStruct(_, ref fields, _) => {
self.handle_field_pattern_match(pat, fields.as_slice());
}
_ => ()
}
visit::walk_pat(self, pat, ())
}
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, _: ()) { fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, _: ()) {
self.lookup_and_handle_definition(&id); self.lookup_and_handle_definition(&id);
visit::walk_path(self, path, ()); visit::walk_path(self, path, ());
} }
fn visit_item(&mut self, _item: &ast::Item, _: ()) { fn visit_item(&mut self, _: &ast::Item, _: ()) {
// Do not recurse into items. These items will be added to the // Do not recurse into items. These items will be added to the
// worklist and recursed into manually if necessary. // worklist and recursed into manually if necessary.
} }
@ -317,6 +369,23 @@ struct DeadVisitor<'a> {
} }
impl<'a> DeadVisitor<'a> { impl<'a> DeadVisitor<'a> {
fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
let (is_named, has_leading_underscore) = match node.ident() {
Some(ref ident) => (true, token::get_ident(*ident).get()[0] == ('_' as u8)),
_ => (false, false)
};
let field_type = ty::node_id_to_type(self.tcx, node.id);
let is_marker_field = match ty::ty_to_def_id(field_type) {
Some(def_id) => self.tcx.lang_items.items().any(|(_, item)| *item == Some(def_id)),
_ => false
};
is_named
&& !self.symbol_is_live(node.id, None)
&& !has_leading_underscore
&& !is_marker_field
&& !has_allow_dead_code_or_lang_attr(node.attrs.as_slice())
}
// id := node id of an item's definition. // id := node id of an item's definition.
// ctor_id := `Some` if the item is a struct_ctor (tuple struct), // ctor_id := `Some` if the item is a struct_ctor (tuple struct),
// `None` otherwise. // `None` otherwise.
@ -399,6 +468,14 @@ impl<'a> Visitor<()> for DeadVisitor<'a> {
visit::walk_block(self, block, ()); visit::walk_block(self, block, ());
} }
fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
if self.should_warn_about_field(&field.node) {
self.warn_dead_code(field.node.id, field.span, field.node.ident().unwrap());
}
visit::walk_struct_field(self, field, ());
}
// Overwrite so that we don't warn the trait method itself. // Overwrite so that we don't warn the trait method itself.
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) { fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
match *trait_method { match *trait_method {

View File

@ -226,21 +226,12 @@ fn invalid_node() -> LiveNode { LiveNode(uint::MAX) }
struct CaptureInfo { struct CaptureInfo {
ln: LiveNode, ln: LiveNode,
is_move: bool,
var_nid: NodeId var_nid: NodeId
} }
enum LocalKind {
FromMatch(BindingMode),
FromLetWithInitializer,
FromLetNoInitializer
}
struct LocalInfo { struct LocalInfo {
id: NodeId, id: NodeId,
ident: Ident, ident: Ident
is_mutbl: bool,
kind: LocalKind,
} }
enum VarKind { enum VarKind {
@ -406,23 +397,13 @@ fn visit_fn(ir: &mut IrMaps,
} }
fn visit_local(ir: &mut IrMaps, local: &Local) { fn visit_local(ir: &mut IrMaps, local: &Local) {
pat_util::pat_bindings(&ir.tcx.def_map, local.pat, |bm, p_id, sp, path| { pat_util::pat_bindings(&ir.tcx.def_map, local.pat, |_, p_id, sp, path| {
debug!("adding local variable {}", p_id); debug!("adding local variable {}", p_id);
let name = ast_util::path_to_ident(path); let name = ast_util::path_to_ident(path);
ir.add_live_node_for_node(p_id, VarDefNode(sp)); ir.add_live_node_for_node(p_id, VarDefNode(sp));
let kind = match local.init {
Some(_) => FromLetWithInitializer,
None => FromLetNoInitializer
};
let mutbl = match bm {
BindByValue(MutMutable) => true,
_ => false
};
ir.add_variable(Local(LocalInfo { ir.add_variable(Local(LocalInfo {
id: p_id, id: p_id,
ident: name, ident: name
is_mutbl: mutbl,
kind: kind
})); }));
}); });
visit::walk_local(ir, local, ()); visit::walk_local(ir, local, ());
@ -434,16 +415,10 @@ fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
debug!("adding local variable {} from match with bm {:?}", debug!("adding local variable {} from match with bm {:?}",
p_id, bm); p_id, bm);
let name = ast_util::path_to_ident(path); let name = ast_util::path_to_ident(path);
let mutbl = match bm {
BindByValue(MutMutable) => true,
_ => false
};
ir.add_live_node_for_node(p_id, VarDefNode(sp)); ir.add_live_node_for_node(p_id, VarDefNode(sp));
ir.add_variable(Local(LocalInfo { ir.add_variable(Local(LocalInfo {
id: p_id, id: p_id,
ident: name, ident: name
is_mutbl: mutbl,
kind: FromMatch(bm)
})); }));
}) })
} }
@ -481,27 +456,12 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
// in better error messages than just pointing at the closure // in better error messages than just pointing at the closure
// construction site. // construction site.
let mut call_caps = Vec::new(); let mut call_caps = Vec::new();
let fv_mode = freevars::get_capture_mode(ir.tcx, expr.id);
freevars::with_freevars(ir.tcx, expr.id, |freevars| { freevars::with_freevars(ir.tcx, expr.id, |freevars| {
for fv in freevars.iter() { for fv in freevars.iter() {
match moved_variable_node_id_from_def(fv.def) { match moved_variable_node_id_from_def(fv.def) {
Some(rv) => { Some(rv) => {
let fv_ln = ir.add_live_node(FreeVarNode(fv.span)); let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
let fv_id = fv.def.def_id().node;
let fv_ty = ty::node_id_to_type(ir.tcx, fv_id);
let is_move = match fv_mode {
// var must be dead afterwards
freevars::CaptureByValue => {
ty::type_moves_by_default(ir.tcx, fv_ty)
}
// var can still be used
freevars::CaptureByRef => {
false
}
};
call_caps.push(CaptureInfo {ln: fv_ln, call_caps.push(CaptureInfo {ln: fv_ln,
is_move: is_move,
var_nid: rv}); var_nid: rv});
} }
None => {} None => {}

View File

@ -353,7 +353,6 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
struct PrivacyVisitor<'a> { struct PrivacyVisitor<'a> {
tcx: &'a ty::ctxt, tcx: &'a ty::ctxt,
curitem: ast::NodeId, curitem: ast::NodeId,
in_fn: bool,
in_foreign: bool, in_foreign: bool,
parents: NodeMap<ast::NodeId>, parents: NodeMap<ast::NodeId>,
external_exports: resolve::ExternalExports, external_exports: resolve::ExternalExports,
@ -1445,7 +1444,6 @@ pub fn check_crate(tcx: &ty::ctxt,
// Use the parent map to check the privacy of everything // Use the parent map to check the privacy of everything
let mut visitor = PrivacyVisitor { let mut visitor = PrivacyVisitor {
curitem: ast::DUMMY_NODE_ID, curitem: ast::DUMMY_NODE_ID,
in_fn: false,
in_foreign: false, in_foreign: false,
tcx: tcx, tcx: tcx,
parents: visitor.parents, parents: visitor.parents,

View File

@ -806,7 +806,6 @@ fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
/// The main resolver class. /// The main resolver class.
struct Resolver<'a> { struct Resolver<'a> {
session: &'a Session, session: &'a Session,
lang_items: &'a LanguageItems,
graph_root: NameBindings, graph_root: NameBindings,
@ -843,9 +842,6 @@ struct Resolver<'a> {
// The idents for the primitive types. // The idents for the primitive types.
primitive_type_table: PrimitiveTypeTable, primitive_type_table: PrimitiveTypeTable,
// The four namespaces.
namespaces: Vec<Namespace> ,
def_map: DefMap, def_map: DefMap,
export_map2: ExportMap2, export_map2: ExportMap2,
trait_map: TraitMap, trait_map: TraitMap,
@ -902,7 +898,7 @@ impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> {
} }
impl<'a> Resolver<'a> { impl<'a> Resolver<'a> {
fn new(session: &'a Session, lang_items: &'a LanguageItems, crate_span: Span) -> Resolver<'a> { fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
let graph_root = NameBindings::new(); let graph_root = NameBindings::new();
graph_root.define_module(NoParentLink, graph_root.define_module(NoParentLink,
@ -916,7 +912,6 @@ impl<'a> Resolver<'a> {
Resolver { Resolver {
session: session, session: session,
lang_items: lang_items,
// The outermost module has def ID 0; this is not reflected in the // The outermost module has def ID 0; this is not reflected in the
// AST. // AST.
@ -941,8 +936,6 @@ impl<'a> Resolver<'a> {
primitive_type_table: PrimitiveTypeTable::new(), primitive_type_table: PrimitiveTypeTable::new(),
namespaces: vec!(TypeNS, ValueNS),
def_map: RefCell::new(NodeMap::new()), def_map: RefCell::new(NodeMap::new()),
export_map2: RefCell::new(NodeMap::new()), export_map2: RefCell::new(NodeMap::new()),
trait_map: NodeMap::new(), trait_map: NodeMap::new(),
@ -5582,10 +5575,10 @@ pub struct CrateMap {
/// Entry point to crate resolution. /// Entry point to crate resolution.
pub fn resolve_crate(session: &Session, pub fn resolve_crate(session: &Session,
lang_items: &LanguageItems, _: &LanguageItems,
krate: &Crate) krate: &Crate)
-> CrateMap { -> CrateMap {
let mut resolver = Resolver::new(session, lang_items, krate.span); let mut resolver = Resolver::new(session, krate.span);
resolver.resolve(krate); resolver.resolve(krate);
let Resolver { def_map, export_map2, trait_map, last_private, let Resolver { def_map, export_map2, trait_map, last_private,
external_exports, .. } = resolver; external_exports, .. } = resolver;

View File

@ -106,7 +106,9 @@ pub fn init_insn_ctxt() {
task_local_insn_key.replace(Some(RefCell::new(Vec::new()))); task_local_insn_key.replace(Some(RefCell::new(Vec::new())));
} }
pub struct _InsnCtxt { _x: () } pub struct _InsnCtxt {
_cannot_construct_outside_of_this_module: ()
}
#[unsafe_destructor] #[unsafe_destructor]
impl Drop for _InsnCtxt { impl Drop for _InsnCtxt {
@ -124,7 +126,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
Some(ctx) => ctx.borrow_mut().push(s), Some(ctx) => ctx.borrow_mut().push(s),
None => {} None => {}
} }
_InsnCtxt { _x: () } _InsnCtxt { _cannot_construct_outside_of_this_module: () }
} }
pub struct StatRecorder<'a> { pub struct StatRecorder<'a> {

View File

@ -64,9 +64,6 @@ struct LlvmSignature {
// function, because the foreign function may opt to return via an // function, because the foreign function may opt to return via an
// out pointer. // out pointer.
llret_ty: Type, llret_ty: Type,
// True if *Rust* would use an outpointer for this function.
sret: bool,
} }
@ -847,8 +844,7 @@ fn foreign_signature(ccx: &CrateContext, fn_sig: &ty::FnSig, arg_tys: &[ty::t])
let llret_ty = type_of::type_of(ccx, fn_sig.output); let llret_ty = type_of::type_of(ccx, fn_sig.output);
LlvmSignature { LlvmSignature {
llarg_tys: llarg_tys, llarg_tys: llarg_tys,
llret_ty: llret_ty, llret_ty: llret_ty
sret: type_of::return_uses_outptr(ccx, fn_sig.output),
} }
} }

View File

@ -52,9 +52,7 @@ use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
struct UniversalQuantificationResult { struct UniversalQuantificationResult {
monotype: t, monotype: t
type_variables: Vec<ty::t> ,
type_param_defs: Rc<Vec<ty::TypeParameterDef> >
} }
fn get_base_type(inference_context: &InferCtxt, fn get_base_type(inference_context: &InferCtxt,
@ -515,9 +513,7 @@ impl<'a> CoherenceChecker<'a> {
let monotype = polytype.ty.subst(self.crate_context.tcx, &substitutions); let monotype = polytype.ty.subst(self.crate_context.tcx, &substitutions);
UniversalQuantificationResult { UniversalQuantificationResult {
monotype: monotype, monotype: monotype
type_variables: substitutions.tps,
type_param_defs: polytype.generics.type_param_defs.clone()
} }
} }

View File

@ -271,7 +271,6 @@ enum ParamKind { TypeParam, RegionParam, SelfParam }
struct InferredInfo<'a> { struct InferredInfo<'a> {
item_id: ast::NodeId, item_id: ast::NodeId,
kind: ParamKind, kind: ParamKind,
index: uint,
param_id: ast::NodeId, param_id: ast::NodeId,
term: VarianceTermPtr<'a>, term: VarianceTermPtr<'a>,
} }
@ -310,7 +309,6 @@ impl<'a> TermsContext<'a> {
let term = self.arena.alloc(|| InferredTerm(inf_index)); let term = self.arena.alloc(|| InferredTerm(inf_index));
self.inferred_infos.push(InferredInfo { item_id: item_id, self.inferred_infos.push(InferredInfo { item_id: item_id,
kind: kind, kind: kind,
index: index,
param_id: param_id, param_id: param_id,
term: term }); term: term });
let newly_added = self.inferred_map.insert(param_id, inf_index); let newly_added = self.inferred_map.insert(param_id, inf_index);

View File

@ -42,23 +42,17 @@ pub fn indent<R>(op: || -> R) -> R {
r r
} }
pub struct _indenter { pub struct Indenter {
_i: (), _cannot_construct_outside_of_this_module: ()
} }
impl Drop for _indenter { impl Drop for Indenter {
fn drop(&mut self) { debug!("<<"); } fn drop(&mut self) { debug!("<<"); }
} }
pub fn _indenter(_i: ()) -> _indenter { pub fn indenter() -> Indenter {
_indenter {
_i: ()
}
}
pub fn indenter() -> _indenter {
debug!(">>"); debug!(">>");
_indenter(()) Indenter { _cannot_construct_outside_of_this_module: () }
} }
struct LoopQueryVisitor<'a> { struct LoopQueryVisitor<'a> {

View File

@ -24,6 +24,7 @@
//! // ... something using html //! // ... something using html
//! ``` //! ```
#![allow(dead_code)]
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use libc; use libc;

View File

@ -298,10 +298,12 @@ mod imp {
static _PTHREAD_MUTEX_SIG_init: libc::c_long = 0x32AAABA7; static _PTHREAD_MUTEX_SIG_init: libc::c_long = 0x32AAABA7;
static _PTHREAD_COND_SIG_init: libc::c_long = 0x3CB0B1BB; static _PTHREAD_COND_SIG_init: libc::c_long = 0x3CB0B1BB;
#[repr(C)]
pub struct pthread_mutex_t { pub struct pthread_mutex_t {
__sig: libc::c_long, __sig: libc::c_long,
__opaque: [u8, ..__PTHREAD_MUTEX_SIZE__], __opaque: [u8, ..__PTHREAD_MUTEX_SIZE__],
} }
#[repr(C)]
pub struct pthread_cond_t { pub struct pthread_cond_t {
__sig: libc::c_long, __sig: libc::c_long,
__opaque: [u8, ..__PTHREAD_COND_SIZE__], __opaque: [u8, ..__PTHREAD_COND_SIZE__],
@ -339,10 +341,12 @@ mod imp {
#[cfg(target_arch = "mips")] #[cfg(target_arch = "mips")]
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8; static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
#[repr(C)]
pub struct pthread_mutex_t { pub struct pthread_mutex_t {
__align: libc::c_longlong, __align: libc::c_longlong,
size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T], size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T],
} }
#[repr(C)]
pub struct pthread_cond_t { pub struct pthread_cond_t {
__align: libc::c_longlong, __align: libc::c_longlong,
size: [u8, ..__SIZEOF_PTHREAD_COND_T], size: [u8, ..__SIZEOF_PTHREAD_COND_T],
@ -361,7 +365,9 @@ mod imp {
mod os { mod os {
use libc; use libc;
#[repr(C)]
pub struct pthread_mutex_t { value: libc::c_int } pub struct pthread_mutex_t { value: libc::c_int }
#[repr(C)]
pub struct pthread_cond_t { value: libc::c_int } pub struct pthread_cond_t { value: libc::c_int }
pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {

View File

@ -18,7 +18,6 @@ use std::rt::rtio::{Callback, PausableIdleCallback};
pub struct IdleWatcher { pub struct IdleWatcher {
handle: *uvll::uv_idle_t, handle: *uvll::uv_idle_t,
idle_flag: bool, idle_flag: bool,
closed: bool,
callback: Box<Callback:Send>, callback: Box<Callback:Send>,
} }
@ -31,7 +30,6 @@ impl IdleWatcher {
let me = box IdleWatcher { let me = box IdleWatcher {
handle: handle, handle: handle,
idle_flag: false, idle_flag: false,
closed: false,
callback: cb, callback: cb,
}; };
return me.install(); return me.install();

View File

@ -165,7 +165,6 @@ pub struct TcpWatcher {
pub struct TcpListener { pub struct TcpListener {
home: HomeHandle, home: HomeHandle,
handle: *uvll::uv_pipe_t, handle: *uvll::uv_pipe_t,
closing_task: Option<BlockedTask>,
outgoing: Sender<Result<Box<rtio::RtioTcpStream:Send>, IoError>>, outgoing: Sender<Result<Box<rtio::RtioTcpStream:Send>, IoError>>,
incoming: Receiver<Result<Box<rtio::RtioTcpStream:Send>, IoError>>, incoming: Receiver<Result<Box<rtio::RtioTcpStream:Send>, IoError>>,
} }
@ -358,7 +357,6 @@ impl TcpListener {
let l = box TcpListener { let l = box TcpListener {
home: io.make_handle(), home: io.make_handle(),
handle: handle, handle: handle,
closing_task: None,
outgoing: tx, outgoing: tx,
incoming: rx, incoming: rx,
}; };

View File

@ -136,6 +136,7 @@ pub struct uv_process_options_t {
// These fields are private because they must be interfaced with through the // These fields are private because they must be interfaced with through the
// functions below. // functions below.
#[repr(C)]
pub struct uv_stdio_container_t { pub struct uv_stdio_container_t {
flags: libc::c_int, flags: libc::c_int,
stream: *uv_stream_t, stream: *uv_stream_t,

View File

@ -393,7 +393,7 @@ mod table {
} }
pub fn move_iter(self) -> MoveEntries<K, V> { pub fn move_iter(self) -> MoveEntries<K, V> {
MoveEntries { table: self, idx: 0, elems_seen: 0 } MoveEntries { table: self, idx: 0 }
} }
} }
@ -428,8 +428,7 @@ mod table {
/// Iterator over the entries in a table, consuming the table. /// Iterator over the entries in a table, consuming the table.
pub struct MoveEntries<K, V> { pub struct MoveEntries<K, V> {
table: RawTable<K, V>, table: RawTable<K, V>,
idx: uint, idx: uint
elems_seen: uint,
} }
impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> { impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {

View File

@ -325,6 +325,7 @@ mod imp {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
fn print(w: &mut Writer, idx: int, addr: *libc::c_void) -> IoResult<()> { fn print(w: &mut Writer, idx: int, addr: *libc::c_void) -> IoResult<()> {
use intrinsics; use intrinsics;
#[repr(C)]
struct Dl_info { struct Dl_info {
dli_fname: *libc::c_char, dli_fname: *libc::c_char,
dli_fbase: *libc::c_void, dli_fbase: *libc::c_void,

View File

@ -84,7 +84,7 @@ pub struct TaskBuilder {
/// Options to spawn the new task with /// Options to spawn the new task with
pub opts: TaskOpts, pub opts: TaskOpts,
gen_body: Option<proc(v: proc():Send):Send -> proc():Send>, gen_body: Option<proc(v: proc():Send):Send -> proc():Send>,
nocopy: Option<marker::NoCopy>, nocopy: marker::NoCopy,
} }
impl TaskBuilder { impl TaskBuilder {
@ -94,7 +94,7 @@ impl TaskBuilder {
TaskBuilder { TaskBuilder {
opts: TaskOpts::new(), opts: TaskOpts::new(),
gen_body: None, gen_body: None,
nocopy: None, nocopy: marker::NoCopy,
} }
} }

View File

@ -355,7 +355,7 @@ pub struct Semaphore {
/// dropped, this value will release the resource back to the semaphore. /// dropped, this value will release the resource back to the semaphore.
#[must_use] #[must_use]
pub struct SemaphoreGuard<'a> { pub struct SemaphoreGuard<'a> {
guard: SemGuard<'a, ()>, _guard: SemGuard<'a, ()>,
} }
impl Semaphore { impl Semaphore {
@ -375,7 +375,7 @@ impl Semaphore {
/// Acquire a resource of this semaphore, returning an RAII guard which will /// Acquire a resource of this semaphore, returning an RAII guard which will
/// release the resource when dropped. /// release the resource when dropped.
pub fn access<'a>(&'a self) -> SemaphoreGuard<'a> { pub fn access<'a>(&'a self) -> SemaphoreGuard<'a> {
SemaphoreGuard { guard: self.sem.access() } SemaphoreGuard { _guard: self.sem.access() }
} }
} }
@ -398,7 +398,7 @@ pub struct Mutex {
/// corresponding mutex is also unlocked. /// corresponding mutex is also unlocked.
#[must_use] #[must_use]
pub struct MutexGuard<'a> { pub struct MutexGuard<'a> {
guard: SemGuard<'a, Vec<WaitQueue>>, _guard: SemGuard<'a, Vec<WaitQueue>>,
/// Inner condition variable which is connected to the outer mutex, and can /// Inner condition variable which is connected to the outer mutex, and can
/// be used for atomic-unlock-and-deschedule. /// be used for atomic-unlock-and-deschedule.
pub cond: Condvar<'a>, pub cond: Condvar<'a>,
@ -421,7 +421,7 @@ impl Mutex {
/// also be accessed through the returned guard. /// also be accessed through the returned guard.
pub fn lock<'a>(&'a self) -> MutexGuard<'a> { pub fn lock<'a>(&'a self) -> MutexGuard<'a> {
let SemCondGuard { guard, cvar } = self.sem.access_cond(); let SemCondGuard { guard, cvar } = self.sem.access_cond();
MutexGuard { guard: guard, cond: cvar } MutexGuard { _guard: guard, cond: cvar }
} }
} }

View File

@ -1053,6 +1053,15 @@ pub struct StructField_ {
pub attrs: Vec<Attribute>, pub attrs: Vec<Attribute>,
} }
impl StructField_ {
pub fn ident(&self) -> Option<Ident> {
match self.kind {
NamedField(ref ident, _) => Some(ident.clone()),
UnnamedField(_) => None
}
}
}
pub type StructField = Spanned<StructField_>; pub type StructField = Spanned<StructField_>;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]

View File

@ -21,11 +21,6 @@ use parse::token::special_idents;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
pub struct Field {
ident: ast::Ident,
ex: @ast::Expr
}
// Transitional reexports so qquote can find the paths it is looking for // Transitional reexports so qquote can find the paths it is looking for
mod syntax { mod syntax {
pub use ext; pub use ext;
@ -1000,9 +995,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
} }
struct Duplicator<'a> { struct Duplicator<'a>;
cx: &'a ExtCtxt<'a>,
}
impl<'a> Folder for Duplicator<'a> { impl<'a> Folder for Duplicator<'a> {
fn new_id(&mut self, _: NodeId) -> NodeId { fn new_id(&mut self, _: NodeId) -> NodeId {
@ -1021,10 +1014,8 @@ pub trait Duplicate {
} }
impl Duplicate for @ast::Expr { impl Duplicate for @ast::Expr {
fn duplicate(&self, cx: &ExtCtxt) -> @ast::Expr { fn duplicate(&self, _: &ExtCtxt) -> @ast::Expr {
let mut folder = Duplicator { let mut folder = Duplicator;
cx: cx,
};
folder.fold_expr(*self) folder.fold_expr(*self)
} }
} }

View File

@ -19,7 +19,6 @@ use codemap::{CodeMap, BytePos};
use codemap; use codemap;
use diagnostic; use diagnostic;
use parse::classify::expr_is_simple_block; use parse::classify::expr_is_simple_block;
use parse::token::IdentInterner;
use parse::token; use parse::token;
use parse::lexer::comments; use parse::lexer::comments;
use parse; use parse;
@ -30,7 +29,6 @@ use print::pp;
use std::io::{IoResult, MemWriter}; use std::io::{IoResult, MemWriter};
use std::io; use std::io;
use std::mem; use std::mem;
use std::rc::Rc;
use std::str; use std::str;
use std::string::String; use std::string::String;
@ -58,7 +56,6 @@ pub struct CurrentCommentAndLiteral {
pub struct State<'a> { pub struct State<'a> {
pub s: pp::Printer, pub s: pp::Printer,
cm: Option<&'a CodeMap>, cm: Option<&'a CodeMap>,
intr: Rc<token::IdentInterner>,
comments: Option<Vec<comments::Comment> >, comments: Option<Vec<comments::Comment> >,
literals: Option<Vec<comments::Literal> >, literals: Option<Vec<comments::Literal> >,
cur_cmnt_and_lit: CurrentCommentAndLiteral, cur_cmnt_and_lit: CurrentCommentAndLiteral,
@ -76,7 +73,6 @@ pub fn rust_printer_annotated<'a>(writer: Box<io::Writer>,
State { State {
s: pp::mk_printer(writer, default_columns), s: pp::mk_printer(writer, default_columns),
cm: None, cm: None,
intr: token::get_ident_interner(),
comments: None, comments: None,
literals: None, literals: None,
cur_cmnt_and_lit: CurrentCommentAndLiteral { cur_cmnt_and_lit: CurrentCommentAndLiteral {
@ -111,7 +107,6 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
let mut s = State { let mut s = State {
s: pp::mk_printer(out, default_columns), s: pp::mk_printer(out, default_columns),
cm: Some(cm), cm: Some(cm),
intr: token::get_ident_interner(),
comments: Some(cmnts), comments: Some(cmnts),
// If the code is post expansion, don't use the table of // If the code is post expansion, don't use the table of
// literals, since it doesn't correspond with the literals // literals, since it doesn't correspond with the literals

View File

@ -39,7 +39,10 @@ static STATIC_USED_IN_ENUM_DISCRIMINANT: uint = 10;
pub type typ = *UsedStruct4; pub type typ = *UsedStruct4;
pub struct PubStruct(); pub struct PubStruct();
struct PrivStruct; //~ ERROR: code is never used struct PrivStruct; //~ ERROR: code is never used
struct UsedStruct1 { x: int } struct UsedStruct1 {
#[allow(dead_code)]
x: int
}
struct UsedStruct2(int); struct UsedStruct2(int);
struct UsedStruct3; struct UsedStruct3;
struct UsedStruct4; struct UsedStruct4;
@ -53,6 +56,7 @@ struct StructUsedAsField;
struct StructUsedInEnum; struct StructUsedInEnum;
struct StructUsedInGeneric; struct StructUsedInGeneric;
pub struct PubStruct2 { pub struct PubStruct2 {
#[allow(dead_code)]
struct_used_as_field: *StructUsedAsField struct_used_as_field: *StructUsedAsField
} }

View File

@ -0,0 +1,67 @@
// Copyright 2013 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.
#![feature(struct_variant)]
#![allow(unused_variable)]
#![allow(non_camel_case_types)]
#![deny(dead_code)]
extern crate libc;
use std::num;
struct Foo {
x: uint,
b: bool, //~ ERROR: code is never used
marker: std::kinds::marker::NoCopy
}
fn field_read(f: Foo) -> uint {
num::pow(f.x, 2)
}
enum XYZ {
X,
Y {
a: String,
b: int //~ ERROR: code is never used
},
Z
}
fn field_match_in_patterns(b: XYZ) -> String {
match b {
Y { a: a, .. } => a,
_ => "".to_string()
}
}
struct Bar {
x: uint, //~ ERROR: code is never used
b: bool,
_guard: ()
}
#[repr(C)]
struct Baz {
x: libc::c_uint
}
fn field_match_in_let(f: Bar) -> bool {
let Bar { b, .. } = f;
b
}
fn main() {
field_read(Foo { x: 1, b: false, marker: std::kinds::marker::NoCopy });
field_match_in_patterns(Z);
field_match_in_let(Bar { x: 42u, b: true, _guard: () });
let _ = Baz { x: 0 };
}

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(dead_code)]
#![feature(managed_boxes)] #![feature(managed_boxes)]
#![forbid(managed_heap_memory)] #![forbid(managed_heap_memory)]

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(dead_code)]
#![forbid(owned_heap_memory)] #![forbid(owned_heap_memory)]

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(dead_code)]
#![deny(uppercase_variables)] #![deny(uppercase_variables)]
use std::io::File; use std::io::File;