mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 10:13:54 +00:00
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:
commit
9bb8f88d3a
@ -44,7 +44,6 @@ use std::string::String;
|
||||
* pattern - see the `glob` function for more details.
|
||||
*/
|
||||
pub struct Paths {
|
||||
root: Path,
|
||||
dir_patterns: Vec<Pattern>,
|
||||
require_dir: bool,
|
||||
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,
|
||||
// since we can't very well find all UNC shares with a 1-letter server name.
|
||||
return Paths {
|
||||
root: root,
|
||||
dir_patterns: Vec::new(),
|
||||
require_dir: false,
|
||||
options: options,
|
||||
@ -134,7 +132,6 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths {
|
||||
}
|
||||
|
||||
Paths {
|
||||
root: root,
|
||||
dir_patterns: dir_patterns,
|
||||
require_dir: require_dir,
|
||||
options: options,
|
||||
|
@ -143,6 +143,7 @@ extern {
|
||||
// stacks are disabled.
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[repr(C)]
|
||||
struct Registers {
|
||||
eax: u32, ebx: u32, ecx: u32, edx: u32,
|
||||
ebp: u32, esi: u32, edi: u32, esp: u32,
|
||||
|
@ -20,6 +20,7 @@ pub static FIONBIO: libc::c_long = 0x8004667e;
|
||||
static FD_SETSIZE: uint = 64;
|
||||
pub static MSG_DONTWAIT: libc::c_int = 0;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WSADATA {
|
||||
pub wVersion: libc::WORD,
|
||||
pub wHighVersion: libc::WORD,
|
||||
@ -32,6 +33,7 @@ pub struct WSADATA {
|
||||
|
||||
pub type LPWSADATA = *mut WSADATA;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct fd_set {
|
||||
fd_count: libc::c_uint,
|
||||
fd_array: [libc::SOCKET, ..FD_SETSIZE],
|
||||
|
@ -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
|
||||
/// native I/O functionality.
|
||||
pub struct IoFactory {
|
||||
cannot_construct_outside_of_this_module: ()
|
||||
_cannot_construct_outside_of_this_module: ()
|
||||
}
|
||||
|
||||
impl IoFactory {
|
||||
pub fn new() -> IoFactory {
|
||||
net::init();
|
||||
IoFactory { cannot_construct_outside_of_this_module: () }
|
||||
IoFactory { _cannot_construct_outside_of_this_module: () }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,10 @@ pub struct TcpStream {
|
||||
|
||||
struct Inner {
|
||||
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> {
|
||||
|
@ -58,7 +58,10 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
|
||||
|
||||
struct Inner {
|
||||
fd: fd_t,
|
||||
lock: mutex::NativeMutex,
|
||||
|
||||
// Unused on Linux, where this lock is not necessary.
|
||||
#[allow(dead_code)]
|
||||
lock: mutex::NativeMutex
|
||||
}
|
||||
|
||||
impl Inner {
|
||||
|
@ -81,7 +81,6 @@ struct GammaSmallShape {
|
||||
/// See `Gamma` for sampling from a Gamma distribution with general
|
||||
/// shape parameters.
|
||||
struct GammaLargeShape {
|
||||
shape: f64,
|
||||
scale: f64,
|
||||
c: f64,
|
||||
d: f64
|
||||
@ -118,7 +117,6 @@ impl GammaLargeShape {
|
||||
fn new_raw(shape: f64, scale: f64) -> GammaLargeShape {
|
||||
let d = shape - 1. / 3.;
|
||||
GammaLargeShape {
|
||||
shape: shape,
|
||||
scale: scale,
|
||||
c: 1. / (9. * d).sqrt(),
|
||||
d: d
|
||||
|
@ -130,9 +130,7 @@ fn inject_crates_ref(sess: &Session, krate: ast::Crate) -> ast::Crate {
|
||||
fold.fold_crate(krate)
|
||||
}
|
||||
|
||||
struct PreludeInjector<'a> {
|
||||
sess: &'a Session,
|
||||
}
|
||||
struct 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 {
|
||||
let mut fold = PreludeInjector {
|
||||
sess: sess,
|
||||
};
|
||||
fn inject_prelude(_: &Session, krate: ast::Crate) -> ast::Crate {
|
||||
let mut fold = PreludeInjector;
|
||||
fold.fold_crate(krate)
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ pub struct Library {
|
||||
}
|
||||
|
||||
pub struct ArchiveMetadata {
|
||||
archive: ArchiveRO,
|
||||
_archive: ArchiveRO,
|
||||
// See comments in ArchiveMetadata::new for why this is static
|
||||
data: &'static [u8],
|
||||
}
|
||||
@ -487,7 +487,7 @@ impl ArchiveMetadata {
|
||||
unsafe { mem::transmute(data) }
|
||||
};
|
||||
Some(ArchiveMetadata {
|
||||
archive: ar,
|
||||
_archive: ar,
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
|
@ -42,8 +42,6 @@ pub struct ctxt<'a> {
|
||||
// Extra parameters are for converting to/from def_ids in the string rep.
|
||||
// Whatever format you choose should not contain pipe characters.
|
||||
pub struct ty_abbrev {
|
||||
pos: uint,
|
||||
len: uint,
|
||||
s: String
|
||||
}
|
||||
|
||||
@ -68,8 +66,6 @@ pub fn enc_ty(w: &mut MemWriter, cx: &ctxt, t: ty::t) {
|
||||
if abbrev_len < len {
|
||||
// I.e. it's actually an abbreviation.
|
||||
cx.abbrevs.borrow_mut().insert(t, ty_abbrev {
|
||||
pos: pos as uint,
|
||||
len: len as uint,
|
||||
s: format!("\\#{:x}:{:x}\\#", pos, len)
|
||||
});
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
|
||||
cause: euv::LoanCause,
|
||||
cmt: mc::cmt,
|
||||
loan_region: ty::Region,
|
||||
loan_kind: ty::BorrowKind)
|
||||
_: ty::BorrowKind)
|
||||
-> Result<(),()> {
|
||||
debug!("guarantee_lifetime(cmt={}, loan_region={})",
|
||||
cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
|
||||
@ -38,7 +38,6 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
|
||||
span: span,
|
||||
cause: cause,
|
||||
loan_region: loan_region,
|
||||
loan_kind: loan_kind,
|
||||
cmt_original: cmt.clone()};
|
||||
ctxt.check(&cmt, None)
|
||||
}
|
||||
@ -55,7 +54,6 @@ struct GuaranteeLifetimeContext<'a> {
|
||||
span: Span,
|
||||
cause: euv::LoanCause,
|
||||
loan_region: ty::Region,
|
||||
loan_kind: ty::BorrowKind,
|
||||
cmt_original: mc::cmt
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,6 @@ impl<'a> GatherLoanCtxt<'a> {
|
||||
Loan {
|
||||
index: self.all_loans.len(),
|
||||
loan_path: loan_path,
|
||||
cmt: cmt,
|
||||
kind: req_kind,
|
||||
gen_scope: gen_scope,
|
||||
kill_scope: kill_scope,
|
||||
@ -481,8 +480,7 @@ impl<'a> GatherLoanCtxt<'a> {
|
||||
/// This visitor walks static initializer's expressions and makes
|
||||
/// sure the loans being taken are sound.
|
||||
struct StaticInitializerCtxt<'a> {
|
||||
bccx: &'a BorrowckCtxt<'a>,
|
||||
item_ub: ast::NodeId,
|
||||
bccx: &'a BorrowckCtxt<'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));
|
||||
|
||||
let mut sicx = StaticInitializerCtxt {
|
||||
bccx: bccx,
|
||||
item_ub: expr.id,
|
||||
bccx: bccx
|
||||
};
|
||||
|
||||
sicx.visit_expr(expr, ());
|
||||
|
@ -36,7 +36,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
|
||||
bccx: bccx,
|
||||
span: span,
|
||||
cause: cause,
|
||||
cmt_original: cmt.clone(),
|
||||
loan_region: loan_region,
|
||||
};
|
||||
|
||||
@ -49,7 +48,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
|
||||
struct RestrictionsContext<'a> {
|
||||
bccx: &'a BorrowckCtxt<'a>,
|
||||
span: Span,
|
||||
cmt_original: mc::cmt,
|
||||
loan_region: ty::Region,
|
||||
cause: euv::LoanCause,
|
||||
}
|
||||
|
@ -180,7 +180,6 @@ pub enum PartialTotal {
|
||||
pub struct Loan {
|
||||
index: uint,
|
||||
loan_path: Rc<LoanPath>,
|
||||
cmt: mc::cmt,
|
||||
kind: ty::BorrowKind,
|
||||
restrictions: Vec<Restriction>,
|
||||
gen_scope: ast::NodeId,
|
||||
|
@ -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) {
|
||||
let mut scanned = HashSet::new();
|
||||
while self.worklist.len() > 0 {
|
||||
@ -147,10 +173,22 @@ impl<'a> MarkSymbolVisitor<'a> {
|
||||
match *node {
|
||||
ast_map::NodeItem(item) => {
|
||||
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::ItemTy(..)
|
||||
| ast::ItemEnum(..)
|
||||
| ast::ItemStruct(..)
|
||||
| ast::ItemStatic(..) => {
|
||||
visit::walk_item(self, item, ());
|
||||
}
|
||||
@ -178,18 +216,32 @@ impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
|
||||
ast::ExprMethodCall(..) => {
|
||||
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, ())
|
||||
}
|
||||
|
||||
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, _: ()) {
|
||||
self.lookup_and_handle_definition(&id);
|
||||
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
|
||||
// worklist and recursed into manually if necessary.
|
||||
}
|
||||
@ -317,6 +369,23 @@ struct 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.
|
||||
// ctor_id := `Some` if the item is a struct_ctor (tuple struct),
|
||||
// `None` otherwise.
|
||||
@ -399,6 +468,14 @@ impl<'a> Visitor<()> for DeadVisitor<'a> {
|
||||
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.
|
||||
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
|
||||
match *trait_method {
|
||||
|
@ -226,21 +226,12 @@ fn invalid_node() -> LiveNode { LiveNode(uint::MAX) }
|
||||
|
||||
struct CaptureInfo {
|
||||
ln: LiveNode,
|
||||
is_move: bool,
|
||||
var_nid: NodeId
|
||||
}
|
||||
|
||||
enum LocalKind {
|
||||
FromMatch(BindingMode),
|
||||
FromLetWithInitializer,
|
||||
FromLetNoInitializer
|
||||
}
|
||||
|
||||
struct LocalInfo {
|
||||
id: NodeId,
|
||||
ident: Ident,
|
||||
is_mutbl: bool,
|
||||
kind: LocalKind,
|
||||
ident: Ident
|
||||
}
|
||||
|
||||
enum VarKind {
|
||||
@ -406,23 +397,13 @@ fn visit_fn(ir: &mut IrMaps,
|
||||
}
|
||||
|
||||
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);
|
||||
let name = ast_util::path_to_ident(path);
|
||||
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 {
|
||||
id: p_id,
|
||||
ident: name,
|
||||
is_mutbl: mutbl,
|
||||
kind: kind
|
||||
ident: name
|
||||
}));
|
||||
});
|
||||
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 {:?}",
|
||||
p_id, bm);
|
||||
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_variable(Local(LocalInfo {
|
||||
id: p_id,
|
||||
ident: name,
|
||||
is_mutbl: mutbl,
|
||||
kind: FromMatch(bm)
|
||||
ident: name
|
||||
}));
|
||||
})
|
||||
}
|
||||
@ -481,27 +456,12 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
|
||||
// in better error messages than just pointing at the closure
|
||||
// construction site.
|
||||
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| {
|
||||
for fv in freevars.iter() {
|
||||
match moved_variable_node_id_from_def(fv.def) {
|
||||
Some(rv) => {
|
||||
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,
|
||||
is_move: is_move,
|
||||
var_nid: rv});
|
||||
}
|
||||
None => {}
|
||||
|
@ -353,7 +353,6 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
|
||||
struct PrivacyVisitor<'a> {
|
||||
tcx: &'a ty::ctxt,
|
||||
curitem: ast::NodeId,
|
||||
in_fn: bool,
|
||||
in_foreign: bool,
|
||||
parents: NodeMap<ast::NodeId>,
|
||||
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
|
||||
let mut visitor = PrivacyVisitor {
|
||||
curitem: ast::DUMMY_NODE_ID,
|
||||
in_fn: false,
|
||||
in_foreign: false,
|
||||
tcx: tcx,
|
||||
parents: visitor.parents,
|
||||
|
@ -806,7 +806,6 @@ fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
|
||||
/// The main resolver class.
|
||||
struct Resolver<'a> {
|
||||
session: &'a Session,
|
||||
lang_items: &'a LanguageItems,
|
||||
|
||||
graph_root: NameBindings,
|
||||
|
||||
@ -843,9 +842,6 @@ struct Resolver<'a> {
|
||||
// The idents for the primitive types.
|
||||
primitive_type_table: PrimitiveTypeTable,
|
||||
|
||||
// The four namespaces.
|
||||
namespaces: Vec<Namespace> ,
|
||||
|
||||
def_map: DefMap,
|
||||
export_map2: ExportMap2,
|
||||
trait_map: TraitMap,
|
||||
@ -902,7 +898,7 @@ impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> {
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
graph_root.define_module(NoParentLink,
|
||||
@ -916,7 +912,6 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
Resolver {
|
||||
session: session,
|
||||
lang_items: lang_items,
|
||||
|
||||
// The outermost module has def ID 0; this is not reflected in the
|
||||
// AST.
|
||||
@ -941,8 +936,6 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
primitive_type_table: PrimitiveTypeTable::new(),
|
||||
|
||||
namespaces: vec!(TypeNS, ValueNS),
|
||||
|
||||
def_map: RefCell::new(NodeMap::new()),
|
||||
export_map2: RefCell::new(NodeMap::new()),
|
||||
trait_map: NodeMap::new(),
|
||||
@ -5582,10 +5575,10 @@ pub struct CrateMap {
|
||||
|
||||
/// Entry point to crate resolution.
|
||||
pub fn resolve_crate(session: &Session,
|
||||
lang_items: &LanguageItems,
|
||||
_: &LanguageItems,
|
||||
krate: &Crate)
|
||||
-> CrateMap {
|
||||
let mut resolver = Resolver::new(session, lang_items, krate.span);
|
||||
let mut resolver = Resolver::new(session, krate.span);
|
||||
resolver.resolve(krate);
|
||||
let Resolver { def_map, export_map2, trait_map, last_private,
|
||||
external_exports, .. } = resolver;
|
||||
|
@ -106,7 +106,9 @@ pub fn init_insn_ctxt() {
|
||||
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]
|
||||
impl Drop for _InsnCtxt {
|
||||
@ -124,7 +126,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
|
||||
Some(ctx) => ctx.borrow_mut().push(s),
|
||||
None => {}
|
||||
}
|
||||
_InsnCtxt { _x: () }
|
||||
_InsnCtxt { _cannot_construct_outside_of_this_module: () }
|
||||
}
|
||||
|
||||
pub struct StatRecorder<'a> {
|
||||
|
@ -64,9 +64,6 @@ struct LlvmSignature {
|
||||
// function, because the foreign function may opt to return via an
|
||||
// out pointer.
|
||||
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);
|
||||
LlvmSignature {
|
||||
llarg_tys: llarg_tys,
|
||||
llret_ty: llret_ty,
|
||||
sret: type_of::return_uses_outptr(ccx, fn_sig.output),
|
||||
llret_ty: llret_ty
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,9 +52,7 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
struct UniversalQuantificationResult {
|
||||
monotype: t,
|
||||
type_variables: Vec<ty::t> ,
|
||||
type_param_defs: Rc<Vec<ty::TypeParameterDef> >
|
||||
monotype: t
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
UniversalQuantificationResult {
|
||||
monotype: monotype,
|
||||
type_variables: substitutions.tps,
|
||||
type_param_defs: polytype.generics.type_param_defs.clone()
|
||||
monotype: monotype
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,6 @@ enum ParamKind { TypeParam, RegionParam, SelfParam }
|
||||
struct InferredInfo<'a> {
|
||||
item_id: ast::NodeId,
|
||||
kind: ParamKind,
|
||||
index: uint,
|
||||
param_id: ast::NodeId,
|
||||
term: VarianceTermPtr<'a>,
|
||||
}
|
||||
@ -310,7 +309,6 @@ impl<'a> TermsContext<'a> {
|
||||
let term = self.arena.alloc(|| InferredTerm(inf_index));
|
||||
self.inferred_infos.push(InferredInfo { item_id: item_id,
|
||||
kind: kind,
|
||||
index: index,
|
||||
param_id: param_id,
|
||||
term: term });
|
||||
let newly_added = self.inferred_map.insert(param_id, inf_index);
|
||||
|
@ -42,23 +42,17 @@ pub fn indent<R>(op: || -> R) -> R {
|
||||
r
|
||||
}
|
||||
|
||||
pub struct _indenter {
|
||||
_i: (),
|
||||
pub struct Indenter {
|
||||
_cannot_construct_outside_of_this_module: ()
|
||||
}
|
||||
|
||||
impl Drop for _indenter {
|
||||
impl Drop for Indenter {
|
||||
fn drop(&mut self) { debug!("<<"); }
|
||||
}
|
||||
|
||||
pub fn _indenter(_i: ()) -> _indenter {
|
||||
_indenter {
|
||||
_i: ()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indenter() -> _indenter {
|
||||
pub fn indenter() -> Indenter {
|
||||
debug!(">>");
|
||||
_indenter(())
|
||||
Indenter { _cannot_construct_outside_of_this_module: () }
|
||||
}
|
||||
|
||||
struct LoopQueryVisitor<'a> {
|
||||
|
@ -24,6 +24,7 @@
|
||||
//! // ... something using html
|
||||
//! ```
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use libc;
|
||||
|
@ -298,10 +298,12 @@ mod imp {
|
||||
static _PTHREAD_MUTEX_SIG_init: libc::c_long = 0x32AAABA7;
|
||||
static _PTHREAD_COND_SIG_init: libc::c_long = 0x3CB0B1BB;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t {
|
||||
__sig: libc::c_long,
|
||||
__opaque: [u8, ..__PTHREAD_MUTEX_SIZE__],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_cond_t {
|
||||
__sig: libc::c_long,
|
||||
__opaque: [u8, ..__PTHREAD_COND_SIZE__],
|
||||
@ -339,10 +341,12 @@ mod imp {
|
||||
#[cfg(target_arch = "mips")]
|
||||
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t {
|
||||
__align: libc::c_longlong,
|
||||
size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_cond_t {
|
||||
__align: libc::c_longlong,
|
||||
size: [u8, ..__SIZEOF_PTHREAD_COND_T],
|
||||
@ -361,7 +365,9 @@ mod imp {
|
||||
mod os {
|
||||
use libc;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t { value: libc::c_int }
|
||||
#[repr(C)]
|
||||
pub struct pthread_cond_t { value: libc::c_int }
|
||||
|
||||
pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
|
@ -18,7 +18,6 @@ use std::rt::rtio::{Callback, PausableIdleCallback};
|
||||
pub struct IdleWatcher {
|
||||
handle: *uvll::uv_idle_t,
|
||||
idle_flag: bool,
|
||||
closed: bool,
|
||||
callback: Box<Callback:Send>,
|
||||
}
|
||||
|
||||
@ -31,7 +30,6 @@ impl IdleWatcher {
|
||||
let me = box IdleWatcher {
|
||||
handle: handle,
|
||||
idle_flag: false,
|
||||
closed: false,
|
||||
callback: cb,
|
||||
};
|
||||
return me.install();
|
||||
|
@ -165,7 +165,6 @@ pub struct TcpWatcher {
|
||||
pub struct TcpListener {
|
||||
home: HomeHandle,
|
||||
handle: *uvll::uv_pipe_t,
|
||||
closing_task: Option<BlockedTask>,
|
||||
outgoing: Sender<Result<Box<rtio::RtioTcpStream:Send>, IoError>>,
|
||||
incoming: Receiver<Result<Box<rtio::RtioTcpStream:Send>, IoError>>,
|
||||
}
|
||||
@ -358,7 +357,6 @@ impl TcpListener {
|
||||
let l = box TcpListener {
|
||||
home: io.make_handle(),
|
||||
handle: handle,
|
||||
closing_task: None,
|
||||
outgoing: tx,
|
||||
incoming: rx,
|
||||
};
|
||||
|
@ -136,6 +136,7 @@ pub struct uv_process_options_t {
|
||||
|
||||
// These fields are private because they must be interfaced with through the
|
||||
// functions below.
|
||||
#[repr(C)]
|
||||
pub struct uv_stdio_container_t {
|
||||
flags: libc::c_int,
|
||||
stream: *uv_stream_t,
|
||||
|
@ -393,7 +393,7 @@ mod table {
|
||||
}
|
||||
|
||||
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.
|
||||
pub struct MoveEntries<K, V> {
|
||||
table: RawTable<K, V>,
|
||||
idx: uint,
|
||||
elems_seen: uint,
|
||||
idx: uint
|
||||
}
|
||||
|
||||
impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
|
||||
|
@ -325,6 +325,7 @@ mod imp {
|
||||
#[cfg(target_os = "macos")]
|
||||
fn print(w: &mut Writer, idx: int, addr: *libc::c_void) -> IoResult<()> {
|
||||
use intrinsics;
|
||||
#[repr(C)]
|
||||
struct Dl_info {
|
||||
dli_fname: *libc::c_char,
|
||||
dli_fbase: *libc::c_void,
|
||||
|
@ -84,7 +84,7 @@ pub struct TaskBuilder {
|
||||
/// Options to spawn the new task with
|
||||
pub opts: TaskOpts,
|
||||
gen_body: Option<proc(v: proc():Send):Send -> proc():Send>,
|
||||
nocopy: Option<marker::NoCopy>,
|
||||
nocopy: marker::NoCopy,
|
||||
}
|
||||
|
||||
impl TaskBuilder {
|
||||
@ -94,7 +94,7 @@ impl TaskBuilder {
|
||||
TaskBuilder {
|
||||
opts: TaskOpts::new(),
|
||||
gen_body: None,
|
||||
nocopy: None,
|
||||
nocopy: marker::NoCopy,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,7 @@ pub struct Semaphore {
|
||||
/// dropped, this value will release the resource back to the semaphore.
|
||||
#[must_use]
|
||||
pub struct SemaphoreGuard<'a> {
|
||||
guard: SemGuard<'a, ()>,
|
||||
_guard: SemGuard<'a, ()>,
|
||||
}
|
||||
|
||||
impl Semaphore {
|
||||
@ -375,7 +375,7 @@ impl Semaphore {
|
||||
/// Acquire a resource of this semaphore, returning an RAII guard which will
|
||||
/// release the resource when dropped.
|
||||
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.
|
||||
#[must_use]
|
||||
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
|
||||
/// be used for atomic-unlock-and-deschedule.
|
||||
pub cond: Condvar<'a>,
|
||||
@ -421,7 +421,7 @@ impl Mutex {
|
||||
/// also be accessed through the returned guard.
|
||||
pub fn lock<'a>(&'a self) -> MutexGuard<'a> {
|
||||
let SemCondGuard { guard, cvar } = self.sem.access_cond();
|
||||
MutexGuard { guard: guard, cond: cvar }
|
||||
MutexGuard { _guard: guard, cond: cvar }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1053,6 +1053,15 @@ pub struct StructField_ {
|
||||
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_>;
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
|
@ -21,11 +21,6 @@ use parse::token::special_idents;
|
||||
use parse::token::InternedString;
|
||||
use parse::token;
|
||||
|
||||
pub struct Field {
|
||||
ident: ast::Ident,
|
||||
ex: @ast::Expr
|
||||
}
|
||||
|
||||
// Transitional reexports so qquote can find the paths it is looking for
|
||||
mod syntax {
|
||||
pub use ext;
|
||||
@ -1000,9 +995,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
struct Duplicator<'a> {
|
||||
cx: &'a ExtCtxt<'a>,
|
||||
}
|
||||
struct Duplicator<'a>;
|
||||
|
||||
impl<'a> Folder for Duplicator<'a> {
|
||||
fn new_id(&mut self, _: NodeId) -> NodeId {
|
||||
@ -1021,10 +1014,8 @@ pub trait Duplicate {
|
||||
}
|
||||
|
||||
impl Duplicate for @ast::Expr {
|
||||
fn duplicate(&self, cx: &ExtCtxt) -> @ast::Expr {
|
||||
let mut folder = Duplicator {
|
||||
cx: cx,
|
||||
};
|
||||
fn duplicate(&self, _: &ExtCtxt) -> @ast::Expr {
|
||||
let mut folder = Duplicator;
|
||||
folder.fold_expr(*self)
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ use codemap::{CodeMap, BytePos};
|
||||
use codemap;
|
||||
use diagnostic;
|
||||
use parse::classify::expr_is_simple_block;
|
||||
use parse::token::IdentInterner;
|
||||
use parse::token;
|
||||
use parse::lexer::comments;
|
||||
use parse;
|
||||
@ -30,7 +29,6 @@ use print::pp;
|
||||
use std::io::{IoResult, MemWriter};
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use std::str;
|
||||
use std::string::String;
|
||||
|
||||
@ -58,7 +56,6 @@ pub struct CurrentCommentAndLiteral {
|
||||
pub struct State<'a> {
|
||||
pub s: pp::Printer,
|
||||
cm: Option<&'a CodeMap>,
|
||||
intr: Rc<token::IdentInterner>,
|
||||
comments: Option<Vec<comments::Comment> >,
|
||||
literals: Option<Vec<comments::Literal> >,
|
||||
cur_cmnt_and_lit: CurrentCommentAndLiteral,
|
||||
@ -76,7 +73,6 @@ pub fn rust_printer_annotated<'a>(writer: Box<io::Writer>,
|
||||
State {
|
||||
s: pp::mk_printer(writer, default_columns),
|
||||
cm: None,
|
||||
intr: token::get_ident_interner(),
|
||||
comments: None,
|
||||
literals: None,
|
||||
cur_cmnt_and_lit: CurrentCommentAndLiteral {
|
||||
@ -111,7 +107,6 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
|
||||
let mut s = State {
|
||||
s: pp::mk_printer(out, default_columns),
|
||||
cm: Some(cm),
|
||||
intr: token::get_ident_interner(),
|
||||
comments: Some(cmnts),
|
||||
// If the code is post expansion, don't use the table of
|
||||
// literals, since it doesn't correspond with the literals
|
||||
|
@ -39,7 +39,10 @@ static STATIC_USED_IN_ENUM_DISCRIMINANT: uint = 10;
|
||||
pub type typ = *UsedStruct4;
|
||||
pub struct PubStruct();
|
||||
struct PrivStruct; //~ ERROR: code is never used
|
||||
struct UsedStruct1 { x: int }
|
||||
struct UsedStruct1 {
|
||||
#[allow(dead_code)]
|
||||
x: int
|
||||
}
|
||||
struct UsedStruct2(int);
|
||||
struct UsedStruct3;
|
||||
struct UsedStruct4;
|
||||
@ -53,6 +56,7 @@ struct StructUsedAsField;
|
||||
struct StructUsedInEnum;
|
||||
struct StructUsedInGeneric;
|
||||
pub struct PubStruct2 {
|
||||
#[allow(dead_code)]
|
||||
struct_used_as_field: *StructUsedAsField
|
||||
}
|
||||
|
||||
|
67
src/test/compile-fail/lint-dead-code-4.rs
Normal file
67
src/test/compile-fail/lint-dead-code-4.rs
Normal 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 };
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![feature(managed_boxes)]
|
||||
#![forbid(managed_heap_memory)]
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![forbid(owned_heap_memory)]
|
||||
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![deny(uppercase_variables)]
|
||||
|
||||
use std::io::File;
|
||||
|
Loading…
Reference in New Issue
Block a user