auto merge of #10870 : ktt3ja/rust/issue-10865, r=alexcrichton
Fix #10865 and #10939.
This commit is contained in:
commit
3d3a663d25
7 changed files with 97 additions and 48 deletions
|
|
@ -41,11 +41,15 @@ stage2_tests.sort()
|
|||
|
||||
c = open("tmp/run_pass_stage2.rc", "w")
|
||||
i = 0
|
||||
c.write("// AUTO-GENERATED FILE: DO NOT EDIT\n")
|
||||
c.write("#[pkgid=\"run_pass_stage2#0.1\"];\n")
|
||||
c.write("#[link(name=\"run_pass_stage2\", vers=\"0.1\")];\n")
|
||||
c.write("#[feature(globs, macro_rules, struct_variant, managed_boxes)];\n")
|
||||
c.write("#[allow(attribute_usage)];\n")
|
||||
c.write(
|
||||
"""
|
||||
// AUTO-GENERATED FILE: DO NOT EDIT
|
||||
#[pkgid=\"run_pass_stage2#0.1\"];
|
||||
#[link(name=\"run_pass_stage2\", vers=\"0.1\")];
|
||||
#[feature(globs, macro_rules, struct_variant, managed_boxes)];
|
||||
#[allow(warnings)];
|
||||
"""
|
||||
)
|
||||
for t in stage2_tests:
|
||||
p = os.path.join(run_pass, t)
|
||||
p = p.replace("\\", "\\\\")
|
||||
|
|
@ -56,15 +60,19 @@ c.close()
|
|||
|
||||
|
||||
d = open("tmp/run_pass_stage2_driver.rs", "w")
|
||||
d.write("// AUTO-GENERATED FILE: DO NOT EDIT\n")
|
||||
d.write("#[feature(globs, managed_boxes)];\n")
|
||||
d.write("extern mod extra;\n")
|
||||
d.write("extern mod run_pass_stage2;\n")
|
||||
d.write("use run_pass_stage2::*;\n")
|
||||
d.write("use std::io;\n")
|
||||
d.write("use std::io::Writer;\n")
|
||||
d.write("fn main() {\n")
|
||||
d.write(" let mut out = io::stdout();\n")
|
||||
d.write(
|
||||
"""
|
||||
// AUTO-GENERATED FILE: DO NOT EDIT
|
||||
#[feature(globs, managed_boxes)];
|
||||
extern mod extra;
|
||||
extern mod run_pass_stage2;
|
||||
use run_pass_stage2::*;
|
||||
use std::io;
|
||||
use std::io::Writer;
|
||||
fn main() {
|
||||
let mut out = io::stdout();
|
||||
"""
|
||||
)
|
||||
i = 0
|
||||
for t in stage2_tests:
|
||||
p = os.path.join("test", "run-pass", t)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ fn should_explore(tcx: ty::ctxt, def_id: ast::DefId) -> bool {
|
|||
match tcx.items.find(&def_id.node) {
|
||||
Some(&ast_map::node_item(..))
|
||||
| Some(&ast_map::node_method(..))
|
||||
| Some(&ast_map::node_foreign_item(..))
|
||||
| Some(&ast_map::node_trait_method(..)) => true,
|
||||
_ => false
|
||||
}
|
||||
|
|
@ -61,11 +62,10 @@ impl MarkSymbolVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
fn lookup_and_handle_definition(&mut self, id: &ast::NodeId,
|
||||
span: codemap::Span) {
|
||||
fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
|
||||
let def = match self.tcx.def_map.find(id) {
|
||||
Some(&def) => def,
|
||||
None => self.tcx.sess.span_bug(span, "def ID not in def map?!"),
|
||||
None => return
|
||||
};
|
||||
let def_id = match def {
|
||||
ast::DefVariant(enum_id, _, _) => Some(enum_id),
|
||||
|
|
@ -107,8 +107,7 @@ impl MarkSymbolVisitor {
|
|||
match item.node {
|
||||
ast::item_fn(..)
|
||||
| ast::item_ty(..)
|
||||
| ast::item_static(..)
|
||||
| ast::item_foreign_mod(_) => {
|
||||
| ast::item_static(..) => {
|
||||
visit::walk_item(self, item, ());
|
||||
}
|
||||
_ => ()
|
||||
|
|
@ -120,6 +119,9 @@ impl MarkSymbolVisitor {
|
|||
ast_map::node_method(method, _, _) => {
|
||||
visit::walk_block(self, method.body, ());
|
||||
}
|
||||
ast_map::node_foreign_item(foreign_item, _, _, _) => {
|
||||
visit::walk_foreign_item(self, foreign_item, ());
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
|
@ -129,9 +131,6 @@ impl Visitor<()> for MarkSymbolVisitor {
|
|||
|
||||
fn visit_expr(&mut self, expr: @ast::Expr, _: ()) {
|
||||
match expr.node {
|
||||
ast::ExprPath(_) | ast::ExprStruct(..) => {
|
||||
self.lookup_and_handle_definition(&expr.id, expr.span);
|
||||
}
|
||||
ast::ExprMethodCall(..) => {
|
||||
match self.method_map.find(&expr.id) {
|
||||
Some(&typeck::method_map_entry {
|
||||
|
|
@ -160,12 +159,16 @@ impl Visitor<()> for MarkSymbolVisitor {
|
|||
fn visit_ty(&mut self, typ: &ast::Ty, _: ()) {
|
||||
match typ.node {
|
||||
ast::ty_path(_, _, ref id) => {
|
||||
self.lookup_and_handle_definition(id, typ.span);
|
||||
self.lookup_and_handle_definition(id);
|
||||
}
|
||||
_ => visit::walk_ty(self, typ, ()),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, _: &ast::Path, id: ast::NodeId, _: ()) {
|
||||
self.lookup_and_handle_definition(&id);
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, _item: @ast::item, _: ()) {
|
||||
// Do not recurse into items. These items will be added to the
|
||||
// worklist and recursed into manually if necessary.
|
||||
|
|
@ -299,19 +302,31 @@ impl DeadVisitor {
|
|||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn warn_dead_code(&mut self, id: ast::NodeId,
|
||||
span: codemap::Span, ident: &ast::Ident) {
|
||||
self.tcx.sess.add_lint(dead_code, id, span,
|
||||
format!("code is never used: `{}`",
|
||||
token::ident_to_str(ident)));
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor<()> for DeadVisitor {
|
||||
fn visit_item(&mut self, item: @ast::item, _: ()) {
|
||||
let ctor_id = get_struct_ctor_id(item);
|
||||
if !self.symbol_is_live(item.id, ctor_id) && should_warn(item) {
|
||||
self.tcx.sess.add_lint(dead_code, item.id, item.span,
|
||||
format!("code is never used: `{}`",
|
||||
token::ident_to_str(&item.ident)));
|
||||
self.warn_dead_code(item.id, item.span, &item.ident);
|
||||
}
|
||||
visit::walk_item(self, item, ());
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, fi: @ast::foreign_item, _: ()) {
|
||||
if !self.symbol_is_live(fi.id, None) {
|
||||
self.warn_dead_code(fi.id, fi.span, &fi.ident);
|
||||
}
|
||||
visit::walk_foreign_item(self, fi, ());
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: &visit::fn_kind,
|
||||
_: &ast::fn_decl, block: ast::P<ast::Block>,
|
||||
span: codemap::Span, id: ast::NodeId, _: ()) {
|
||||
|
|
@ -320,10 +335,7 @@ impl Visitor<()> for DeadVisitor {
|
|||
visit::fk_method(..) => {
|
||||
let ident = visit::name_of_fn(fk);
|
||||
if !self.symbol_is_live(id, None) {
|
||||
self.tcx.sess
|
||||
.add_lint(dead_code, id, span,
|
||||
format!("code is never used: `{}`",
|
||||
token::ident_to_str(&ident)));
|
||||
self.warn_dead_code(id, span, &ident);
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
|
|
|
|||
|
|
@ -29,12 +29,15 @@
|
|||
|
||||
#[allow(non_camel_case_types)]; // C types
|
||||
|
||||
use std::libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t, c_double};
|
||||
use std::libc::{size_t, c_int, c_uint, c_void, c_char, c_double};
|
||||
use std::libc::ssize_t;
|
||||
use std::libc::{malloc, free};
|
||||
use std::libc;
|
||||
use std::vec;
|
||||
|
||||
#[cfg(test)]
|
||||
use std::libc::uintptr_t;
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
pub static OK: c_int = 0;
|
||||
|
|
@ -541,7 +544,9 @@ extern {
|
|||
pub fn rust_is_ipv4_sockaddr(addr: *sockaddr) -> c_int;
|
||||
pub fn rust_is_ipv6_sockaddr(addr: *sockaddr) -> c_int;
|
||||
|
||||
#[cfg(test)]
|
||||
fn rust_uv_handle_type_max() -> uintptr_t;
|
||||
#[cfg(test)]
|
||||
fn rust_uv_req_type_max() -> uintptr_t;
|
||||
fn rust_uv_get_udp_handle_from_send_req(req: *uv_udp_send_t) -> *uv_udp_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
#[allow(non_uppercase_statics)];
|
||||
#[allow(dead_code)];
|
||||
|
||||
// function names are almost identical to C's libmath, a few have been
|
||||
// renamed, grep for "rename:"
|
||||
|
|
|
|||
|
|
@ -26,20 +26,7 @@ pub static pub_static: int = 0;
|
|||
static priv_static: int = 0; //~ ERROR: code is never used
|
||||
static used_static: int = 0;
|
||||
pub static used_static2: int = used_static;
|
||||
|
||||
pub fn pub_fn() {
|
||||
used_fn();
|
||||
let used_struct1 = UsedStruct1 { x: 1 };
|
||||
let used_struct2 = UsedStruct2(1);
|
||||
let used_struct3 = UsedStruct3;
|
||||
let e = foo3;
|
||||
SemiUsedStruct::la_la_la();
|
||||
|
||||
}
|
||||
fn priv_fn() { //~ ERROR: code is never used
|
||||
let unused_struct = PrivStruct;
|
||||
}
|
||||
fn used_fn() {}
|
||||
static USED_STATIC: int = 0;
|
||||
|
||||
pub type typ = ~UsedStruct4;
|
||||
pub struct PubStruct();
|
||||
|
|
@ -59,6 +46,25 @@ pub enum pub_enum { foo1, bar1 }
|
|||
enum priv_enum { foo2, bar2 } //~ ERROR: code is never used
|
||||
enum used_enum { foo3, bar3 }
|
||||
|
||||
pub fn pub_fn() {
|
||||
used_fn();
|
||||
let used_struct1 = UsedStruct1 { x: 1 };
|
||||
let used_struct2 = UsedStruct2(1);
|
||||
let used_struct3 = UsedStruct3;
|
||||
let e = foo3;
|
||||
SemiUsedStruct::la_la_la();
|
||||
|
||||
let i = 1;
|
||||
match i {
|
||||
USED_STATIC => (),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
fn priv_fn() { //~ ERROR: code is never used
|
||||
let unused_struct = PrivStruct;
|
||||
}
|
||||
fn used_fn() {}
|
||||
|
||||
fn foo() { //~ ERROR: code is never used
|
||||
bar();
|
||||
let unused_enum = foo2;
|
||||
|
|
|
|||
|
|
@ -40,11 +40,27 @@ fn bar2() {
|
|||
pub fn pub_fn() {
|
||||
let foo2_struct = Foo2;
|
||||
foo2_struct.foo2();
|
||||
|
||||
blah::baz();
|
||||
}
|
||||
|
||||
// not warned because it's used in the parameter of `free` below
|
||||
enum c_void {}
|
||||
mod blah {
|
||||
use std::libc::size_t;
|
||||
// not warned because it's used in the parameter of `free` and return of
|
||||
// `malloc` below, which are also used.
|
||||
enum c_void {}
|
||||
|
||||
extern {
|
||||
fn free(p: *c_void);
|
||||
fn malloc(size: size_t) -> *c_void;
|
||||
}
|
||||
|
||||
pub fn baz() {
|
||||
unsafe { free(malloc(4)); }
|
||||
}
|
||||
}
|
||||
|
||||
enum c_void {} //~ ERROR: code is never used
|
||||
extern {
|
||||
fn free(p: *c_void);
|
||||
fn free(p: *c_void); //~ ERROR: code is never used
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
#[forbid(ctypes)];
|
||||
#[allow(dead_code)];
|
||||
|
||||
mod xx {
|
||||
extern {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue