about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-12-08 11:51:22 -0800
committerbors <bors@rust-lang.org>2013-12-08 11:51:22 -0800
commita6310f6ad3434a03d5c257db5eae85b7b7522c29 (patch)
treecc9478fa0b97bafcbf6b7eab427ae0abca4ca87e /src/libsyntax/parse/parser.rs
parentaf6010ca0bfc0abf3f9e184cc33b9821c8453916 (diff)
parent1755408d1a58684b6c9bce11aeceb18a1ec2d66e (diff)
downloadrust-a6310f6ad3434a03d5c257db5eae85b7b7522c29.tar.gz
rust-a6310f6ad3434a03d5c257db5eae85b7b7522c29.zip
auto merge of #10477 : ktt3ja/rust/dead-code, r=alexcrichton
PR for issue #1749 mainly to get some feedback and suggestion. This adds a pass that warns if a function, struct, enum, or static item is never used. For the following code,

```rust
pub static pub_static: int = 0;
static priv_static: int = 0;
static used_static: int = 0;

pub fn pub_fn() { used_fn(); }
fn priv_fn() { let unused_struct = PrivStruct; }
fn used_fn() {}

pub struct PubStruct();
struct PrivStruct();
struct UsedStruct1 { x: int }
struct UsedStruct2(int);
struct UsedStruct3();

pub enum pub_enum { foo1, bar1 }
enum priv_enum { foo2, bar2 }
enum used_enum { foo3, bar3 }

fn foo() {
	bar();
	let unused_enum = foo2;
}

fn bar() {
	foo();
}

fn main() {
	let used_struct1 = UsedStruct1 { x: 1 };
	let used_struct2 = UsedStruct2(1);
	let used_struct3 = UsedStruct3;
	let t = used_static;
	let e = foo3;
}
```

it would add the following warnings:

```rust
/home/ktt3ja/test.rs:2:0: 2:28 warning: code is never used: `priv_static`, #[warn(dead_code)] on by default
/home/ktt3ja/test.rs:2 static priv_static: int = 0;
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ktt3ja/test.rs:6:0: 6:48 warning: code is never used: `priv_fn`, #[warn(dead_code)] on by default
/home/ktt3ja/test.rs:6 fn priv_fn() { let unused_struct = PrivStruct; }
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ktt3ja/test.rs:10:0: 10:20 warning: code is never used: `PrivStruct`, #[warn(dead_code)] on by default
/home/ktt3ja/test.rs:10 struct PrivStruct();
                        ^~~~~~~~~~~~~~~~~~~~
/home/ktt3ja/test.rs:16:0: 16:29 warning: code is never used: `priv_enum`, #[warn(dead_code)] on by default
/home/ktt3ja/test.rs:16 enum priv_enum { foo2, bar2 }
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ktt3ja/test.rs:19:0: 22:1 warning: code is never used: `foo`, #[warn(dead_code)] on by default
/home/ktt3ja/test.rs:19 fn foo() {
/home/ktt3ja/test.rs:20 	bar();
/home/ktt3ja/test.rs:21 	let unused_enum = foo2;
/home/ktt3ja/test.rs:22 }
/home/ktt3ja/test.rs:24:0: 26:1 warning: code is never used: `bar`, #[warn(dead_code)] on by default
/home/ktt3ja/test.rs:24 fn bar() {
/home/ktt3ja/test.rs:25 	foo();
/home/ktt3ja/test.rs:26 }
```

Furthermore, I would like to solicit some test cases since I haven't tested extensively and I'm still unclear about some of the things in here. For example, I'm not sure how reexports would affect this and just assumed that LiveContext (which is a copy of reachable::ReachableContext) does enough work to handle it. Also, the test case above doesn't include any impl or methods, etc.
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs100
1 files changed, 0 insertions, 100 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8c4bf5d87ab..62bfd7c80f9 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -135,13 +135,6 @@ pub enum item_or_view_item {
     iovi_view_item(view_item)
 }
 
-#[deriving(Eq)]
-enum view_item_parse_mode {
-    VIEW_ITEMS_AND_ITEMS_ALLOWED,
-    FOREIGN_ITEMS_ALLOWED,
-    IMPORTS_AND_ITEMS_ALLOWED
-}
-
 /* The expr situation is not as complex as I thought it would be.
 The important thing is to make sure that lookahead doesn't balk
 at INTERPOLATED tokens */
@@ -3455,18 +3448,6 @@ impl Parser {
         })
     }
 
-    fn parse_optional_purity(&self) -> ast::purity {
-        if self.eat_keyword(keywords::Unsafe) {
-            ast::unsafe_fn
-        } else {
-            ast::impure_fn
-        }
-    }
-
-    fn parse_optional_onceness(&self) -> ast::Onceness {
-        if self.eat_keyword(keywords::Once) { ast::Once } else { ast::Many }
-    }
-
     // matches optbounds = ( ( : ( boundseq )? )? )
     // where   boundseq  = ( bound + boundseq ) | bound
     // and     bound     = 'static | ty
@@ -3531,15 +3512,6 @@ impl Parser {
         }
     }
 
-    // parse a generic use site
-    fn parse_generic_values(&self) -> (OptVec<ast::Lifetime>, ~[P<Ty>]) {
-        if !self.eat(&token::LT) {
-            (opt_vec::Empty, ~[])
-        } else {
-            self.parse_generic_values_after_lt()
-        }
-    }
-
     fn parse_generic_values_after_lt(&self) -> (OptVec<ast::Lifetime>, ~[P<Ty>]) {
         let lifetimes = self.parse_lifetimes();
         let result = self.parse_seq_to_gt(
@@ -4080,13 +4052,6 @@ impl Parser {
          None)
     }
 
-    fn token_is_pound_or_doc_comment(&self, tok: token::Token) -> bool {
-        match tok {
-            token::POUND | token::DOC_COMMENT(_) => true,
-            _ => false
-        }
-    }
-
     // parse a structure field declaration
     pub fn parse_single_struct_field(&self,
                                      vis: visibility,
@@ -4556,26 +4521,6 @@ impl Parser {
         (id, item_enum(enum_definition, generics), None)
     }
 
-    fn parse_fn_ty_sigil(&self) -> Option<Sigil> {
-        match *self.token {
-            token::AT => {
-                self.bump();
-                Some(ManagedSigil)
-            }
-            token::TILDE => {
-                self.bump();
-                Some(OwnedSigil)
-            }
-            token::BINOP(token::AND) => {
-                self.bump();
-                Some(BorrowedSigil)
-            }
-            _ => {
-                None
-            }
-        }
-    }
-
     fn fn_expr_lookahead(&self, tok: &token::Token) -> bool {
         match *tok {
           token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true,
@@ -4983,51 +4928,6 @@ impl Parser {
         return vp;
     }
 
-    fn is_view_item(&self) -> bool {
-        if !self.is_keyword(keywords::Pub) && !self.is_keyword(keywords::Priv) {
-            token::is_keyword(keywords::Use, self.token)
-                || (token::is_keyword(keywords::Extern, self.token) &&
-                    self.look_ahead(1,
-                                    |t| token::is_keyword(keywords::Mod, t)))
-        } else {
-            self.look_ahead(1, |t| token::is_keyword(keywords::Use, t))
-                || (self.look_ahead(1,
-                                    |t| token::is_keyword(keywords::Extern,
-                                                          t)) &&
-                    self.look_ahead(2,
-                                    |t| token::is_keyword(keywords::Mod, t)))
-        }
-    }
-
-    // parse a view item.
-    fn parse_view_item(
-        &self,
-        attrs: ~[Attribute],
-        vis: visibility
-    ) -> view_item {
-        let lo = self.span.lo;
-        let node = if self.eat_keyword(keywords::Use) {
-            self.parse_use()
-        } else if self.eat_keyword(keywords::Extern) {
-            self.expect_keyword(keywords::Mod);
-            let ident = self.parse_ident();
-            let path = if *self.token == token::EQ {
-                self.bump();
-                Some(self.parse_str())
-            }
-            else { None };
-            let metadata = self.parse_optional_meta();
-            view_item_extern_mod(ident, path, metadata, ast::DUMMY_NODE_ID)
-        } else {
-            self.bug("expected view item");
-        };
-        self.expect(&token::SEMI);
-        ast::view_item { node: node,
-                          attrs: attrs,
-                          vis: vis,
-                          span: mk_sp(lo, self.last_span.hi) }
-    }
-
     // Parses a sequence of items. Stops when it finds program
     // text that can't be parsed as an item
     // - mod_items uses extern_mod_allowed = true