From 2ec795b4f030ec19cf2ddc48fe5e2e158d5c0e42 Mon Sep 17 00:00:00 2001
From: Jakub Wieczorek <jakub@jakub.cc>
Date: Sat, 20 Sep 2014 13:26:10 +0200
Subject: [PATCH 1/4] Add detection of unused enum variants

---
 src/librustc/middle/dead.rs               | 98 ++++++++++++++---------
 src/test/compile-fail/lint-dead-code-1.rs |  6 +-
 src/test/compile-fail/lint-dead-code-4.rs |  4 +-
 src/test/compile-fail/lint-dead-code-5.rs | 41 ++++++++++
 4 files changed, 110 insertions(+), 39 deletions(-)
 create mode 100644 src/test/compile-fail/lint-dead-code-5.rs

diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 345b8c88372..7110c5f5720 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -13,21 +13,20 @@
 // from live codes are live, and everything else is dead.
 
 use middle::def;
-use lint;
+use middle::pat_util;
 use middle::privacy;
 use middle::ty;
 use middle::typeck;
+use lint;
 use util::nodemap::NodeSet;
 
 use std::collections::HashSet;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util::{local_def, is_local, PostExpansionMethod};
-use syntax::attr::AttrMetaMethods;
-use syntax::attr;
+use syntax::attr::{mod, AttrMetaMethods};
 use syntax::codemap;
-use syntax::visit::Visitor;
-use syntax::visit;
+use syntax::visit::{mod, Visitor};
 
 // Any local node that may call something in its body block should be
 // explored. For example, if it's a live NodeItem that is a
@@ -51,7 +50,8 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     worklist: Vec<ast::NodeId>,
     tcx: &'a ty::ctxt<'tcx>,
     live_symbols: Box<HashSet<ast::NodeId>>,
-    struct_has_extern_repr: bool
+    struct_has_extern_repr: bool,
+    ignore_paths: bool
 }
 
 impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
@@ -61,7 +61,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
             worklist: worklist,
             tcx: tcx,
             live_symbols: box HashSet::new(),
-            struct_has_extern_repr: false
+            struct_has_extern_repr: false,
+            ignore_paths: false
         }
     }
 
@@ -73,19 +74,18 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
     }
 
     fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
-        let def = match self.tcx.def_map.borrow().find(id) {
-            Some(&def) => def,
-            None => return
-        };
-        let def_id = match def {
-            def::DefVariant(enum_id, _, _) => Some(enum_id),
-            def::DefPrimTy(_) => None,
-            _ => Some(def.def_id())
-        };
-        match def_id {
-            Some(def_id) => self.check_def_id(def_id),
-            None => (),
-        }
+        self.tcx.def_map.borrow().find(id).map(|def| {
+            match def {
+                &def::DefPrimTy(_) => (),
+                &def::DefVariant(enum_id, variant_id, _) => {
+                    self.check_def_id(enum_id);
+                    self.check_def_id(variant_id);
+                }
+                _ => {
+                    self.check_def_id(def.def_id());
+                }
+            }
+        });
     }
 
     fn lookup_and_handle_method(&mut self, id: ast::NodeId,
@@ -275,22 +275,27 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
     }
 
     fn visit_pat(&mut self, pat: &ast::Pat) {
+        let def_map = &self.tcx.def_map;
         match pat.node {
             ast::PatStruct(_, ref fields, _) => {
                 self.handle_field_pattern_match(pat, fields.as_slice());
             }
-            ast::PatIdent(_, _, _) => {
+            _ if pat_util::pat_is_const(def_map, pat) => {
                 // it might be the only use of a static:
                 self.lookup_and_handle_definition(&pat.id)
             }
             _ => ()
         }
 
+        self.ignore_paths = true;
         visit::walk_pat(self, pat);
+        self.ignore_paths = false;
     }
 
     fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
-        self.lookup_and_handle_definition(&id);
+        if !self.ignore_paths {
+            self.lookup_and_handle_definition(&id);
+        }
         visit::walk_path(self, path);
     }
 
@@ -330,15 +335,19 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
 //   2) We are not sure to be live or not
 //     * Implementation of a trait method
 struct LifeSeeder {
-    worklist: Vec<ast::NodeId> ,
+    worklist: Vec<ast::NodeId>
 }
 
 impl<'v> Visitor<'v> for LifeSeeder {
     fn visit_item(&mut self, item: &ast::Item) {
-        if has_allow_dead_code_or_lang_attr(item.attrs.as_slice()) {
+        let allow_dead_code = has_allow_dead_code_or_lang_attr(item.attrs.as_slice());
+        if allow_dead_code {
             self.worklist.push(item.id);
         }
         match item.node {
+            ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
+                self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
+            }
             ast::ItemImpl(_, Some(ref _trait_ref), _, ref impl_items) => {
                 for impl_item in impl_items.iter() {
                     match *impl_item {
@@ -415,16 +424,6 @@ fn find_live(tcx: &ty::ctxt,
     symbol_visitor.live_symbols
 }
 
-fn should_warn(item: &ast::Item) -> bool {
-    match item.node {
-        ast::ItemStatic(..)
-        | ast::ItemFn(..)
-        | ast::ItemEnum(..)
-        | ast::ItemStruct(..) => true,
-        _ => false
-    }
-}
-
 fn get_struct_ctor_id(item: &ast::Item) -> Option<ast::NodeId> {
     match item.node {
         ast::ItemStruct(ref struct_def, _) => struct_def.ctor_id,
@@ -438,6 +437,18 @@ struct DeadVisitor<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
+    fn should_warn_about_item(&mut self, item: &ast::Item) -> bool {
+        let should_warn = match item.node {
+            ast::ItemStatic(..)
+            | ast::ItemFn(..)
+            | ast::ItemEnum(..)
+            | ast::ItemStruct(..) => true,
+            _ => false
+        };
+        let ctor_id = get_struct_ctor_id(item);
+        should_warn && !self.symbol_is_live(item.id, ctor_id)
+    }
+
     fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
         let is_named = node.ident().is_some();
         let field_type = ty::node_id_to_type(self.tcx, node.id);
@@ -451,6 +462,11 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
             && !has_allow_dead_code_or_lang_attr(node.attrs.as_slice())
     }
 
+    fn should_warn_about_variant(&mut self, variant: &ast::Variant_) -> bool {
+        !self.symbol_is_live(variant.id, None)
+            && !has_allow_dead_code_or_lang_attr(variant.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.
@@ -506,9 +522,19 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
 
 impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
     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) {
+        if self.should_warn_about_item(item) {
             self.warn_dead_code(item.id, item.span, item.ident);
+        } else {
+            match item.node {
+                ast::ItemEnum(ref enum_def, _) => {
+                    for variant in enum_def.variants.iter() {
+                        if self.should_warn_about_variant(&variant.node) {
+                            self.warn_dead_code(variant.node.id, variant.span, variant.node.name);
+                        }
+                    }
+                },
+                _ => ()
+            }
         }
         visit::walk_item(self, item);
     }
diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs
index a2d2c02dc43..8c40ea2afe2 100644
--- a/src/test/compile-fail/lint-dead-code-1.rs
+++ b/src/test/compile-fail/lint-dead-code-1.rs
@@ -63,8 +63,12 @@ pub struct PubStruct2 {
 pub enum pub_enum { foo1, bar1 }
 pub enum pub_enum2 { a(*const StructUsedInEnum) }
 pub enum pub_enum3 { Foo = STATIC_USED_IN_ENUM_DISCRIMINANT }
+
 enum priv_enum { foo2, bar2 } //~ ERROR: code is never used
-enum used_enum { foo3, bar3 }
+enum used_enum {
+    foo3,
+    bar3 //~ ERROR code is never used
+}
 
 fn f<T>() {}
 
diff --git a/src/test/compile-fail/lint-dead-code-4.rs b/src/test/compile-fail/lint-dead-code-4.rs
index 718af1841b6..826faad32c9 100644
--- a/src/test/compile-fail/lint-dead-code-4.rs
+++ b/src/test/compile-fail/lint-dead-code-4.rs
@@ -28,8 +28,8 @@ fn field_read(f: Foo) -> uint {
 }
 
 enum XYZ {
-    X,
-    Y {
+    X, //~ ERROR variant is never used
+    Y { //~ ERROR variant is never used
         a: String,
         b: int //~ ERROR: code is never used
     },
diff --git a/src/test/compile-fail/lint-dead-code-5.rs b/src/test/compile-fail/lint-dead-code-5.rs
new file mode 100644
index 00000000000..c26ae1a7023
--- /dev/null
+++ b/src/test/compile-fail/lint-dead-code-5.rs
@@ -0,0 +1,41 @@
+// Copyright 2014 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)]
+#![deny(dead_code)]
+
+enum Enum1 {
+    Variant1(int),
+    Variant2 //~ ERROR: code is never used
+}
+
+enum Enum2 {
+    Variant3(bool),
+    #[allow(dead_code)]
+    Variant4(int),
+    Variant5 { _x: int }, //~ ERROR: variant is never used: `Variant5`
+    Variant6(int), //~ ERROR: variant is never used: `Variant6`
+    _Variant7,
+}
+
+enum Enum3 { //~ ERROR: enum is never used
+    Variant8,
+    Variant9
+}
+
+fn main() {
+    let v = Variant1(1);
+    match v {
+        Variant1(_) => (),
+        Variant2 => ()
+    }
+    let x = Variant3(true);
+}

From 3530e4a6471b6948c719f709bc10923c3f5524a5 Mon Sep 17 00:00:00 2001
From: Jakub Wieczorek <jakub@jakub.cc>
Date: Sat, 20 Sep 2014 14:08:10 +0200
Subject: [PATCH 2/4] Use more descriptive names in dead code messages

---
 src/librustc/middle/dead.rs                   | 17 +++++++------
 src/libsyntax/ast.rs                          | 25 +++++++++++++++++++
 .../syntax-extension-regex-unused-static.rs   |  2 +-
 .../compile-fail/fail-no-dead-code-core.rs    |  2 +-
 src/test/compile-fail/fail-no-dead-code.rs    |  2 +-
 src/test/compile-fail/lint-dead-code-1.rs     | 16 ++++++------
 src/test/compile-fail/lint-dead-code-2.rs     |  6 ++---
 src/test/compile-fail/lint-dead-code-3.rs     | 12 ++++-----
 src/test/compile-fail/lint-dead-code-4.rs     |  6 ++---
 src/test/compile-fail/lint-dead-code-5.rs     |  2 +-
 10 files changed, 59 insertions(+), 31 deletions(-)

diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 7110c5f5720..1b2f62a9385 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -507,7 +507,8 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
     fn warn_dead_code(&mut self,
                       id: ast::NodeId,
                       span: codemap::Span,
-                      ident: ast::Ident) {
+                      ident: ast::Ident,
+                      node_type: &str) {
         let name = ident.as_str();
         if !name.starts_with("_") {
             self.tcx
@@ -515,7 +516,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
                 .add_lint(lint::builtin::DEAD_CODE,
                           id,
                           span,
-                          format!("code is never used: `{}`", name));
+                          format!("{} is never used: `{}`", node_type, name));
         }
     }
 }
@@ -523,13 +524,14 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
 impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &ast::Item) {
         if self.should_warn_about_item(item) {
-            self.warn_dead_code(item.id, item.span, item.ident);
+            self.warn_dead_code(item.id, item.span, item.ident, item.node.descriptive_variant());
         } else {
             match item.node {
                 ast::ItemEnum(ref enum_def, _) => {
                     for variant in enum_def.variants.iter() {
                         if self.should_warn_about_variant(&variant.node) {
-                            self.warn_dead_code(variant.node.id, variant.span, variant.node.name);
+                            self.warn_dead_code(variant.node.id, variant.span,
+                                                variant.node.name, "variant");
                         }
                     }
                 },
@@ -541,7 +543,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
 
     fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
         if !self.symbol_is_live(fi.id, None) {
-            self.warn_dead_code(fi.id, fi.span, fi.ident);
+            self.warn_dead_code(fi.id, fi.span, fi.ident, fi.node.descriptive_variant());
         }
         visit::walk_foreign_item(self, fi);
     }
@@ -553,7 +555,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
         match fk {
             visit::FkMethod(name, _, _) => {
                 if !self.symbol_is_live(id, None) {
-                    self.warn_dead_code(id, span, name);
+                    self.warn_dead_code(id, span, name, "method");
                 }
             }
             _ => ()
@@ -563,7 +565,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
 
     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());
+            self.warn_dead_code(field.node.id, field.span,
+                                field.node.ident().unwrap(), "struct field");
         }
 
         visit::walk_struct_field(self, field);
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 74c69762be1..38d8136c1a1 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1323,6 +1323,22 @@ pub enum Item_ {
     ItemMac(Mac),
 }
 
+impl Item_ {
+    pub fn descriptive_variant(&self) -> &str {
+        match *self {
+            ItemStatic(..) => "static item",
+            ItemFn(..) => "function",
+            ItemMod(..) => "module",
+            ItemForeignMod(..) => "foreign module",
+            ItemTy(..) => "type alias",
+            ItemEnum(..) => "enum",
+            ItemStruct(..) => "struct",
+            ItemTrait(..) => "trait",
+            _ => "item"
+        }
+    }
+}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct ForeignItem {
     pub ident: Ident,
@@ -1339,6 +1355,15 @@ pub enum ForeignItem_ {
     ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
 }
 
+impl ForeignItem_ {
+    pub fn descriptive_variant(&self) -> &str {
+        match *self {
+            ForeignItemFn(..) => "foreign function",
+            ForeignItemStatic(..) => "foreign static item"
+        }
+    }
+}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum UnboxedClosureKind {
     FnUnboxedClosureKind,
diff --git a/src/test/compile-fail-fulldeps/syntax-extension-regex-unused-static.rs b/src/test/compile-fail-fulldeps/syntax-extension-regex-unused-static.rs
index d7135bc5c91..095acf56e48 100644
--- a/src/test/compile-fail-fulldeps/syntax-extension-regex-unused-static.rs
+++ b/src/test/compile-fail-fulldeps/syntax-extension-regex-unused-static.rs
@@ -26,5 +26,5 @@ extern crate regex;
 // unused variable warning).
 
 fn main() {
-    static fubar: regex::Regex = regex!("abc"); //~ ERROR code is never used: `fubar`
+    static fubar: regex::Regex = regex!("abc"); //~ ERROR static item is never used: `fubar`
 }
diff --git a/src/test/compile-fail/fail-no-dead-code-core.rs b/src/test/compile-fail/fail-no-dead-code-core.rs
index b2b04edc787..58ecdec538e 100644
--- a/src/test/compile-fail/fail-no-dead-code-core.rs
+++ b/src/test/compile-fail/fail-no-dead-code-core.rs
@@ -15,7 +15,7 @@
 #[phase(link, plugin)] extern crate core;
 
 
-fn foo() { //~ ERROR code is never used
+fn foo() { //~ ERROR function is never used
 
     // none of these should have any dead_code exposed to the user
     fail!();
diff --git a/src/test/compile-fail/fail-no-dead-code.rs b/src/test/compile-fail/fail-no-dead-code.rs
index da59722c3ff..897710609fd 100644
--- a/src/test/compile-fail/fail-no-dead-code.rs
+++ b/src/test/compile-fail/fail-no-dead-code.rs
@@ -11,7 +11,7 @@
 #![deny(dead_code)]
 #![allow(unreachable_code)]
 
-fn foo() { //~ ERROR code is never used
+fn foo() { //~ ERROR function is never used
 
     // none of these should have any dead_code exposed to the user
     fail!();
diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs
index 8c40ea2afe2..3e563e9e138 100644
--- a/src/test/compile-fail/lint-dead-code-1.rs
+++ b/src/test/compile-fail/lint-dead-code-1.rs
@@ -22,7 +22,7 @@ pub use foo2::Bar2;
 pub trait Sized {}
 
 mod foo {
-    pub struct Bar; //~ ERROR: code is never used
+    pub struct Bar; //~ ERROR: struct is never used
 }
 
 mod foo2 {
@@ -30,7 +30,7 @@ mod foo2 {
 }
 
 pub static pub_static: int = 0;
-static priv_static: int = 0; //~ ERROR: code is never used
+static priv_static: int = 0; //~ ERROR: static item is never used
 static used_static: int = 0;
 pub static used_static2: int = used_static;
 static USED_STATIC: int = 0;
@@ -38,7 +38,7 @@ static STATIC_USED_IN_ENUM_DISCRIMINANT: int = 10;
 
 pub type typ = *const UsedStruct4;
 pub struct PubStruct;
-struct PrivStruct; //~ ERROR: code is never used
+struct PrivStruct; //~ ERROR: struct is never used
 struct UsedStruct1 {
     #[allow(dead_code)]
     x: int
@@ -64,10 +64,10 @@ pub enum pub_enum { foo1, bar1 }
 pub enum pub_enum2 { a(*const StructUsedInEnum) }
 pub enum pub_enum3 { Foo = STATIC_USED_IN_ENUM_DISCRIMINANT }
 
-enum priv_enum { foo2, bar2 } //~ ERROR: code is never used
+enum priv_enum { foo2, bar2 } //~ ERROR: enum is never used
 enum used_enum {
     foo3,
-    bar3 //~ ERROR code is never used
+    bar3 //~ ERROR variant is never used
 }
 
 fn f<T>() {}
@@ -87,17 +87,17 @@ pub fn pub_fn() {
     }
     f::<StructUsedInGeneric>();
 }
-fn priv_fn() { //~ ERROR: code is never used
+fn priv_fn() { //~ ERROR: function is never used
     let unused_struct = PrivStruct;
 }
 fn used_fn() {}
 
-fn foo() { //~ ERROR: code is never used
+fn foo() { //~ ERROR: function is never used
     bar();
     let unused_enum = foo2;
 }
 
-fn bar() { //~ ERROR: code is never used
+fn bar() { //~ ERROR: function is never used
     foo();
 }
 
diff --git a/src/test/compile-fail/lint-dead-code-2.rs b/src/test/compile-fail/lint-dead-code-2.rs
index 4ad56ce9154..eb284c4d054 100644
--- a/src/test/compile-fail/lint-dead-code-2.rs
+++ b/src/test/compile-fail/lint-dead-code-2.rs
@@ -28,10 +28,10 @@ impl Bar for Foo {
 
 fn live_fn() {}
 
-fn dead_fn() {} //~ ERROR: code is never used
+fn dead_fn() {} //~ ERROR: function is never used
 
 #[main]
-fn dead_fn2() {} //~ ERROR: code is never used
+fn dead_fn2() {} //~ ERROR: function is never used
 
 fn used_fn() {}
 
@@ -44,7 +44,7 @@ fn start(_: int, _: *const *const u8) -> int {
 }
 
 // this is not main
-fn main() { //~ ERROR: code is never used
+fn main() { //~ ERROR: function is never used
     dead_fn();
     dead_fn2();
 }
diff --git a/src/test/compile-fail/lint-dead-code-3.rs b/src/test/compile-fail/lint-dead-code-3.rs
index 41e6f24d79c..f73c19b5fc9 100644
--- a/src/test/compile-fail/lint-dead-code-3.rs
+++ b/src/test/compile-fail/lint-dead-code-3.rs
@@ -21,15 +21,15 @@ extern {
     fn extern_foo();
 }
 
-struct Foo; //~ ERROR: code is never used
+struct Foo; //~ ERROR: struct is never used
 impl Foo {
-    fn foo(&self) { //~ ERROR: code is never used
+    fn foo(&self) { //~ ERROR: method is never used
         bar()
     }
 }
 
-fn bar() { //~ ERROR: code is never used
-    fn baz() {} //~ ERROR: code is never used
+fn bar() { //~ ERROR: function is never used
+    fn baz() {} //~ ERROR: function is never used
 
     Foo.foo();
     baz();
@@ -68,9 +68,9 @@ mod blah {
     }
 }
 
-enum c_void {} //~ ERROR: code is never used
+enum c_void {} //~ ERROR: enum is never used
 extern {
-    fn free(p: *const c_void); //~ ERROR: code is never used
+    fn free(p: *const c_void); //~ ERROR: foreign function is never used
 }
 
 // Check provided method
diff --git a/src/test/compile-fail/lint-dead-code-4.rs b/src/test/compile-fail/lint-dead-code-4.rs
index 826faad32c9..ba02faf11c3 100644
--- a/src/test/compile-fail/lint-dead-code-4.rs
+++ b/src/test/compile-fail/lint-dead-code-4.rs
@@ -19,7 +19,7 @@ use std::num;
 
 struct Foo {
     x: uint,
-    b: bool, //~ ERROR: code is never used
+    b: bool, //~ ERROR: struct field is never used
     marker: std::kinds::marker::NoCopy
 }
 
@@ -31,7 +31,7 @@ enum XYZ {
     X, //~ ERROR variant is never used
     Y { //~ ERROR variant is never used
         a: String,
-        b: int //~ ERROR: code is never used
+        b: int //~ ERROR: struct field is never used
     },
     Z
 }
@@ -44,7 +44,7 @@ fn field_match_in_patterns(b: XYZ) -> String {
 }
 
 struct Bar {
-    x: uint, //~ ERROR: code is never used
+    x: uint, //~ ERROR: struct field is never used
     b: bool,
     _guard: ()
 }
diff --git a/src/test/compile-fail/lint-dead-code-5.rs b/src/test/compile-fail/lint-dead-code-5.rs
index c26ae1a7023..62afa089bbe 100644
--- a/src/test/compile-fail/lint-dead-code-5.rs
+++ b/src/test/compile-fail/lint-dead-code-5.rs
@@ -14,7 +14,7 @@
 
 enum Enum1 {
     Variant1(int),
-    Variant2 //~ ERROR: code is never used
+    Variant2 //~ ERROR: variant is never used
 }
 
 enum Enum2 {

From 5bcc154dffb0aa58eef270f9e7396ec440101ca5 Mon Sep 17 00:00:00 2001
From: Jakub Wieczorek <jakub@jakub.cc>
Date: Sat, 20 Sep 2014 15:37:14 +0200
Subject: [PATCH 3/4] Remove unused enum variants

---
 src/libcore/fmt/float.rs                      | 55 +++----------------
 src/librustc/lint/builtin.rs                  | 26 ++-------
 src/librustc/middle/borrowck/mod.rs           |  6 --
 src/librustc/middle/resolve.rs                |  4 --
 src/librustc/middle/typeck/check/writeback.rs |  7 ---
 src/librustc/middle/typeck/infer/mod.rs       |  9 +--
 src/libsyntax/ext/format.rs                   |  9 +--
 7 files changed, 17 insertions(+), 99 deletions(-)

diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index fcc794fd0d1..92ef0c281f2 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -28,21 +28,12 @@ pub enum ExponentFormat {
     /// Use exponential notation with the exponent having a base of 10 and the
     /// exponent sign being `e` or `E`. For example, 1000 would be printed
     /// 1e3.
-    ExpDec,
-    /// Use exponential notation with the exponent having a base of 2 and the
-    /// exponent sign being `p` or `P`. For example, 8 would be printed 1p3.
-    ExpBin,
+    ExpDec
 }
 
 /// The number of digits used for emitting the fractional part of a number, if
 /// any.
 pub enum SignificantDigits {
-    /// All calculable digits will be printed.
-    ///
-    /// Note that bignums or fractions may cause a surprisingly large number
-    /// of digits to be printed.
-    DigAll,
-
     /// At most the given number of digits will be printed, truncating any
     /// trailing zeroes.
     DigMax(uint),
@@ -53,17 +44,11 @@ pub enum SignificantDigits {
 
 /// How to emit the sign of a number.
 pub enum SignFormat {
-    /// No sign will be printed. The exponent sign will also be emitted.
-    SignNone,
     /// `-` will be printed for negative values, but no sign will be emitted
     /// for positive numbers.
-    SignNeg,
-    /// `+` will be printed for positive values, and `-` will be printed for
-    /// negative values.
-    SignAll,
+    SignNeg
 }
 
-static DIGIT_P_RADIX: uint = ('p' as uint) - ('a' as uint) + 11u;
 static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
 
 /**
@@ -111,9 +96,6 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
         ExpDec if radix >= DIGIT_E_RADIX       // decimal exponent 'e'
           => fail!("float_to_str_bytes_common: radix {} incompatible with \
                     use of 'e' as decimal exponent", radix),
-        ExpBin if radix >= DIGIT_P_RADIX       // binary exponent 'p'
-          => fail!("float_to_str_bytes_common: radix {} incompatible with \
-                    use of 'p' as binary exponent", radix),
         _ => ()
     }
 
@@ -123,16 +105,10 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
     match num.classify() {
         FPNaN => return f("NaN".as_bytes()),
         FPInfinite if num > _0 => {
-            return match sign {
-                SignAll => return f("+inf".as_bytes()),
-                _       => return f("inf".as_bytes()),
-            };
+            return f("inf".as_bytes());
         }
         FPInfinite if num < _0 => {
-            return match sign {
-                SignNone => return f("inf".as_bytes()),
-                _        => return f("-inf".as_bytes()),
-            };
+            return f("-inf".as_bytes());
         }
         _ => {}
     }
@@ -147,11 +123,10 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
 
     let (num, exp) = match exp_format {
         ExpNone => (num, 0i32),
-        ExpDec | ExpBin if num == _0 => (num, 0i32),
-        ExpDec | ExpBin => {
+        ExpDec if num == _0 => (num, 0i32),
+        ExpDec => {
             let (exp, exp_base) = match exp_format {
                 ExpDec => (num.abs().log10().floor(), cast::<f64, T>(10.0f64).unwrap()),
-                ExpBin => (num.abs().log2().floor(), cast::<f64, T>(2.0f64).unwrap()),
                 ExpNone => fail!("unreachable"),
             };
 
@@ -185,21 +160,16 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
 
     // If limited digits, calculate one digit more for rounding.
     let (limit_digits, digit_count, exact) = match digits {
-        DigAll          => (false, 0u,      false),
-        DigMax(count)   => (true,  count+1, false),
-        DigExact(count) => (true,  count+1, true)
+        DigMax(count)   => (true, count + 1, false),
+        DigExact(count) => (true, count + 1, true)
     };
 
     // Decide what sign to put in front
     match sign {
-        SignNeg | SignAll if neg => {
+        SignNeg if neg => {
             buf[end] = b'-';
             end += 1;
         }
-        SignAll => {
-            buf[end] = b'+';
-            end += 1;
-        }
         _ => ()
     }
 
@@ -329,8 +299,6 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
             buf[end] = match exp_format {
                 ExpDec if exp_upper => 'E',
                 ExpDec if !exp_upper => 'e',
-                ExpBin if exp_upper => 'P',
-                ExpBin if !exp_upper => 'p',
                 _ => fail!("unreachable"),
             } as u8;
             end += 1;
@@ -356,11 +324,6 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
                         fmt::write(&mut filler, args)
                     }, "{:-}", exp);
                 }
-                SignNone | SignAll => {
-                    let _ = format_args!(|args| {
-                        fmt::write(&mut filler, args)
-                    }, "{}", exp);
-                }
             }
         }
     }
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index b4685ce456a..3919bf6bb94 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -1269,11 +1269,6 @@ impl LintPass for UnusedMut {
     }
 }
 
-enum Allocation {
-    VectorAllocation,
-    BoxAllocation
-}
-
 declare_lint!(UNNECESSARY_ALLOCATION, Warn,
               "detects unnecessary allocations that can be eliminated")
 
@@ -1285,30 +1280,21 @@ impl LintPass for UnnecessaryAllocation {
     }
 
     fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        // Warn if boxing expressions are immediately borrowed.
-        let allocation = match e.node {
-            ast::ExprUnary(ast::UnUniq, _) |
-            ast::ExprUnary(ast::UnBox, _) => BoxAllocation,
-
+        match e.node {
+            ast::ExprUnary(ast::UnUniq, _) | ast::ExprUnary(ast::UnBox, _) => (),
             _ => return
-        };
+        }
 
         match cx.tcx.adjustments.borrow().find(&e.id) {
             Some(adjustment) => {
                 match *adjustment {
                     ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) => {
-                        match (allocation, autoref) {
-                            (VectorAllocation, &Some(ty::AutoPtr(_, _, None))) => {
-                                cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
-                                             "unnecessary allocation, the sigil can be removed");
-                            }
-                            (BoxAllocation,
-                             &Some(ty::AutoPtr(_, ast::MutImmutable, None))) => {
+                        match autoref {
+                            &Some(ty::AutoPtr(_, ast::MutImmutable, None)) => {
                                 cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
                                              "unnecessary allocation, use & instead");
                             }
-                            (BoxAllocation,
-                             &Some(ty::AutoPtr(_, ast::MutMutable, None))) => {
+                            &Some(ty::AutoPtr(_, ast::MutMutable, None)) => {
                                 cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
                                              "unnecessary allocation, use &mut instead");
                             }
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 7d734323ee8..4f18d00070a 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -243,12 +243,6 @@ struct BorrowStats {
 
 pub type BckResult<T> = Result<T, BckError>;
 
-#[deriving(PartialEq)]
-pub enum PartialTotal {
-    Partial,   // Loan affects some portion
-    Total      // Loan affects entire path
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // Loans and loan paths
 
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index cf80d91595e..7d88ba57ad7 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -488,7 +488,6 @@ enum ParentLink {
 #[deriving(PartialEq)]
 enum ModuleKind {
     NormalModuleKind,
-    ExternModuleKind,
     TraitModuleKind,
     ImplModuleKind,
     AnonymousModuleKind,
@@ -3348,7 +3347,6 @@ impl<'a> Resolver<'a> {
                                     parents");
                             return Failed(None);
                         }
-                        ExternModuleKind |
                         TraitModuleKind |
                         ImplModuleKind |
                         AnonymousModuleKind => {
@@ -3446,7 +3444,6 @@ impl<'a> Resolver<'a> {
                     let new_module = new_module.upgrade().unwrap();
                     match new_module.kind.get() {
                         NormalModuleKind => return Some(new_module),
-                        ExternModuleKind |
                         TraitModuleKind |
                         ImplModuleKind |
                         AnonymousModuleKind => module_ = new_module,
@@ -3462,7 +3459,6 @@ impl<'a> Resolver<'a> {
                                                 -> Rc<Module> {
         match module_.kind.get() {
             NormalModuleKind => return module_,
-            ExternModuleKind |
             TraitModuleKind |
             ImplModuleKind |
             AnonymousModuleKind => {
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index e2a04116f90..5f76c748417 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -361,7 +361,6 @@ enum ResolveReason {
     ResolvingLocal(Span),
     ResolvingPattern(Span),
     ResolvingUpvar(ty::UpvarId),
-    ResolvingImplRes(Span),
     ResolvingUnboxedClosure(ast::DefId),
 }
 
@@ -374,7 +373,6 @@ impl ResolveReason {
             ResolvingUpvar(upvar_id) => {
                 ty::expr_span(tcx, upvar_id.closure_expr_id)
             }
-            ResolvingImplRes(s) => s,
             ResolvingUnboxedClosure(did) => {
                 if did.krate == ast::LOCAL_CRATE {
                     ty::expr_span(tcx, did.node)
@@ -462,11 +460,6 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
                         infer::fixup_err_to_string(e));
                 }
 
-                ResolvingImplRes(span) => {
-                    span_err!(self.tcx.sess, span, E0105,
-                        "cannot determine a type for impl supertrait");
-                }
-
                 ResolvingUnboxedClosure(_) => {
                     let span = self.reason.span(self.tcx);
                     self.tcx.sess.span_err(span,
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index db90593b5b3..3af744824ff 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -271,9 +271,7 @@ pub enum RegionVariableOrigin {
 pub enum fixup_err {
     unresolved_int_ty(IntVid),
     unresolved_float_ty(FloatVid),
-    unresolved_ty(TyVid),
-    unresolved_region(RegionVid),
-    region_var_bound_by_region_var(RegionVid, RegionVid)
+    unresolved_ty(TyVid)
 }
 
 pub fn fixup_err_to_string(f: fixup_err) -> String {
@@ -287,11 +285,6 @@ pub fn fixup_err_to_string(f: fixup_err) -> String {
            the type explicitly".to_string()
       }
       unresolved_ty(_) => "unconstrained type".to_string(),
-      unresolved_region(_) => "unconstrained region".to_string(),
-      region_var_bound_by_region_var(r1, r2) => {
-        format!("region var {:?} bound by another region var {:?}; \
-                 this is a bug in rustc", r1, r2)
-      }
     }
 }
 
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index b760c893a10..1ed41e6870d 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -24,8 +24,7 @@ use std::string;
 #[deriving(PartialEq)]
 enum ArgumentType {
     Known(string::String),
-    Unsigned,
-    String,
+    Unsigned
 }
 
 enum Position {
@@ -691,12 +690,6 @@ impl<'a, 'b> Context<'a, 'b> {
                     }
                 }
             }
-            String => {
-                return ecx.expr_call_global(sp, vec![
-                        ecx.ident_of("std"),
-                        ecx.ident_of("fmt"),
-                        ecx.ident_of("argumentstr")], vec![arg])
-            }
             Unsigned => {
                 return ecx.expr_call_global(sp, vec![
                         ecx.ident_of("std"),

From fd52224e78fe14828f8750fed469cc5c40f260e7 Mon Sep 17 00:00:00 2001
From: Jakub Wieczorek <jakub@jakub.cc>
Date: Sat, 20 Sep 2014 15:20:54 +0200
Subject: [PATCH 4/4] Remove dead code from librustc

---
 src/librustc/back/link.rs                     |  7 --
 src/librustc/diagnostics.rs                   |  2 -
 src/librustc/middle/astencode.rs              | 73 ----------------
 src/librustc/middle/borrowck/mod.rs           | 82 -----------------
 src/librustc/middle/borrowck/move_data.rs     | 23 -----
 src/librustc/middle/kind.rs                   | 11 ---
 src/librustc/middle/mem_categorization.rs     |  4 -
 src/librustc/middle/subst.rs                  | 52 -----------
 src/librustc/middle/trans/monomorphize.rs     | 30 -------
 src/librustc/middle/ty.rs                     | 86 ------------------
 src/librustc/middle/typeck/check/demand.rs    | 14 ---
 src/librustc/middle/typeck/check/mod.rs       | 87 -------------------
 src/librustc/middle/typeck/check/regionck.rs  | 20 -----
 src/librustc/middle/typeck/check/vtable2.rs   | 11 ---
 src/librustc/middle/typeck/check/writeback.rs | 17 +---
 src/librustc/middle/typeck/infer/mod.rs       |  6 --
 .../typeck/infer/region_inference/mod.rs      | 11 ---
 src/librustc/util/ppaux.rs                    |  9 --
 18 files changed, 1 insertion(+), 544 deletions(-)

diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index e6e9448fa56..633248562a5 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -397,13 +397,6 @@ pub fn get_cc_prog(sess: &Session) -> String {
     }.to_string()
 }
 
-pub fn get_ar_prog(sess: &Session) -> String {
-    match sess.opts.cg.ar {
-        Some(ref ar) => (*ar).clone(),
-        None => "ar".to_string()
-    }
-}
-
 pub fn remove(sess: &Session, path: &Path) {
     match fs::unlink(path) {
         Ok(..) => {}
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 14cf07cd5e4..20842beae16 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -114,7 +114,6 @@ register_diagnostics!(
     E0102,
     E0103,
     E0104,
-    E0105,
     E0106,
     E0107,
     E0108,
@@ -152,7 +151,6 @@ register_diagnostics!(
     E0144,
     E0145,
     E0146,
-    E0147,
     E0148,
     E0151,
     E0152,
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index acb4f1be85c..f40d6d47281 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -662,30 +662,6 @@ impl tr for MethodOrigin {
     }
 }
 
-// ______________________________________________________________________
-// Encoding and decoding vtable_res
-
-pub fn encode_vtable_res(ecx: &e::EncodeContext,
-                         rbml_w: &mut Encoder,
-                         dr: &typeck::vtable_res) {
-    // can't autogenerate this code because automatic code of
-    // ty::t doesn't work, and there is no way (atm) to have
-    // hand-written encoding routines combine with auto-generated
-    // ones. perhaps we should fix this.
-    encode_vec_per_param_space(
-        rbml_w, dr,
-        |rbml_w, param_tables| encode_vtable_param_res(ecx, rbml_w,
-                                                       param_tables))
-}
-
-pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
-                     rbml_w: &mut Encoder,
-                     param_tables: &typeck::vtable_param_res) {
-    rbml_w.emit_from_vec(param_tables.as_slice(), |rbml_w, vtable_origin| {
-        Ok(encode_vtable_origin(ecx, rbml_w, vtable_origin))
-    }).unwrap()
-}
-
 pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
                                    kind: ty::UnboxedClosureKind) {
     use serialize::Encoder;
@@ -714,55 +690,6 @@ pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
     }).unwrap()
 }
 
-pub fn encode_vtable_origin(ecx: &e::EncodeContext,
-                            rbml_w: &mut Encoder,
-                            vtable_origin: &typeck::vtable_origin) {
-    use serialize::Encoder;
-
-    rbml_w.emit_enum("vtable_origin", |rbml_w| {
-        match *vtable_origin {
-          typeck::vtable_static(def_id, ref substs, ref vtable_res) => {
-            rbml_w.emit_enum_variant("vtable_static", 0u, 3u, |rbml_w| {
-                rbml_w.emit_enum_variant_arg(0u, |rbml_w| {
-                    Ok(rbml_w.emit_def_id(def_id))
-                });
-                rbml_w.emit_enum_variant_arg(1u, |rbml_w| {
-                    Ok(rbml_w.emit_substs(ecx, substs))
-                });
-                rbml_w.emit_enum_variant_arg(2u, |rbml_w| {
-                    Ok(encode_vtable_res(ecx, rbml_w, vtable_res))
-                })
-            })
-          }
-          typeck::vtable_param(pn, bn) => {
-            rbml_w.emit_enum_variant("vtable_param", 1u, 3u, |rbml_w| {
-                rbml_w.emit_enum_variant_arg(0u, |rbml_w| {
-                    pn.encode(rbml_w)
-                });
-                rbml_w.emit_enum_variant_arg(1u, |rbml_w| {
-                    rbml_w.emit_uint(bn)
-                })
-            })
-          }
-          typeck::vtable_unboxed_closure(def_id) => {
-              rbml_w.emit_enum_variant("vtable_unboxed_closure",
-                                       2u,
-                                       1u,
-                                       |rbml_w| {
-                rbml_w.emit_enum_variant_arg(0u, |rbml_w| {
-                    Ok(rbml_w.emit_def_id(def_id))
-                })
-              })
-          }
-          typeck::vtable_error => {
-            rbml_w.emit_enum_variant("vtable_error", 3u, 3u, |_rbml_w| {
-                Ok(())
-            })
-          }
-        }
-    }).unwrap()
-}
-
 pub trait vtable_decoder_helpers {
     fn read_vec_per_param_space<T>(&mut self,
                                    f: |&mut Self| -> T)
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 4f18d00070a..d3d6e7508f0 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -16,7 +16,6 @@ use middle::cfg;
 use middle::dataflow::DataFlowContext;
 use middle::dataflow::BitwiseOperator;
 use middle::dataflow::DataFlowOperator;
-use middle::def;
 use middle::expr_use_visitor as euv;
 use middle::mem_categorization as mc;
 use middle::ty;
@@ -386,11 +385,6 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
         self.tcx.region_maps.is_subregion_of(r_sub, r_sup)
     }
 
-    pub fn is_subscope_of(&self, r_sub: ast::NodeId, r_sup: ast::NodeId)
-                          -> bool {
-        self.tcx.region_maps.is_subscope_of(r_sub, r_sup)
-    }
-
     pub fn mc(&self) -> mc::MemCategorizationContext<'a, ty::ctxt<'tcx>> {
         mc::MemCategorizationContext::new(self.tcx)
     }
@@ -404,82 +398,6 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> mc::cmt {
-        match self.mc().cat_expr_unadjusted(expr) {
-            Ok(c) => c,
-            Err(()) => {
-                self.tcx.sess.span_bug(expr.span, "error in mem categorization");
-            }
-        }
-    }
-
-    pub fn cat_expr_autoderefd(&self,
-                               expr: &ast::Expr,
-                               adj: &ty::AutoAdjustment)
-                               -> mc::cmt {
-        let r = match *adj {
-            ty::AdjustDerefRef(
-                ty::AutoDerefRef {
-                    autoderefs: autoderefs, ..}) => {
-                self.mc().cat_expr_autoderefd(expr, autoderefs)
-            }
-            ty::AdjustAddEnv(..) => {
-                // no autoderefs
-                self.mc().cat_expr_unadjusted(expr)
-            }
-        };
-
-        match r {
-            Ok(c) => c,
-            Err(()) => {
-                self.tcx.sess.span_bug(expr.span,
-                                       "error in mem categorization");
-            }
-        }
-    }
-
-    pub fn cat_def(&self,
-                   id: ast::NodeId,
-                   span: Span,
-                   ty: ty::t,
-                   def: def::Def)
-                   -> mc::cmt {
-        match self.mc().cat_def(id, span, ty, def) {
-            Ok(c) => c,
-            Err(()) => {
-                self.tcx.sess.span_bug(span, "error in mem categorization");
-            }
-        }
-    }
-
-    pub fn cat_captured_var(&self,
-                            closure_id: ast::NodeId,
-                            closure_span: Span,
-                            upvar_def: def::Def)
-                            -> mc::cmt {
-        // Create the cmt for the variable being borrowed, from the
-        // caller's perspective
-        let var_id = upvar_def.def_id().node;
-        let var_ty = ty::node_id_to_type(self.tcx, var_id);
-        self.cat_def(closure_id, closure_span, var_ty, upvar_def)
-    }
-
-    pub fn cat_discr(&self, cmt: mc::cmt, match_id: ast::NodeId) -> mc::cmt {
-        Rc::new(mc::cmt_ {
-            cat: mc::cat_discr(cmt.clone(), match_id),
-            mutbl: cmt.mutbl.inherit(),
-            ..*cmt
-        })
-    }
-
-    pub fn cat_pattern(&self,
-                       cmt: mc::cmt,
-                       pat: &ast::Pat,
-                       op: |mc::cmt, &ast::Pat|) {
-        let r = self.mc().cat_pattern(cmt, pat, |_,x,y| op(x,y));
-        assert!(r.is_ok());
-    }
-
     pub fn report(&self, err: BckError) {
         self.span_err(
             err.span,
diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs
index fdd16c88686..d8597c08b45 100644
--- a/src/librustc/middle/borrowck/move_data.rs
+++ b/src/librustc/middle/borrowck/move_data.rs
@@ -568,22 +568,6 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
         }
     }
 
-    pub fn each_path_moved_by(&self,
-                              id: ast::NodeId,
-                              f: |&Move, &LoanPath| -> bool)
-                              -> bool {
-        /*!
-         * Iterates through each path moved by `id`
-         */
-
-        self.dfcx_moves.each_gen_bit(id, |index| {
-            let move = self.move_data.moves.borrow();
-            let move = move.get(index);
-            let moved_path = move.path;
-            f(move, &*self.move_data.path_loan_path(moved_path))
-        })
-    }
-
     pub fn kind_of_move_of_path(&self,
                                 id: ast::NodeId,
                                 loan_path: &Rc<LoanPath>)
@@ -665,13 +649,6 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
         })
     }
 
-    pub fn is_assignee(&self,
-                       id: ast::NodeId)
-                       -> bool {
-        //! True if `id` is the id of the LHS of an assignment
-        self.move_data.assignee_ids.borrow().iter().any(|x| x == &id)
-    }
-
     pub fn each_assignment_of(&self,
                               id: ast::NodeId,
                               loan_path: &Rc<LoanPath>,
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 4a5b2e01463..f5d4ece3bcc 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -355,17 +355,6 @@ pub fn check_freevar_bounds(cx: &Context, fn_span: Span, sp: Span, ty: ty::t,
     });
 }
 
-pub fn check_trait_cast_bounds(cx: &Context, sp: Span, ty: ty::t,
-                               bounds: ty::BuiltinBounds) {
-    check_builtin_bounds(cx, ty, bounds, |missing| {
-        span_err!(cx.tcx.sess, sp, E0147,
-            "cannot pack type `{}`, which does not fulfill `{}`, as a trait bounded by {}",
-            ty_to_string(cx.tcx, ty),
-            missing.user_string(cx.tcx),
-            bounds.user_string(cx.tcx));
-    });
-}
-
 fn check_copy(cx: &Context, ty: ty::t, sp: Span, reason: &str) {
     debug!("type_contents({})={}",
            ty_to_string(cx.tcx, ty),
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index c3b477da4bc..3b831dd6847 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -735,10 +735,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         })
     }
 
-    pub fn cat_deref_obj<N:ast_node>(&self, node: &N, base_cmt: cmt) -> cmt {
-        self.cat_deref_common(node, base_cmt, 0, ty::mk_nil(), false)
-    }
-
     fn cat_deref<N:ast_node>(&self,
                              node: &N,
                              base_cmt: cmt,
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 9583dcf560e..b55678e3a50 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -195,11 +195,6 @@ impl Substs {
         }
     }
 
-    pub fn with_method_from(self, substs: &Substs) -> Substs {
-        self.with_method(Vec::from_slice(substs.types.get_slice(FnSpace)),
-                         Vec::from_slice(substs.regions().get_slice(FnSpace)))
-    }
-
     pub fn with_method(self,
                        m_types: Vec<ty::t>,
                        m_regions: Vec<ty::Region>)
@@ -292,15 +287,6 @@ impl<T:fmt::Show> fmt::Show for VecPerParamSpace<T> {
     }
 }
 
-impl<T:Clone> VecPerParamSpace<T> {
-    pub fn push_all(&mut self, space: ParamSpace, values: &[T]) {
-        // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
-        for t in values.iter() {
-            self.push(space, t.clone());
-        }
-    }
-}
-
 impl<T> VecPerParamSpace<T> {
     fn limits(&self, space: ParamSpace) -> (uint, uint) {
         match space {
@@ -348,14 +334,6 @@ impl<T> VecPerParamSpace<T> {
         }
     }
 
-    pub fn sort(t: Vec<T>, space: |&T| -> ParamSpace) -> VecPerParamSpace<T> {
-        let mut result = VecPerParamSpace::empty();
-        for t in t.into_iter() {
-            result.push(space(&t), t);
-        }
-        result
-    }
-
     /// Appends `value` to the vector associated with `space`.
     ///
     /// Unlike the `push` method in `Vec`, this should not be assumed
@@ -435,12 +413,6 @@ impl<T> VecPerParamSpace<T> {
         &self.get_slice(space)[index]
     }
 
-    pub fn get_mut<'a>(&'a mut self,
-                       space: ParamSpace,
-                       index: uint) -> &'a mut T {
-        &mut self.get_mut_slice(space)[index]
-    }
-
     pub fn iter<'a>(&'a self) -> Items<'a,T> {
         self.content.iter()
     }
@@ -476,30 +448,6 @@ impl<T> VecPerParamSpace<T> {
                               f.into_iter().map(|p| pred(p)).collect())
     }
 
-    pub fn map_rev<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
-        /*!
-         * Executes the map but in reverse order. For hacky reasons, we rely
-         * on this in table.
-         *
-         * FIXME(#5527) -- order of eval becomes irrelevant with newer
-         * trait reform, which features an idempotent algorithm that
-         * can be run to a fixed point
-         */
-
-        let mut fns: Vec<U> = self.get_slice(FnSpace).iter().rev().map(|p| pred(p)).collect();
-
-        // NB: Calling foo.rev().map().rev() causes the calls to map
-        // to occur in the wrong order. This was somewhat surprising
-        // to me, though it makes total sense.
-        fns.reverse();
-
-        let mut selfs: Vec<U> = self.get_slice(SelfSpace).iter().rev().map(|p| pred(p)).collect();
-        selfs.reverse();
-        let mut tys: Vec<U> = self.get_slice(TypeSpace).iter().rev().map(|p| pred(p)).collect();
-        tys.reverse();
-        VecPerParamSpace::new(tys, selfs, fns)
-    }
-
     pub fn split(self) -> (Vec<T>, Vec<T>, Vec<T>) {
         // FIXME (#15418): this does two traversals when in principle
         // one would suffice.  i.e. change to use `move_iter`.
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index d2bbbdfad0e..12a2815cfef 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -21,7 +21,6 @@ use middle::trans::base;
 use middle::trans::common::*;
 use middle::trans::foreign;
 use middle::ty;
-use middle::typeck;
 use util::ppaux::Repr;
 
 use syntax::abi;
@@ -285,37 +284,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
     (lldecl, true)
 }
 
-// Used to identify cached monomorphized functions
-#[deriving(PartialEq, Eq, Hash)]
-pub struct MonoParamId {
-    pub subst: ty::t,
-}
-
 #[deriving(PartialEq, Eq, Hash)]
 pub struct MonoId {
     pub def: ast::DefId,
     pub params: subst::VecPerParamSpace<ty::t>
 }
-
-pub fn make_vtable_id(_ccx: &CrateContext,
-                      origin: &typeck::vtable_origin)
-                      -> MonoId {
-    match origin {
-        &typeck::vtable_static(impl_id, ref substs, _) => {
-            MonoId {
-                def: impl_id,
-                params: substs.types.clone()
-            }
-        }
-
-        &typeck::vtable_unboxed_closure(def_id) => {
-            MonoId {
-                def: def_id,
-                params: subst::VecPerParamSpace::empty(),
-            }
-        }
-
-        // can't this be checked at the callee?
-        _ => fail!("make_vtable_id needs vtable_static")
-    }
-}
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 469cdad076d..f1499cb9166 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -1915,13 +1915,6 @@ pub fn fold_ty(cx: &ctxt, t0: t, fldop: |t| -> t) -> t {
     f.fold_ty(t0)
 }
 
-pub fn walk_regions_and_ty(cx: &ctxt, ty: t, fldr: |r: Region|, fldt: |t: t|)
-                           -> t {
-    ty_fold::RegionFolder::general(cx,
-                                   |r| { fldr(r); r },
-                                   |t| { fldt(t); t }).fold_ty(ty)
-}
-
 impl ParamTy {
     pub fn new(space: subst::ParamSpace,
                index: uint,
@@ -3551,58 +3544,6 @@ pub fn unsize_ty(cx: &ctxt,
     }
 }
 
-impl AutoRef {
-    pub fn map_region(&self, f: |Region| -> Region) -> AutoRef {
-        match *self {
-            ty::AutoPtr(r, m, None) => ty::AutoPtr(f(r), m, None),
-            ty::AutoPtr(r, m, Some(ref a)) => ty::AutoPtr(f(r), m, Some(box a.map_region(f))),
-            ty::AutoUnsize(ref k) => ty::AutoUnsize(k.clone()),
-            ty::AutoUnsizeUniq(ref k) => ty::AutoUnsizeUniq(k.clone()),
-            ty::AutoUnsafe(m, None) => ty::AutoUnsafe(m, None),
-            ty::AutoUnsafe(m, Some(ref a)) => ty::AutoUnsafe(m, Some(box a.map_region(f))),
-        }
-    }
-}
-
-pub fn method_call_type_param_defs<'tcx, T>(typer: &T,
-                                            origin: &typeck::MethodOrigin)
-                                            -> VecPerParamSpace<TypeParameterDef>
-                                            where T: mc::Typer<'tcx> {
-    match *origin {
-        typeck::MethodStatic(did) => {
-            ty::lookup_item_type(typer.tcx(), did).generics.types.clone()
-        }
-        typeck::MethodStaticUnboxedClosure(did) => {
-            let def_id = typer.unboxed_closures()
-                              .borrow()
-                              .find(&did)
-                              .expect("method_call_type_param_defs: didn't \
-                                       find unboxed closure")
-                              .kind
-                              .trait_did(typer.tcx());
-            lookup_trait_def(typer.tcx(), def_id).generics.types.clone()
-        }
-        typeck::MethodTypeParam(typeck::MethodParam{
-            trait_ref: ref trait_ref,
-            method_num: n_mth,
-            ..
-        }) |
-        typeck::MethodTraitObject(typeck::MethodObject{
-                trait_ref: ref trait_ref,
-                method_num: n_mth,
-                ..
-        }) => {
-            match ty::trait_item(typer.tcx(), trait_ref.def_id, n_mth) {
-                ty::MethodTraitItem(method) => method.generics.types.clone(),
-                ty::TypeTraitItem(_) => {
-                    typer.tcx().sess.bug("method_call_type_param_defs() \
-                                          called on associated type")
-                }
-            }
-        }
-    }
-}
-
 pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
     match tcx.def_map.borrow().find(&expr.id) {
         Some(&def) => def,
@@ -3821,22 +3762,6 @@ pub fn impl_or_trait_item_idx(id: ast::Ident, trait_items: &[ImplOrTraitItem])
     trait_items.iter().position(|m| m.ident() == id)
 }
 
-/// Returns a vector containing the indices of all type parameters that appear
-/// in `ty`.  The vector may contain duplicates.  Probably should be converted
-/// to a bitset or some other representation.
-pub fn param_tys_in_type(ty: t) -> Vec<ParamTy> {
-    let mut rslt = Vec::new();
-    walk_ty(ty, |ty| {
-        match get(ty).sty {
-          ty_param(p) => {
-            rslt.push(p);
-          }
-          _ => ()
-        }
-    });
-    rslt
-}
-
 pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
     match get(t).sty {
         ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
@@ -4706,17 +4631,6 @@ pub fn is_tuple_struct(cx: &ctxt, did: ast::DefId) -> bool {
     !fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field)
 }
 
-pub fn lookup_struct_field(cx: &ctxt,
-                           parent: ast::DefId,
-                           field_id: ast::DefId)
-                        -> field_ty {
-    let r = lookup_struct_fields(cx, parent);
-    match r.iter().find(|f| f.id.node == field_id.node) {
-        Some(t) => t.clone(),
-        None => cx.sess.bug("struct ID not found in parent's fields")
-    }
-}
-
 // Returns a list of fields corresponding to the struct's items. trans uses
 // this. Takes a list of substs with which to instantiate field types.
 pub fn struct_fields(cx: &ctxt, did: ast::DefId, substs: &Substs)
diff --git a/src/librustc/middle/typeck/check/demand.rs b/src/librustc/middle/typeck/check/demand.rs
index 1b10b30b335..2359f9d72d2 100644
--- a/src/librustc/middle/typeck/check/demand.rs
+++ b/src/librustc/middle/typeck/check/demand.rs
@@ -77,17 +77,3 @@ pub fn coerce(fcx: &FnCtxt, sp: Span, expected: ty::t, expr: &ast::Expr) {
       }
     }
 }
-
-pub fn coerce_with_fn(fcx: &FnCtxt,
-                      sp: Span,
-                      expected: ty::t,
-                      expr: &ast::Expr,
-                      handle_err: |Span, ty::t, ty::t, &ty::type_err|) {
-    let expr_ty = fcx.expr_ty(expr);
-    match fcx.mk_assignty(expr, expr_ty, expected) {
-      result::Ok(()) => { /* ok */ }
-      result::Err(ref err) => {
-        handle_err(sp, expected, expr_ty, err);
-      }
-    }
-}
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 5f1ff1d6406..821cf629d83 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -1901,18 +1901,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn method_ty_substs(&self, id: ast::NodeId) -> subst::Substs {
-        match self.inh.method_map.borrow().find(&MethodCall::expr(id)) {
-            Some(method) => method.substs.clone(),
-            None => {
-                self.tcx().sess.bug(
-                    format!("no method entry for node {}: {} in fcx {}",
-                            id, self.tcx().map.node_to_string(id),
-                            self.tag()).as_slice());
-            }
-        }
-    }
-
     pub fn opt_node_ty_substs(&self,
                               id: ast::NodeId,
                               f: |&ty::ItemSubsts|) {
@@ -1984,18 +1972,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
     }
 
-    pub fn report_mismatched_return_types(&self,
-                                          sp: Span,
-                                          e: ty::t,
-                                          a: ty::t,
-                                          err: &ty::type_err) {
-        // Derived error
-        if ty::type_is_error(e) || ty::type_is_error(a) {
-            return;
-        }
-        self.infcx().report_mismatched_types(sp, e, a, err)
-    }
-
     pub fn report_mismatched_types(&self,
                                    sp: Span,
                                    e: ty::t,
@@ -4663,24 +4639,6 @@ impl Repr for Expectation {
     }
 }
 
-pub fn require_uint(fcx: &FnCtxt, sp: Span, t: ty::t) {
-    if !type_is_uint(fcx, sp, t) {
-        fcx.type_error_message(sp, |actual| {
-            format!("mismatched types: expected `uint` type, found `{}`",
-                    actual)
-        }, t, None);
-    }
-}
-
-pub fn require_integral(fcx: &FnCtxt, sp: Span, t: ty::t) {
-    if !type_is_integral(fcx, sp, t) {
-        fcx.type_error_message(sp, |actual| {
-            format!("mismatched types: expected integral type, found `{}`",
-                    actual)
-        }, t, None);
-    }
-}
-
 pub fn check_decl_initializer(fcx: &FnCtxt,
                               nid: ast::NodeId,
                               init: &ast::Expr)
@@ -5602,51 +5560,6 @@ pub fn structure_of<'a>(fcx: &FnCtxt, sp: Span, typ: ty::t)
     &ty::get(structurally_resolved_type(fcx, sp, typ)).sty
 }
 
-pub fn type_is_integral(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
-    let typ_s = structurally_resolved_type(fcx, sp, typ);
-    return ty::type_is_integral(typ_s);
-}
-
-pub fn type_is_uint(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
-    let typ_s = structurally_resolved_type(fcx, sp, typ);
-    return ty::type_is_uint(typ_s);
-}
-
-pub fn type_is_scalar(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
-    let typ_s = structurally_resolved_type(fcx, sp, typ);
-    return ty::type_is_scalar(typ_s);
-}
-
-pub fn type_is_char(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
-    let typ_s = structurally_resolved_type(fcx, sp, typ);
-    return ty::type_is_char(typ_s);
-}
-
-pub fn type_is_bare_fn(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
-    let typ_s = structurally_resolved_type(fcx, sp, typ);
-    return ty::type_is_bare_fn(typ_s);
-}
-
-pub fn type_is_floating_point(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
-    let typ_s = structurally_resolved_type(fcx, sp, typ);
-    return ty::type_is_floating_point(typ_s);
-}
-
-pub fn type_is_unsafe_ptr(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
-    let typ_s = structurally_resolved_type(fcx, sp, typ);
-    return ty::type_is_unsafe_ptr(typ_s);
-}
-
-pub fn type_is_region_ptr(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
-    let typ_s = structurally_resolved_type(fcx, sp, typ);
-    return ty::type_is_region_ptr(typ_s);
-}
-
-pub fn type_is_c_like_enum(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
-    let typ_s = structurally_resolved_type(fcx, sp, typ);
-    return ty::type_is_c_like_enum(fcx.ccx.tcx, typ_s);
-}
-
 // Returns true if b contains a break that can exit from b
 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
     // First: is there an unlabeled break immediately
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index d0791191c0f..85fe0a42c49 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -213,26 +213,6 @@ pub struct Rcx<'a, 'tcx: 'a> {
     repeating_scope: ast::NodeId,
 }
 
-/// When entering a function, we can derive relationships from the
-/// signature between various regions and type parameters. Consider
-/// a function like:
-///
-///     fn foo<'a, A>(x: &'a A) { ... }
-///
-/// Here, we can derive that `A` must outlive `'a`, because otherwise
-/// the caller would be illegal. We record this by storing a series of
-/// pairs (in this case, `('a, A)`). These pairs will be consulted
-/// later during regionck.
-///
-/// In the case of nested fns, additional relationships may be
-/// derived.  The result is a link list walking up the stack (hence
-/// the `previous` field).
-#[deriving(Clone)]
-pub struct RegionSubParamConstraints<'a> {
-    pairs: Vec<(ty::Region, ty::ParamTy)>,
-    previous: Option<&'a RegionSubParamConstraints<'a>>,
-}
-
 fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region {
     /*!
      * Returns the validity region of `def` -- that is, how long
diff --git a/src/librustc/middle/typeck/check/vtable2.rs b/src/librustc/middle/typeck/check/vtable2.rs
index 0022efd845e..61ff86afcec 100644
--- a/src/librustc/middle/typeck/check/vtable2.rs
+++ b/src/librustc/middle/typeck/check/vtable2.rs
@@ -25,17 +25,6 @@ use syntax::codemap::Span;
 use util::ppaux::UserString;
 use util::ppaux::Repr;
 
-/// When reporting an error about a failed trait obligation, it's nice
-/// to include some context indicating why we were checking that
-/// obligation in the first place. The span is often enough but
-/// sometimes it's not. Currently this enum is a bit of a hack and I
-/// suspect it should be carried in the obligation or more deeply
-/// integrated somehow.
-pub enum ErrorReportingContext {
-    GenericContext,
-    ImplSupertraitCheck,
-}
-
 pub fn check_object_cast(fcx: &FnCtxt,
                          cast_expr: &ast::Expr,
                          source_expr: &ast::Expr,
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index 5f76c748417..f734aa09e4a 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -22,7 +22,6 @@ use middle::typeck::infer::{force_all, resolve_all, resolve_region};
 use middle::typeck::infer::resolve_type;
 use middle::typeck::infer;
 use middle::typeck::{MethodCall, MethodCallee};
-use middle::typeck::vtable_res;
 use middle::typeck::write_substs_to_tcx;
 use middle::typeck::write_ty_to_tcx;
 use util::ppaux::Repr;
@@ -67,17 +66,6 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
     wbcx.visit_object_cast_map();
 }
 
-pub fn resolve_impl_res(infcx: &infer::InferCtxt,
-                        span: Span,
-                        vtable_res: &vtable_res)
-                        -> vtable_res {
-    let errors = Cell::new(false); // nobody cares
-    let mut resolver = Resolver::from_infcx(infcx,
-                                            &errors,
-                                            ResolvingImplRes(span));
-    vtable_res.resolve_in(&mut resolver)
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // The Writerback context. This visitor walks the AST, checking the
 // fn-specific tables to find references to types or regions. It
@@ -413,10 +401,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
            reason: ResolveReason)
            -> Resolver<'cx, 'tcx>
     {
-        Resolver { infcx: fcx.infcx(),
-                   tcx: fcx.tcx(),
-                   writeback_errors: &fcx.writeback_errors,
-                   reason: reason }
+        Resolver::from_infcx(fcx.infcx(), &fcx.writeback_errors, reason)
     }
 
     fn from_infcx(infcx: &'cx infer::InferCtxt<'cx, 'tcx>,
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index 3af744824ff..d1b754155f8 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -66,12 +66,6 @@ pub mod unify;
 
 pub type Bound<T> = Option<T>;
 
-#[deriving(PartialEq,Clone)]
-pub struct Bounds<T> {
-    pub lb: Bound<T>,
-    pub ub: Bound<T>
-}
-
 pub type cres<T> = Result<T,ty::type_err>; // "combine result"
 pub type ures = cres<()>; // "unify result"
 pub type fres<T> = Result<T, fixup_err>; // "fixup result"
diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs
index 7e61c254a65..008ca6c0771 100644
--- a/src/librustc/middle/typeck/infer/region_inference/mod.rs
+++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs
@@ -525,17 +525,6 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         }
     }
 
-    pub fn max_regions(&self,
-                       a: Region,
-                       b: Region)
-                       -> Option<Region>
-    {
-        match self.glb_concrete_regions(a, b) {
-            Ok(r) => Some(r),
-            Err(_) => None
-        }
-    }
-
     pub fn resolve_var(&self, rid: RegionVid) -> ty::Region {
         match *self.values.borrow() {
             None => {
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 5b83f024309..0a4fd90765c 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -25,7 +25,6 @@ use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
 use middle::ty;
 use middle::typeck;
 use middle::typeck::check::regionmanip;
-use middle::typeck::infer;
 
 use std::rc::Rc;
 use syntax::abi;
@@ -1181,14 +1180,6 @@ impl Repr for ast::FloatTy {
     }
 }
 
-impl<T:Repr> Repr for infer::Bounds<T> {
-    fn repr(&self, tcx: &ctxt) -> String {
-        format!("({} <= {})",
-                self.lb.repr(tcx),
-                self.ub.repr(tcx))
-    }
-}
-
 impl Repr for ty::ExplicitSelfCategory {
     fn repr(&self, _: &ctxt) -> String {
         explicit_self_category_to_str(self).to_string()