about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doc/reference.md4
-rw-r--r--src/libcollections/string.rs16
-rw-r--r--src/libcollections/vec.rs2
-rw-r--r--src/libcore/fmt/mod.rs1
-rw-r--r--src/librustc/lint/builtin.rs65
-rw-r--r--src/librustc/lint/context.rs1
-rw-r--r--src/librustc/metadata/common.rs10
-rw-r--r--src/librustc/metadata/encoder.rs46
-rw-r--r--src/librustc/metadata/tydecode.rs8
-rw-r--r--src/librustc/metadata/tyencode.rs2
-rw-r--r--src/librustc/middle/astencode.rs93
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/def.rs6
-rw-r--r--src/librustc/middle/expr_use_visitor.rs14
-rw-r--r--src/librustc/middle/fast_reject.rs6
-rw-r--r--src/librustc/middle/infer/combine.rs12
-rw-r--r--src/librustc/middle/infer/equate.rs10
-rw-r--r--src/librustc/middle/infer/freshen.rs2
-rw-r--r--src/librustc/middle/infer/glb.rs10
-rw-r--r--src/librustc/middle/infer/lub.rs11
-rw-r--r--src/librustc/middle/infer/sub.rs8
-rw-r--r--src/librustc/middle/lang_items.rs10
-rw-r--r--src/librustc/middle/liveness.rs6
-rw-r--r--src/librustc/middle/mem_categorization.rs42
-rw-r--r--src/librustc/middle/stability.rs2
-rw-r--r--src/librustc/middle/traits/coherence.rs2
-rw-r--r--src/librustc/middle/traits/fulfill.rs8
-rw-r--r--src/librustc/middle/traits/mod.rs19
-rw-r--r--src/librustc/middle/traits/project.rs2
-rw-r--r--src/librustc/middle/traits/select.rs74
-rw-r--r--src/librustc/middle/traits/util.rs4
-rw-r--r--src/librustc/middle/ty.rs192
-rw-r--r--src/librustc/middle/ty_fold.rs22
-rw-r--r--src/librustc/middle/ty_walk.rs7
-rw-r--r--src/librustc/util/ppaux.rs11
-rw-r--r--src/librustc_borrowck/borrowck/check_loans.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs2
-rw-r--r--src/librustc_privacy/lib.rs4
-rw-r--r--src/librustc_resolve/lib.rs12
-rw-r--r--src/librustc_trans/save/mod.rs2
-rw-r--r--src/librustc_trans/trans/_match.rs6
-rw-r--r--src/librustc_trans/trans/adt.rs8
-rw-r--r--src/librustc_trans/trans/base.rs75
-rw-r--r--src/librustc_trans/trans/callee.rs6
-rw-r--r--src/librustc_trans/trans/closure.rs95
-rw-r--r--src/librustc_trans/trans/common.rs78
-rw-r--r--src/librustc_trans/trans/context.rs8
-rw-r--r--src/librustc_trans/trans/debuginfo.rs18
-rw-r--r--src/librustc_trans/trans/expr.rs8
-rw-r--r--src/librustc_trans/trans/glue.rs2
-rw-r--r--src/librustc_trans/trans/meth.rs6
-rw-r--r--src/librustc_trans/trans/monomorphize.rs2
-rw-r--r--src/librustc_trans/trans/type_of.rs12
-rw-r--r--src/librustc_typeck/check/assoc.rs2
-rw-r--r--src/librustc_typeck/check/closure.rs75
-rw-r--r--src/librustc_typeck/check/method/probe.rs46
-rw-r--r--src/librustc_typeck/check/mod.rs40
-rw-r--r--src/librustc_typeck/check/regionck.rs13
-rw-r--r--src/librustc_typeck/check/regionmanip.rs6
-rw-r--r--src/librustc_typeck/check/upvar.rs7
-rw-r--r--src/librustc_typeck/check/writeback.rs35
-rw-r--r--src/librustc_typeck/coherence/mod.rs6
-rw-r--r--src/librustc_typeck/diagnostics.rs2
-rw-r--r--src/librustc_typeck/variance.rs4
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/libsyntax/ast.rs38
-rw-r--r--src/libsyntax/ext/base.rs2
-rw-r--r--src/libsyntax/ext/deriving/bounds.rs3
-rw-r--r--src/libsyntax/ext/deriving/clone.rs3
-rw-r--r--src/libsyntax/ext/deriving/cmp/eq.rs3
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs3
-rw-r--r--src/libsyntax/ext/deriving/cmp/totaleq.rs3
-rw-r--r--src/libsyntax/ext/deriving/cmp/totalord.rs3
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs4
-rw-r--r--src/libsyntax/ext/deriving/default.rs4
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs4
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs24
-rw-r--r--src/libsyntax/ext/deriving/hash.rs3
-rw-r--r--src/libsyntax/ext/deriving/mod.rs8
-rw-r--r--src/libsyntax/ext/deriving/primitive.rs4
-rw-r--r--src/libsyntax/ext/deriving/rand.rs3
-rw-r--r--src/libsyntax/ext/deriving/show.rs7
-rw-r--r--src/libsyntax/parse/parser.rs35
-rw-r--r--src/libsyntax/print/pprust.rs111
-rw-r--r--src/test/compile-fail/deriving-is-deprecated.rs15
-rw-r--r--src/test/compile-fail/missing_debug_impls.rs48
-rw-r--r--src/test/run-pass/issue-21306.rs17
-rw-r--r--src/test/run-pass/issue-21363.rs21
-rw-r--r--src/test/run-pass/unboxed-closures-unique-type-id.rs2
89 files changed, 841 insertions, 841 deletions
diff --git a/src/doc/reference.md b/src/doc/reference.md
index db025ddcc5d..a52100c4cdd 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -2418,10 +2418,6 @@ The currently implemented features of the reference compiler are:
                        for now until the specification of identifiers is fully
                        fleshed out.
 
-* `once_fns` - Onceness guarantees a closure is only executed once. Defining a
-               closure as `once` is unlikely to be supported going forward. So
-               they are hidden behind this feature until they are to be removed.
-
 * `plugin` - Usage of [compiler plugins][plugin] for custom lints or syntax extensions.
              These depend on compiler internals and are subject to change.
 
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index cdceca7176d..5189b825f16 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -1417,4 +1417,20 @@ mod tests {
             let _ = String::from_utf8_lossy(s.as_slice());
         });
     }
+
+    #[bench]
+    fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
+        let s = "Hello there, the quick brown fox jumped over the lazy dog! \
+                 Lorem ipsum dolor sit amet, consectetur. ";
+        // ensure our operation produces an exact-size string before we benchmark it
+        let mut r = String::with_capacity(s.len());
+        r.push_str(s);
+        assert_eq!(r.len(), r.capacity());
+        b.iter(|| {
+            let mut r = String::with_capacity(s.len());
+            r.push_str(s);
+            r.shrink_to_fit();
+            r
+        });
+    }
 }
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 53f75a3e778..c44dfff9117 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -357,7 +357,7 @@ impl<T> Vec<T> {
                 }
                 self.cap = 0;
             }
-        } else {
+        } else if self.cap != self.len {
             unsafe {
                 // Overflow check is unnecessary as the vector is already at
                 // least this large.
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 577c277893c..8e6715fa38b 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -255,6 +255,7 @@ pub trait Show {
            reason = "I/O and core have yet to be reconciled")]
 #[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is defined in your \
                             crate, add `#[derive(Debug)]` or manually implement it"]
+#[lang = "debug_trait"]
 pub trait Debug {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 421f3994189..f13814527cd 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -1625,6 +1625,69 @@ impl LintPass for MissingCopyImplementations {
 }
 
 declare_lint! {
+    MISSING_DEBUG_IMPLEMENTATIONS,
+    Allow,
+    "detects missing implementations of fmt::Debug"
+}
+
+pub struct MissingDebugImplementations {
+    impling_types: Option<NodeSet>,
+}
+
+impl MissingDebugImplementations {
+    pub fn new() -> MissingDebugImplementations {
+        MissingDebugImplementations {
+            impling_types: None,
+        }
+    }
+}
+
+impl LintPass for MissingDebugImplementations {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(MISSING_DEBUG_IMPLEMENTATIONS)
+    }
+
+    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
+        if !cx.exported_items.contains(&item.id) {
+            return;
+        }
+
+        match item.node {
+            ast::ItemStruct(..) | ast::ItemEnum(..) => {},
+            _ => return,
+        }
+
+        let debug = match cx.tcx.lang_items.debug_trait() {
+            Some(debug) => debug,
+            None => return,
+        };
+
+        if self.impling_types.is_none() {
+            let impls = cx.tcx.trait_impls.borrow();
+            let impls = match impls.get(&debug) {
+                Some(impls) => {
+                    impls.borrow().iter()
+                        .filter(|d| d.krate == ast::LOCAL_CRATE)
+                        .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
+                        .map(|d| d.node)
+                        .collect()
+                }
+                None => NodeSet(),
+            };
+            self.impling_types = Some(impls);
+            debug!("{:?}", self.impling_types);
+        }
+
+        if !self.impling_types.as_ref().unwrap().contains(&item.id) {
+            cx.span_lint(MISSING_DEBUG_IMPLEMENTATIONS,
+                         item.span,
+                         "type does not implement `fmt::Debug`; consider adding #[derive(Debug)] \
+                          or a manual implementation")
+        }
+    }
+}
+
+declare_lint! {
     DEPRECATED,
     Warn,
     "detects use of #[deprecated] items"
@@ -1826,7 +1889,7 @@ impl LintPass for UnconditionalRecursion {
                     ty::MethodTraitObject(_) => return false,
 
                     // This `did` refers directly to the method definition.
-                    ty::MethodStatic(did) | ty::MethodStaticUnboxedClosure(did) => did,
+                    ty::MethodStatic(did) | ty::MethodStaticClosure(did) => did,
 
                     // MethodTypeParam are methods from traits:
 
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 1d3904e8512..3a103e42101 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -219,6 +219,7 @@ impl LintStore {
                               TypeLimits,
                               RawPointerDerive,
                               MissingDoc,
+                              MissingDebugImplementations,
         );
 
         add_lint_group!(sess, "bad_style",
diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs
index de9a09ffe44..0ca3e2595ab 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -139,7 +139,7 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
     tag_table_adjustments = 0x51,
     tag_table_moves_map = 0x52,
     tag_table_capture_map = 0x53,
-    tag_table_unboxed_closures = 0x54,
+    tag_table_closures = 0x54,
     tag_table_upvar_borrow_map = 0x55,
     tag_table_capture_modes = 0x56,
     tag_table_object_cast_map = 0x57,
@@ -225,10 +225,10 @@ pub struct LinkMeta {
     pub crate_hash: Svh,
 }
 
-pub const tag_unboxed_closures: uint = 0x95;
-pub const tag_unboxed_closure: uint = 0x96;
-pub const tag_unboxed_closure_type: uint = 0x97;
-pub const tag_unboxed_closure_kind: uint = 0x98;
+pub const tag_closures: uint = 0x95;
+pub const tag_closure: uint = 0x96;
+pub const tag_closure_type: uint = 0x97;
+pub const tag_closure_kind: uint = 0x98;
 
 pub const tag_struct_fields: uint = 0x99;
 pub const tag_struct_field: uint = 0x9a;
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index d0989160488..2de45381249 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -618,13 +618,12 @@ fn encode_visibility(rbml_w: &mut Encoder, visibility: ast::Visibility) {
     rbml_w.end_tag();
 }
 
-fn encode_unboxed_closure_kind(rbml_w: &mut Encoder,
-                               kind: ty::UnboxedClosureKind) {
-    rbml_w.start_tag(tag_unboxed_closure_kind);
+fn encode_closure_kind(rbml_w: &mut Encoder, kind: ty::ClosureKind) {
+    rbml_w.start_tag(tag_closure_kind);
     let ch = match kind {
-        ty::FnUnboxedClosureKind => 'f',
-        ty::FnMutUnboxedClosureKind => 'm',
-        ty::FnOnceUnboxedClosureKind => 'o',
+        ty::FnClosureKind => 'f',
+        ty::FnMutClosureKind => 'm',
+        ty::FnOnceClosureKind => 'o',
     };
     rbml_w.wr_str(&ch.to_string()[]);
     rbml_w.end_tag();
@@ -1838,24 +1837,19 @@ fn encode_macro_defs(rbml_w: &mut Encoder,
     rbml_w.end_tag();
 }
 
-fn encode_unboxed_closures<'a>(
-                           ecx: &'a EncodeContext,
-                           rbml_w: &'a mut Encoder) {
-    rbml_w.start_tag(tag_unboxed_closures);
-    for (unboxed_closure_id, unboxed_closure) in ecx.tcx
-                                                    .unboxed_closures
-                                                    .borrow()
-                                                    .iter() {
-        if unboxed_closure_id.krate != ast::LOCAL_CRATE {
+fn encode_closures<'a>(ecx: &'a EncodeContext, rbml_w: &'a mut Encoder) {
+    rbml_w.start_tag(tag_closures);
+    for (closure_id, closure) in ecx.tcx.closures.borrow().iter() {
+        if closure_id.krate != ast::LOCAL_CRATE {
             continue
         }
 
-        rbml_w.start_tag(tag_unboxed_closure);
-        encode_def_id(rbml_w, *unboxed_closure_id);
-        rbml_w.start_tag(tag_unboxed_closure_type);
-        write_closure_type(ecx, rbml_w, &unboxed_closure.closure_type);
+        rbml_w.start_tag(tag_closure);
+        encode_def_id(rbml_w, *closure_id);
+        rbml_w.start_tag(tag_closure_type);
+        write_closure_type(ecx, rbml_w, &closure.closure_type);
         rbml_w.end_tag();
-        encode_unboxed_closure_kind(rbml_w, unboxed_closure.kind);
+        encode_closure_kind(rbml_w, closure.kind);
         rbml_w.end_tag();
     }
     rbml_w.end_tag();
@@ -2069,7 +2063,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
         native_lib_bytes: u64,
         plugin_registrar_fn_bytes: u64,
         macro_defs_bytes: u64,
-        unboxed_closure_bytes: u64,
+        closure_bytes: u64,
         impl_bytes: u64,
         misc_bytes: u64,
         item_bytes: u64,
@@ -2084,7 +2078,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
         native_lib_bytes: 0,
         plugin_registrar_fn_bytes: 0,
         macro_defs_bytes: 0,
-        unboxed_closure_bytes: 0,
+        closure_bytes: 0,
         impl_bytes: 0,
         misc_bytes: 0,
         item_bytes: 0,
@@ -2154,10 +2148,10 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
     encode_macro_defs(&mut rbml_w, krate);
     stats.macro_defs_bytes = rbml_w.writer.tell().unwrap() - i;
 
-    // Encode the types of all unboxed closures in this crate.
+    // Encode the types of all closures in this crate.
     i = rbml_w.writer.tell().unwrap();
-    encode_unboxed_closures(&ecx, &mut rbml_w);
-    stats.unboxed_closure_bytes = rbml_w.writer.tell().unwrap() - i;
+    encode_closures(&ecx, &mut rbml_w);
+    stats.closure_bytes = rbml_w.writer.tell().unwrap() - i;
 
     // Encode the def IDs of impls, for coherence checking.
     i = rbml_w.writer.tell().unwrap();
@@ -2199,7 +2193,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
         println!("          native bytes: {}", stats.native_lib_bytes);
         println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
         println!("       macro def bytes: {}", stats.macro_defs_bytes);
-        println!(" unboxed closure bytes: {}", stats.unboxed_closure_bytes);
+        println!("         closure bytes: {}", stats.closure_bytes);
         println!("            impl bytes: {}", stats.impl_bytes);
         println!("            misc bytes: {}", stats.misc_bytes);
         println!("            item bytes: {}", stats.item_bytes);
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 943be282103..cb6b7e56b57 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -57,8 +57,8 @@ pub enum DefIdSource {
     // Identifies a region parameter (`fn foo<'X>() { ... }`).
     RegionParameter,
 
-    // Identifies an unboxed closure
-    UnboxedClosureSource
+    // Identifies a closure
+    ClosureSource
 }
 
 // type conv_did = impl FnMut(DefIdSource, ast::DefId) -> ast::DefId;
@@ -537,11 +537,11 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
       }
       'k' => {
           assert_eq!(next(st), '[');
-          let did = parse_def_(st, UnboxedClosureSource, conv);
+          let did = parse_def_(st, ClosureSource, conv);
           let region = parse_region_(st, conv);
           let substs = parse_substs_(st, conv);
           assert_eq!(next(st), ']');
-          return ty::mk_unboxed_closure(st.tcx, did,
+          return ty::mk_closure(st.tcx, did,
                   st.tcx.mk_region(region), st.tcx.mk_substs(substs));
       }
       'P' => {
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 9aead5bf4e7..54b930fbda9 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -139,7 +139,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
             enc_substs(w, cx, substs);
             mywrite!(w, "]");
         }
-        ty::ty_unboxed_closure(def, region, substs) => {
+        ty::ty_closure(def, region, substs) => {
             mywrite!(w, "k[{}|", (cx.ds)(def));
             enc_region(w, cx, *region);
             enc_substs(w, cx, substs);
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 430b63f81c8..fcc2be985a5 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -21,7 +21,7 @@ use metadata::encoder as e;
 use middle::region;
 use metadata::tydecode;
 use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
-use metadata::tydecode::{RegionParameter, UnboxedClosureSource};
+use metadata::tydecode::{RegionParameter, ClosureSource};
 use metadata::tyencode;
 use middle::mem_categorization::Typer;
 use middle::subst;
@@ -448,10 +448,8 @@ impl tr for def::Def {
           def::DefPrimTy(p) => def::DefPrimTy(p),
           def::DefTyParam(s, index, def_id, n) => def::DefTyParam(s, index, def_id.tr(dcx), n),
           def::DefUse(did) => def::DefUse(did.tr(dcx)),
-          def::DefUpvar(nid1, nid2, nid3) => {
-            def::DefUpvar(dcx.tr_id(nid1),
-                           dcx.tr_id(nid2),
-                           dcx.tr_id(nid3))
+          def::DefUpvar(nid1, nid2) => {
+            def::DefUpvar(dcx.tr_id(nid1), dcx.tr_id(nid2))
           }
           def::DefStruct(did) => def::DefStruct(did.tr(dcx)),
           def::DefRegion(nid) => def::DefRegion(dcx.tr_id(nid)),
@@ -618,8 +616,8 @@ impl<'tcx> tr for MethodOrigin<'tcx> {
     fn tr(&self, dcx: &DecodeContext) -> MethodOrigin<'tcx> {
         match *self {
             ty::MethodStatic(did) => ty::MethodStatic(did.tr(dcx)),
-            ty::MethodStaticUnboxedClosure(did) => {
-                ty::MethodStaticUnboxedClosure(did.tr(dcx))
+            ty::MethodStaticClosure(did) => {
+                ty::MethodStaticClosure(did.tr(dcx))
             }
             ty::MethodTypeParam(ref mp) => {
                 ty::MethodTypeParam(
@@ -643,24 +641,23 @@ impl<'tcx> tr for MethodOrigin<'tcx> {
     }
 }
 
-pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
-                                   kind: ty::UnboxedClosureKind) {
+pub fn encode_closure_kind(ebml_w: &mut Encoder, kind: ty::ClosureKind) {
     use serialize::Encoder;
 
-    ebml_w.emit_enum("UnboxedClosureKind", |ebml_w| {
+    ebml_w.emit_enum("ClosureKind", |ebml_w| {
         match kind {
-            ty::FnUnboxedClosureKind => {
-                ebml_w.emit_enum_variant("FnUnboxedClosureKind", 0, 3, |_| {
+            ty::FnClosureKind => {
+                ebml_w.emit_enum_variant("FnClosureKind", 0, 3, |_| {
                     Ok(())
                 })
             }
-            ty::FnMutUnboxedClosureKind => {
-                ebml_w.emit_enum_variant("FnMutUnboxedClosureKind", 1, 3, |_| {
+            ty::FnMutClosureKind => {
+                ebml_w.emit_enum_variant("FnMutClosureKind", 1, 3, |_| {
                     Ok(())
                 })
             }
-            ty::FnOnceUnboxedClosureKind => {
-                ebml_w.emit_enum_variant("FnOnceUnboxedClosureKind",
+            ty::FnOnceClosureKind => {
+                ebml_w.emit_enum_variant("FnOnceClosureKind",
                                          2,
                                          3,
                                          |_| {
@@ -736,7 +733,7 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
             this.read_enum_variant(&["vtable_static",
                                      "vtable_param",
                                      "vtable_error",
-                                     "vtable_unboxed_closure"],
+                                     "vtable_closure"],
                                    |this, i| {
                 Ok(match i {
                   0 => {
@@ -763,7 +760,7 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
                     )
                   }
                   2 => {
-                    ty::vtable_unboxed_closure(
+                    ty::vtable_closure(
                         this.read_enum_variant_arg(0u, |this| {
                             Ok(this.read_def_id_nodcx(cdata))
                         }).unwrap()
@@ -865,8 +862,8 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
                     })
                 }
 
-                ty::MethodStaticUnboxedClosure(def_id) => {
-                    this.emit_enum_variant("MethodStaticUnboxedClosure", 1, 1, |this| {
+                ty::MethodStaticClosure(def_id) => {
+                    this.emit_enum_variant("MethodStaticClosure", 1, 1, |this| {
                         Ok(this.emit_def_id(def_id))
                     })
                 }
@@ -1322,15 +1319,12 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         })
     }
 
-    for unboxed_closure in tcx.unboxed_closures
-                              .borrow()
-                              .get(&ast_util::local_def(id))
-                              .iter() {
-        rbml_w.tag(c::tag_table_unboxed_closures, |rbml_w| {
+    for closure in tcx.closures.borrow().get(&ast_util::local_def(id)).iter() {
+        rbml_w.tag(c::tag_table_closures, |rbml_w| {
             rbml_w.id(id);
             rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_closure_type(ecx, &unboxed_closure.closure_type);
-                encode_unboxed_closure_kind(rbml_w, unboxed_closure.kind)
+                rbml_w.emit_closure_type(ecx, &closure.closure_type);
+                encode_closure_kind(rbml_w, closure.kind)
             })
         })
     }
@@ -1369,8 +1363,8 @@ trait rbml_decoder_decoder_helpers<'tcx> {
                            -> subst::Substs<'tcx>;
     fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                                     -> ty::AutoAdjustment<'tcx>;
-    fn read_unboxed_closure<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-                                    -> ty::UnboxedClosure<'tcx>;
+    fn read_closure<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
+                            -> ty::Closure<'tcx>;
     fn read_auto_deref_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                                    -> ty::AutoDerefRef<'tcx>;
     fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@@ -1436,7 +1430,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                                   -> ty::MethodOrigin<'tcx>
     {
         self.read_enum("MethodOrigin", |this| {
-            let variants = &["MethodStatic", "MethodStaticUnboxedClosure",
+            let variants = &["MethodStatic", "MethodStaticClosure",
                              "MethodTypeParam", "MethodTraitObject"];
             this.read_enum_variant(variants, |this, i| {
                 Ok(match i {
@@ -1447,7 +1441,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
 
                     1 => {
                         let def_id = this.read_def_id(dcx);
-                        ty::MethodStaticUnboxedClosure(def_id)
+                        ty::MethodStaticClosure(def_id)
                     }
 
                     2 => {
@@ -1797,8 +1791,8 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
         }).unwrap()
     }
 
-    fn read_unboxed_closure<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-                                    -> ty::UnboxedClosure<'tcx> {
+    fn read_closure<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
+                            -> ty::Closure<'tcx> {
         let closure_type = self.read_opaque(|this, doc| {
             Ok(tydecode::parse_ty_closure_data(
                 doc.data,
@@ -1808,21 +1802,21 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                 |s, a| this.convert_def_id(dcx, s, a)))
         }).unwrap();
         let variants = &[
-            "FnUnboxedClosureKind",
-            "FnMutUnboxedClosureKind",
-            "FnOnceUnboxedClosureKind"
+            "FnClosureKind",
+            "FnMutClosureKind",
+            "FnOnceClosureKind"
         ];
-        let kind = self.read_enum("UnboxedClosureKind", |this| {
+        let kind = self.read_enum("ClosureKind", |this| {
             this.read_enum_variant(variants, |_, i| {
                 Ok(match i {
-                    0 => ty::FnUnboxedClosureKind,
-                    1 => ty::FnMutUnboxedClosureKind,
-                    2 => ty::FnOnceUnboxedClosureKind,
-                    _ => panic!("bad enum variant for ty::UnboxedClosureKind"),
+                    0 => ty::FnClosureKind,
+                    1 => ty::FnMutClosureKind,
+                    2 => ty::FnOnceClosureKind,
+                    _ => panic!("bad enum variant for ty::ClosureKind"),
                 })
             })
         }).unwrap();
-        ty::UnboxedClosure {
+        ty::Closure {
             closure_type: closure_type,
             kind: kind,
         }
@@ -1864,7 +1858,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                       -> ast::DefId {
         let r = match source {
             NominalType | TypeWithId | RegionParameter => dcx.tr_def_id(did),
-            TypeParameter | UnboxedClosureSource => dcx.tr_intern_def_id(did)
+            TypeParameter | ClosureSource => dcx.tr_intern_def_id(did)
         };
         debug!("convert_def_id(source={:?}, did={:?})={:?}", source, did, r);
         return r;
@@ -1959,14 +1953,11 @@ fn decode_side_tables(dcx: &DecodeContext,
                         let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx);
                         dcx.tcx.adjustments.borrow_mut().insert(id, adj);
                     }
-                    c::tag_table_unboxed_closures => {
-                        let unboxed_closure =
-                            val_dsr.read_unboxed_closure(dcx);
-                        dcx.tcx
-                           .unboxed_closures
-                           .borrow_mut()
-                           .insert(ast_util::local_def(id),
-                                   unboxed_closure);
+                    c::tag_table_closures => {
+                        let closure =
+                            val_dsr.read_closure(dcx);
+                        dcx.tcx.closures.borrow_mut().insert(ast_util::local_def(id),
+                                                             closure);
                     }
                     _ => {
                         dcx.tcx.sess.bug(
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 2e40bdd001a..3db931002d2 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -100,7 +100,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                             None => self.check_def_id(def_id)
                         }
                     }
-                    ty::MethodStaticUnboxedClosure(_) => {}
+                    ty::MethodStaticClosure(_) => {}
                     ty::MethodTypeParam(ty::MethodParam {
                         ref trait_ref,
                         method_num: index,
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index 2e4aa787e84..2043dde72f4 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -43,9 +43,7 @@ pub enum Def {
     DefTyParam(ParamSpace, u32, ast::DefId, ast::Name),
     DefUse(ast::DefId),
     DefUpvar(ast::NodeId,  // id of closed over local
-             ast::NodeId,  // expr node that creates the closure
-             ast::NodeId), // block node for the closest enclosing proc
-                           // or unboxed closure, DUMMY_NODE_ID otherwise
+             ast::NodeId), // expr node that creates the closure
 
     /// Note that if it's a tuple struct's definition, the node id of the ast::DefId
     /// may either refer to the item definition's id or the StructDef.ctor_id.
@@ -145,7 +143,7 @@ impl Def {
             }
             DefLocal(id) |
             DefSelfTy(id) |
-            DefUpvar(id, _, _) |
+            DefUpvar(id, _) |
             DefRegion(id) |
             DefTyParamBinder(id) |
             DefLabel(id) => {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index d9ab86deb3b..70a7b4f13cc 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -26,7 +26,7 @@ use middle::mem_categorization::Typer;
 use middle::ty::{self};
 use middle::ty::{MethodCall, MethodObject, MethodTraitObject};
 use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
-use middle::ty::{MethodStatic, MethodStaticUnboxedClosure};
+use middle::ty::{MethodStatic, MethodStaticClosure};
 use util::ppaux::Repr;
 
 use std::marker;
@@ -257,13 +257,13 @@ impl OverloadedCallType {
         OverloadedCallType::from_trait_id(tcx, trait_ref.def_id)
     }
 
-    fn from_unboxed_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
-                            -> OverloadedCallType {
+    fn from_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
+                    -> OverloadedCallType {
         let trait_did =
-            tcx.unboxed_closures
+            tcx.closures
                .borrow()
                .get(&closure_did)
-               .expect("OverloadedCallType::from_unboxed_closure: didn't \
+               .expect("OverloadedCallType::from_closure: didn't \
                         find closure id")
                .kind
                .trait_did(tcx);
@@ -276,8 +276,8 @@ impl OverloadedCallType {
             MethodStatic(def_id) => {
                 OverloadedCallType::from_method_id(tcx, def_id)
             }
-            MethodStaticUnboxedClosure(def_id) => {
-                OverloadedCallType::from_unboxed_closure(tcx, def_id)
+            MethodStaticClosure(def_id) => {
+                OverloadedCallType::from_closure(tcx, def_id)
             }
             MethodTypeParam(MethodParam { ref trait_ref, .. }) |
             MethodTraitObject(MethodObject { ref trait_ref, .. }) => {
diff --git a/src/librustc/middle/fast_reject.rs b/src/librustc/middle/fast_reject.rs
index 42bc70b5b56..b33e5a802f1 100644
--- a/src/librustc/middle/fast_reject.rs
+++ b/src/librustc/middle/fast_reject.rs
@@ -28,7 +28,7 @@ pub enum SimplifiedType {
     TupleSimplifiedType(uint),
     TraitSimplifiedType(ast::DefId),
     StructSimplifiedType(ast::DefId),
-    UnboxedClosureSimplifiedType(ast::DefId),
+    ClosureSimplifiedType(ast::DefId),
     FunctionSimplifiedType(uint),
     ParameterSimplifiedType,
 }
@@ -74,8 +74,8 @@ pub fn simplify_type(tcx: &ty::ctxt,
             let def_id = tcx.lang_items.owned_box().unwrap();
             Some(StructSimplifiedType(def_id))
         }
-        ty::ty_unboxed_closure(def_id, _, _) => {
-            Some(UnboxedClosureSimplifiedType(def_id))
+        ty::ty_closure(def_id, _, _) => {
+            Some(ClosureSimplifiedType(def_id))
         }
         ty::ty_tup(ref tys) => {
             Some(TupleSimplifiedType(tys.len()))
diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index 3280769ff03..04b3b55df8d 100644
--- a/src/librustc/middle/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -52,7 +52,7 @@ use middle::ty_fold::{TypeFoldable};
 use util::ppaux::Repr;
 
 use std::rc::Rc;
-use syntax::ast::{Onceness, Unsafety};
+use syntax::ast::Unsafety;
 use syntax::ast;
 use syntax::abi;
 use syntax::codemap::Span;
@@ -254,8 +254,6 @@ pub trait Combine<'tcx> : Sized {
         }
     }
 
-    fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness>;
-
     fn projection_tys(&self,
                       a: &ty::ProjectionTy<'tcx>,
                       b: &ty::ProjectionTy<'tcx>)
@@ -514,15 +512,15 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
             Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs)))
       }
 
-      (&ty::ty_unboxed_closure(a_id, a_region, a_substs),
-       &ty::ty_unboxed_closure(b_id, b_region, b_substs))
+      (&ty::ty_closure(a_id, a_region, a_substs),
+       &ty::ty_closure(b_id, b_region, b_substs))
       if a_id == b_id => {
-          // All ty_unboxed_closure types with the same id represent
+          // All ty_closure types with the same id represent
           // the (anonymous) type of the same closure expression. So
           // all of their regions should be equated.
           let region = try!(this.equate().regions(*a_region, *b_region));
           let substs = try!(this.substs_variances(None, a_substs, b_substs));
-          Ok(ty::mk_unboxed_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs)))
+          Ok(ty::mk_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs)))
       }
 
       (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
diff --git a/src/librustc/middle/infer/equate.rs b/src/librustc/middle/infer/equate.rs
index f6ac7461567..f0bde222864 100644
--- a/src/librustc/middle/infer/equate.rs
+++ b/src/librustc/middle/infer/equate.rs
@@ -21,7 +21,7 @@ use middle::infer::{TypeTrace, Subtype};
 use middle::infer::type_variable::{EqTo};
 use util::ppaux::{Repr};
 
-use syntax::ast::{Onceness, Unsafety};
+use syntax::ast::Unsafety;
 
 pub struct Equate<'f, 'tcx: 'f> {
     fields: CombineFields<'f, 'tcx>
@@ -78,14 +78,6 @@ impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
         }
     }
 
-    fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness> {
-        if a != b {
-            Err(ty::terr_onceness_mismatch(expected_found(self, a, b)))
-        } else {
-            Ok(a)
-        }
-    }
-
     fn builtin_bounds(&self,
                       a: BuiltinBounds,
                       b: BuiltinBounds)
diff --git a/src/librustc/middle/infer/freshen.rs b/src/librustc/middle/infer/freshen.rs
index 6bc424fdf95..8e9911aaefa 100644
--- a/src/librustc/middle/infer/freshen.rs
+++ b/src/librustc/middle/infer/freshen.rs
@@ -151,7 +151,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
             ty::ty_bare_fn(..) |
             ty::ty_trait(..) |
             ty::ty_struct(..) |
-            ty::ty_unboxed_closure(..) |
+            ty::ty_closure(..) |
             ty::ty_tup(..) |
             ty::ty_projection(..) |
             ty::ty_param(..) => {
diff --git a/src/librustc/middle/infer/glb.rs b/src/librustc/middle/infer/glb.rs
index 2683d00b858..ff0c2d92f45 100644
--- a/src/librustc/middle/infer/glb.rs
+++ b/src/librustc/middle/infer/glb.rs
@@ -19,8 +19,7 @@ use super::{TypeTrace, Subtype};
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
-use syntax::ast::{Many, Once, MutImmutable, MutMutable};
-use syntax::ast::{Onceness, Unsafety};
+use syntax::ast::{MutImmutable, MutMutable, Unsafety};
 use util::ppaux::mt_to_string;
 use util::ppaux::Repr;
 
@@ -87,13 +86,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
         }
     }
 
-    fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness> {
-        match (a, b) {
-            (Many, _) | (_, Many) => Ok(Many),
-            (Once, Once) => Ok(Once)
-        }
-    }
-
     fn builtin_bounds(&self,
                       a: ty::BuiltinBounds,
                       b: ty::BuiltinBounds)
diff --git a/src/librustc/middle/infer/lub.rs b/src/librustc/middle/infer/lub.rs
index e4cab0f8899..204560e87ee 100644
--- a/src/librustc/middle/infer/lub.rs
+++ b/src/librustc/middle/infer/lub.rs
@@ -19,9 +19,7 @@ use super::{TypeTrace, Subtype};
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
-use syntax::ast::{Many, Once};
-use syntax::ast::{Onceness, Unsafety};
-use syntax::ast::{MutMutable, MutImmutable};
+use syntax::ast::{MutMutable, MutImmutable, Unsafety};
 use util::ppaux::mt_to_string;
 use util::ppaux::Repr;
 
@@ -83,13 +81,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
         }
     }
 
-    fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness> {
-        match (a, b) {
-            (Once, _) | (_, Once) => Ok(Once),
-            (Many, Many) => Ok(Many)
-        }
-    }
-
     fn builtin_bounds(&self,
                       a: ty::BuiltinBounds,
                       b: ty::BuiltinBounds)
diff --git a/src/librustc/middle/infer/sub.rs b/src/librustc/middle/infer/sub.rs
index 4f8364fa44a..1e0d14544ff 100644
--- a/src/librustc/middle/infer/sub.rs
+++ b/src/librustc/middle/infer/sub.rs
@@ -23,7 +23,7 @@ use middle::ty::{self, Ty};
 use middle::ty::TyVar;
 use util::ppaux::{Repr};
 
-use syntax::ast::{Onceness, MutImmutable, MutMutable, Unsafety};
+use syntax::ast::{MutImmutable, MutMutable, Unsafety};
 
 
 /// "Greatest lower bound" (common subtype)
@@ -99,12 +99,6 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
         })
     }
 
-    fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness> {
-        self.lub().oncenesses(a, b).compare(b, || {
-            ty::terr_onceness_mismatch(expected_found(self, a, b))
-        })
-    }
-
     fn builtin_bounds(&self, a: BuiltinBounds, b: BuiltinBounds)
                       -> cres<'tcx, BuiltinBounds> {
         // More bounds is a subtype of fewer bounds.
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 2c0de9d1634..c1ce5945946 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -113,11 +113,11 @@ impl LanguageItems {
         }
     }
 
-    pub fn fn_trait_kind(&self, id: ast::DefId) -> Option<ty::UnboxedClosureKind> {
+    pub fn fn_trait_kind(&self, id: ast::DefId) -> Option<ty::ClosureKind> {
         let def_id_kinds = [
-            (self.fn_trait(), ty::FnUnboxedClosureKind),
-            (self.fn_mut_trait(), ty::FnMutUnboxedClosureKind),
-            (self.fn_once_trait(), ty::FnOnceUnboxedClosureKind),
+            (self.fn_trait(), ty::FnClosureKind),
+            (self.fn_mut_trait(), ty::FnMutClosureKind),
+            (self.fn_once_trait(), ty::FnOnceClosureKind),
             ];
 
         for &(opt_def_id, kind) in def_id_kinds.iter() {
@@ -328,4 +328,6 @@ lets_do_this! {
     IteratorItem,                    "iterator",                iterator;
 
     StackExhaustedLangItem,          "stack_exhausted",         stack_exhausted;
+
+    DebugTraitLangItem,              "debug_trait",             debug_trait;
 }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index c08af95f139..0131b9f1491 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -114,7 +114,7 @@ use middle::mem_categorization::Typer;
 use middle::pat_util;
 use middle::region::CodeExtent;
 use middle::ty;
-use middle::ty::UnboxedClosureTyper;
+use middle::ty::ClosureTyper;
 use lint;
 use util::nodemap::NodeMap;
 
@@ -1519,8 +1519,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> {
         let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
         match fn_ty.sty {
-            ty::ty_unboxed_closure(closure_def_id, _, substs) =>
-                self.ir.tcx.unboxed_closure_type(closure_def_id, substs).sig.output(),
+            ty::ty_closure(closure_def_id, _, substs) =>
+                self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
             _ =>
                 ty::ty_fn_ret(fn_ty),
         }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 90fe6b49911..9954aa39226 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -104,10 +104,7 @@ pub enum categorization<'tcx> {
 #[derive(Clone, Copy, PartialEq, Show)]
 pub struct Upvar {
     pub id: ty::UpvarId,
-    // Unboxed closure kinds are used even for old-style closures for simplicity
-    pub kind: ty::UnboxedClosureKind,
-    // Is this from an unboxed closure?  Used only for diagnostics.
-    pub is_unboxed: bool
+    pub kind: ty::ClosureKind
 }
 
 // different kinds of pointers:
@@ -269,7 +266,7 @@ pub type McResult<T> = Result<T, ()>;
 /// In the borrow checker, in contrast, type checking is complete and we
 /// know that no errors have occurred, so we simply consult the tcx and we
 /// can be sure that only `Ok` results will occur.
-pub trait Typer<'tcx> : ty::UnboxedClosureTyper<'tcx> {
+pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
     fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;
     fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>>;
@@ -593,13 +590,13 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
               }))
           }
 
-          def::DefUpvar(var_id, fn_node_id, _) => {
+          def::DefUpvar(var_id, fn_node_id) => {
               let ty = try!(self.node_ty(fn_node_id));
               match ty.sty {
-                  ty::ty_unboxed_closure(closure_id, _, _) => {
-                      let kind = self.typer.unboxed_closure_kind(closure_id);
+                  ty::ty_closure(closure_id, _, _) => {
+                      let kind = self.typer.closure_kind(closure_id);
                       let mode = self.typer.capture_mode(fn_node_id);
-                      self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, true)
+                      self.cat_upvar(id, span, var_id, fn_node_id, kind, mode)
                   }
                   _ => {
                       self.tcx().sess.span_bug(
@@ -631,9 +628,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                  span: Span,
                  var_id: ast::NodeId,
                  fn_node_id: ast::NodeId,
-                 kind: ty::UnboxedClosureKind,
-                 mode: ast::CaptureClause,
-                 is_unboxed: bool)
+                 kind: ty::ClosureKind,
+                 mode: ast::CaptureClause)
                  -> McResult<cmt<'tcx>> {
         // An upvar can have up to 3 components.  The base is a
         // `cat_upvar`.  Next, we add a deref through the implicit
@@ -654,8 +650,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         // Fn             | copied -> &'env      | upvar -> &'env -> &'up bk
         // FnMut          | copied -> &'env mut  | upvar -> &'env mut -> &'up bk
         // FnOnce         | copied               | upvar -> &'up bk
-        // old stack      | N/A                  | upvar -> &'env mut -> &'up bk
-        // old proc/once  | copied               | N/A
         let var_ty = try!(self.node_ty(var_id));
 
         let upvar_id = ty::UpvarId { var_id: var_id,
@@ -666,12 +660,12 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
 
         // Construct information about env pointer dereference, if any
         let mutbl = match kind {
-            ty::FnOnceUnboxedClosureKind => None, // None, env is by-value
-            ty::FnMutUnboxedClosureKind => match mode { // Depends on capture type
+            ty::FnOnceClosureKind => None, // None, env is by-value
+            ty::FnMutClosureKind => match mode { // Depends on capture type
                 ast::CaptureByValue => Some(var_mutbl), // Mutable if the original var is
                 ast::CaptureByRef => Some(McDeclared) // Mutable regardless
             },
-            ty::FnUnboxedClosureKind => Some(McImmutable) // Never mutable
+            ty::FnClosureKind => Some(McImmutable) // Never mutable
         };
         let env_info = mutbl.map(|env_mutbl| {
             // Look up the node ID of the closure body so we can construct
@@ -711,8 +705,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                     span: span,
                     cat: cat_upvar(Upvar {
                         id: upvar_id,
-                        kind: kind,
-                        is_unboxed: is_unboxed
+                        kind: kind
                     }),
                     mutbl: var_mutbl,
                     ty: var_ty,
@@ -751,8 +744,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                     span: span,
                     cat: cat_upvar(Upvar {
                         id: upvar_id,
-                        kind: kind,
-                        is_unboxed: is_unboxed
+                        kind: kind
                     }),
                     mutbl: McImmutable,
                     ty: self.tcx().types.err,
@@ -1566,7 +1558,7 @@ fn element_kind(t: Ty) -> ElementKind {
     }
 }
 
-impl<'tcx> Repr<'tcx> for ty::UnboxedClosureKind {
+impl<'tcx> Repr<'tcx> for ty::ClosureKind {
     fn repr(&self, _: &ty::ctxt) -> String {
         format!("Upvar({:?})", self)
     }
@@ -1581,9 +1573,9 @@ impl<'tcx> Repr<'tcx> for Upvar {
 impl<'tcx> UserString<'tcx> for Upvar {
     fn user_string(&self, _: &ty::ctxt) -> String {
         let kind = match self.kind {
-            ty::FnUnboxedClosureKind => "Fn",
-            ty::FnMutUnboxedClosureKind => "FnMut",
-            ty::FnOnceUnboxedClosureKind => "FnOnce",
+            ty::FnClosureKind => "Fn",
+            ty::FnMutClosureKind => "FnMut",
+            ty::FnOnceClosureKind => "FnOnce",
         };
         format!("captured outer variable in an `{}` closure", kind)
     }
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 714dd7d98cf..7b5af0ab1aa 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -311,7 +311,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
                         ty::MethodStatic(def_id) => {
                             def_id
                         }
-                        ty::MethodStaticUnboxedClosure(def_id) => {
+                        ty::MethodStaticClosure(def_id) => {
                             def_id
                         }
                         ty::MethodTypeParam(ty::MethodParam {
diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs
index b6d45ab89e7..e3363aa8fb7 100644
--- a/src/librustc/middle/traits/coherence.rs
+++ b/src/librustc/middle/traits/coherence.rs
@@ -138,7 +138,7 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
             tt.principal_def_id().krate == ast::LOCAL_CRATE
         }
 
-        ty::ty_unboxed_closure(..) |
+        ty::ty_closure(..) |
         ty::ty_infer(..) |
         ty::ty_open(..) |
         ty::ty_err => {
diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs
index 568286e39d5..d08857c9613 100644
--- a/src/librustc/middle/traits/fulfill.rs
+++ b/src/librustc/middle/traits/fulfill.rs
@@ -110,7 +110,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
     /// `projection_ty` again.
     pub fn normalize_projection_type<'a>(&mut self,
                                          infcx: &InferCtxt<'a,'tcx>,
-                                         typer: &ty::UnboxedClosureTyper<'tcx>,
+                                         typer: &ty::ClosureTyper<'tcx>,
                                          projection_ty: ty::ProjectionTy<'tcx>,
                                          cause: ObligationCause<'tcx>)
                                          -> Ty<'tcx>
@@ -186,7 +186,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
 
     pub fn select_all_or_error<'a>(&mut self,
                                    infcx: &InferCtxt<'a,'tcx>,
-                                   typer: &ty::UnboxedClosureTyper<'tcx>)
+                                   typer: &ty::ClosureTyper<'tcx>)
                                    -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
         try!(self.select_where_possible(infcx, typer));
@@ -211,7 +211,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
     /// results in `O(n^2)` performance (#18208).
     pub fn select_new_obligations<'a>(&mut self,
                                       infcx: &InferCtxt<'a,'tcx>,
-                                      typer: &ty::UnboxedClosureTyper<'tcx>)
+                                      typer: &ty::ClosureTyper<'tcx>)
                                       -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
         let mut selcx = SelectionContext::new(infcx, typer);
@@ -220,7 +220,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
 
     pub fn select_where_possible<'a>(&mut self,
                                      infcx: &InferCtxt<'a,'tcx>,
-                                     typer: &ty::UnboxedClosureTyper<'tcx>)
+                                     typer: &ty::ClosureTyper<'tcx>)
                                      -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
         let mut selcx = SelectionContext::new(infcx, typer);
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index 89459f95b87..8d3888fcfdb 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -232,11 +232,10 @@ pub enum Vtable<'tcx, N> {
     /// Successful resolution for a builtin trait.
     VtableBuiltin(VtableBuiltinData<N>),
 
-    /// Vtable automatically generated for an unboxed closure. The def
-    /// ID is the ID of the closure expression. This is a `VtableImpl`
-    /// in spirit, but the impl is generated by the compiler and does
-    /// not appear in the source.
-    VtableUnboxedClosure(ast::DefId, subst::Substs<'tcx>),
+    /// Vtable automatically generated for a closure. The def ID is the ID
+    /// of the closure expression. This is a `VtableImpl` in spirit, but the
+    /// impl is generated by the compiler and does not appear in the source.
+    VtableClosure(ast::DefId, subst::Substs<'tcx>),
 
     /// Same as above, but for a fn pointer type with the given signature.
     VtableFnPointer(ty::Ty<'tcx>),
@@ -296,7 +295,7 @@ pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
 /// conservative towards *no impl*, which is the opposite of the
 /// `evaluate` methods).
 pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
-                                       typer: &ty::UnboxedClosureTyper<'tcx>,
+                                       typer: &ty::ClosureTyper<'tcx>,
                                        ty: Ty<'tcx>,
                                        bound: ty::BuiltinBound,
                                        span: Span)
@@ -361,7 +360,7 @@ pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
 }
 
 pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
-                                                 typer: &ty::UnboxedClosureTyper<'tcx>,
+                                                 typer: &ty::ClosureTyper<'tcx>,
                                                  ty: Ty<'tcx>,
                                                  bound: ty::BuiltinBound,
                                                  span: Span)
@@ -446,7 +445,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
         match *self {
             VtableImpl(ref i) => i.iter_nested(),
             VtableFnPointer(..) => (&[]).iter(),
-            VtableUnboxedClosure(..) => (&[]).iter(),
+            VtableClosure(..) => (&[]).iter(),
             VtableParam(ref n) => n.iter(),
             VtableObject(_) => (&[]).iter(),
             VtableBuiltin(ref i) => i.iter_nested(),
@@ -457,7 +456,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
         match *self {
             VtableImpl(ref i) => VtableImpl(i.map_nested(op)),
             VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
-            VtableUnboxedClosure(d, ref s) => VtableUnboxedClosure(d, s.clone()),
+            VtableClosure(d, ref s) => VtableClosure(d, s.clone()),
             VtableParam(ref n) => VtableParam(n.iter().map(op).collect()),
             VtableObject(ref p) => VtableObject(p.clone()),
             VtableBuiltin(ref b) => VtableBuiltin(b.map_nested(op)),
@@ -470,7 +469,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
         match self {
             VtableImpl(i) => VtableImpl(i.map_move_nested(op)),
             VtableFnPointer(sig) => VtableFnPointer(sig),
-            VtableUnboxedClosure(d, s) => VtableUnboxedClosure(d, s),
+            VtableClosure(d, s) => VtableClosure(d, s),
             VtableParam(n) => VtableParam(n.into_iter().map(op).collect()),
             VtableObject(p) => VtableObject(p),
             VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)),
diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs
index 95a938328cf..ffb38091a87 100644
--- a/src/librustc/middle/traits/project.rs
+++ b/src/librustc/middle/traits/project.rs
@@ -579,7 +579,7 @@ fn assemble_candidates_from_impls<'cx,'tcx>(
             // in `assemble_candidates_from_param_env`.
         }
         super::VtableBuiltin(..) |
-        super::VtableUnboxedClosure(..) |
+        super::VtableClosure(..) |
         super::VtableFnPointer(..) => {
             // These traits have no associated types.
             selcx.tcx().sess.span_bug(
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index e8d82150ade..b2e8bbe059f 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -25,7 +25,7 @@ use super::{ObligationCauseCode, BuiltinDerivedObligation};
 use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
 use super::{Selection};
 use super::{SelectionResult};
-use super::{VtableBuiltin, VtableImpl, VtableParam, VtableUnboxedClosure,
+use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
             VtableFnPointer, VtableObject};
 use super::{VtableImplData, VtableObjectData, VtableBuiltinData};
 use super::object_safety;
@@ -47,7 +47,7 @@ use util::ppaux::Repr;
 
 pub struct SelectionContext<'cx, 'tcx:'cx> {
     infcx: &'cx InferCtxt<'cx, 'tcx>,
-    closure_typer: &'cx (ty::UnboxedClosureTyper<'tcx>+'cx),
+    closure_typer: &'cx (ty::ClosureTyper<'tcx>+'cx),
 
     /// Freshener used specifically for skolemizing entries on the
     /// obligation stack. This ensures that all entries on the stack
@@ -143,7 +143,7 @@ enum SelectionCandidate<'tcx> {
 
     /// Implementation of a `Fn`-family trait by one of the
     /// anonymous types generated for a `||` expression.
-    UnboxedClosureCandidate(/* closure */ ast::DefId, Substs<'tcx>),
+    ClosureCandidate(/* closure */ ast::DefId, Substs<'tcx>),
 
     /// Implementation of a `Fn`-family trait by one of the anonymous
     /// types generated for a fn pointer type (e.g., `fn(int)->int`)
@@ -181,7 +181,7 @@ enum EvaluationResult<'tcx> {
 
 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
-               closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
+               closure_typer: &'cx ty::ClosureTyper<'tcx>)
                -> SelectionContext<'cx, 'tcx> {
         SelectionContext {
             infcx: infcx,
@@ -192,7 +192,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>,
-                      closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
+                      closure_typer: &'cx ty::ClosureTyper<'tcx>)
                       -> SelectionContext<'cx, 'tcx> {
         SelectionContext {
             infcx: infcx,
@@ -751,7 +751,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // For the time being, we ignore user-defined impls for builtin-bounds, other than
                 // `Copy`.
                 // (And unboxed candidates only apply to the Fn/FnMut/etc traits.)
-                try!(self.assemble_unboxed_closure_candidates(obligation, &mut candidates));
+                try!(self.assemble_closure_candidates(obligation, &mut candidates));
                 try!(self.assemble_fn_pointer_candidates(obligation, &mut candidates));
                 try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
                 self.assemble_candidates_from_object_ty(obligation, &mut candidates);
@@ -943,15 +943,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     /// Check for the artificial impl that the compiler will create for an obligation like `X :
-    /// FnMut<..>` where `X` is an unboxed closure type.
+    /// FnMut<..>` where `X` is a closure type.
     ///
-    /// Note: the type parameters on an unboxed closure candidate are modeled as *output* type
+    /// Note: the type parameters on a closure candidate are modeled as *output* type
     /// parameters and hence do not affect whether this trait is a match or not. They will be
     /// unified during the confirmation step.
-    fn assemble_unboxed_closure_candidates(&mut self,
-                                           obligation: &TraitObligation<'tcx>,
-                                           candidates: &mut SelectionCandidateSet<'tcx>)
-                                           -> Result<(),SelectionError<'tcx>>
+    fn assemble_closure_candidates(&mut self,
+                                   obligation: &TraitObligation<'tcx>,
+                                   candidates: &mut SelectionCandidateSet<'tcx>)
+                                   -> Result<(),SelectionError<'tcx>>
     {
         let kind = match self.fn_family_trait_kind(obligation.predicate.0.def_id()) {
             Some(k) => k,
@@ -960,7 +960,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
         let (closure_def_id, substs) = match self_ty.sty {
-            ty::ty_unboxed_closure(id, _, ref substs) => (id, substs.clone()),
+            ty::ty_closure(id, _, ref substs) => (id, substs.clone()),
             ty::ty_infer(ty::TyVar(_)) => {
                 candidates.ambiguous = true;
                 return Ok(());
@@ -973,12 +973,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                kind,
                obligation.repr(self.tcx()));
 
-        let closure_kind = self.closure_typer.unboxed_closure_kind(closure_def_id);
+        let closure_kind = self.closure_typer.closure_kind(closure_def_id);
 
         debug!("closure_kind = {:?}", closure_kind);
 
         if closure_kind == kind {
-            candidates.vec.push(UnboxedClosureCandidate(closure_def_id, substs.clone()));
+            candidates.vec.push(ClosureCandidate(closure_def_id, substs.clone()));
         }
 
         Ok(())
@@ -1453,7 +1453,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 Ok(If(tys.clone()))
             }
 
-            ty::ty_unboxed_closure(def_id, _, substs) => {
+            ty::ty_closure(def_id, _, substs) => {
                 // FIXME -- This case is tricky. In the case of by-ref
                 // closures particularly, we need the results of
                 // inference to decide how to reflect the type of each
@@ -1471,7 +1471,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     return Ok(ParameterBuiltin);
                 }
 
-                match self.closure_typer.unboxed_closure_upvars(def_id, substs) {
+                match self.closure_typer.closure_upvars(def_id, substs) {
                     Some(upvars) => {
                         Ok(If(upvars.iter().map(|c| c.ty).collect()))
                     }
@@ -1616,9 +1616,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 Ok(VtableImpl(vtable_impl))
             }
 
-            UnboxedClosureCandidate(closure_def_id, substs) => {
-                try!(self.confirm_unboxed_closure_candidate(obligation, closure_def_id, &substs));
-                Ok(VtableUnboxedClosure(closure_def_id, substs))
+            ClosureCandidate(closure_def_id, substs) => {
+                try!(self.confirm_closure_candidate(obligation, closure_def_id, &substs));
+                Ok(VtableClosure(closure_def_id, substs))
             }
 
             ObjectCandidate => {
@@ -1894,20 +1894,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         Ok(self_ty)
     }
 
-    fn confirm_unboxed_closure_candidate(&mut self,
-                                         obligation: &TraitObligation<'tcx>,
-                                         closure_def_id: ast::DefId,
-                                         substs: &Substs<'tcx>)
-                                         -> Result<(),SelectionError<'tcx>>
+    fn confirm_closure_candidate(&mut self,
+                                 obligation: &TraitObligation<'tcx>,
+                                 closure_def_id: ast::DefId,
+                                 substs: &Substs<'tcx>)
+                                 -> Result<(),SelectionError<'tcx>>
     {
-        debug!("confirm_unboxed_closure_candidate({},{},{})",
+        debug!("confirm_closure_candidate({},{},{})",
                obligation.repr(self.tcx()),
                closure_def_id.repr(self.tcx()),
                substs.repr(self.tcx()));
 
-        let closure_type = self.closure_typer.unboxed_closure_type(closure_def_id, substs);
+        let closure_type = self.closure_typer.closure_type(closure_def_id, substs);
 
-        debug!("confirm_unboxed_closure_candidate: closure_def_id={} closure_type={}",
+        debug!("confirm_closure_candidate: closure_def_id={} closure_type={}",
                closure_def_id.repr(self.tcx()),
                closure_type.repr(self.tcx()));
 
@@ -1923,7 +1923,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             substs: self.tcx().mk_substs(trait_substs),
         }));
 
-        debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})",
+        debug!("confirm_closure_candidate(closure_def_id={}, trait_ref={})",
                closure_def_id.repr(self.tcx()),
                trait_ref.repr(self.tcx()));
 
@@ -1932,7 +1932,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                      trait_ref)
     }
 
-    /// In the case of unboxed closure types and fn pointers,
+    /// In the case of closure types and fn pointers,
     /// we currently treat the input type parameters on the trait as
     /// outputs. This means that when we have a match we have only
     /// considered the self type, so we have to go back and make sure
@@ -1942,7 +1942,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// errors as if there is no applicable impl, but rather report
     /// errors are about mismatched argument types.
     ///
-    /// Here is an example. Imagine we have an unboxed closure expression
+    /// Here is an example. Imagine we have an closure expression
     /// and we desugared it so that the type of the expression is
     /// `Closure`, and `Closure` expects an int as argument. Then it
     /// is "as if" the compiler generated this impl:
@@ -2259,15 +2259,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     fn fn_family_trait_kind(&self,
                             trait_def_id: ast::DefId)
-                            -> Option<ty::UnboxedClosureKind>
+                            -> Option<ty::ClosureKind>
     {
         let tcx = self.tcx();
         if Some(trait_def_id) == tcx.lang_items.fn_trait() {
-            Some(ty::FnUnboxedClosureKind)
+            Some(ty::FnClosureKind)
         } else if Some(trait_def_id) == tcx.lang_items.fn_mut_trait() {
-            Some(ty::FnMutUnboxedClosureKind)
+            Some(ty::FnMutClosureKind)
         } else if Some(trait_def_id) == tcx.lang_items.fn_once_trait() {
-            Some(ty::FnOnceUnboxedClosureKind)
+            Some(ty::FnOnceClosureKind)
         } else {
             None
         }
@@ -2318,8 +2318,8 @@ impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
             ObjectCandidate => {
                 format!("ObjectCandidate")
             }
-            UnboxedClosureCandidate(c, ref s) => {
-                format!("UnboxedClosureCandidate({:?},{})", c, s.repr(tcx))
+            ClosureCandidate(c, ref s) => {
+                format!("ClosureCandidate({:?},{})", c, s.repr(tcx))
             }
         }
     }
diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs
index bdf9b16f139..beb28260834 100644
--- a/src/librustc/middle/traits/util.rs
+++ b/src/librustc/middle/traits/util.rs
@@ -367,8 +367,8 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::Vtable<'tcx, N> {
             super::VtableImpl(ref v) =>
                 v.repr(tcx),
 
-            super::VtableUnboxedClosure(ref d, ref s) =>
-                format!("VtableUnboxedClosure({},{})",
+            super::VtableClosure(ref d, ref s) =>
+                format!("VtableClosure({},{})",
                         d.repr(tcx),
                         s.repr(tcx)),
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index d04c2d2d1a0..0ee26ce1cd3 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -16,7 +16,7 @@ pub use self::BuiltinBound::*;
 pub use self::InferTy::*;
 pub use self::InferRegion::*;
 pub use self::ImplOrTraitItemId::*;
-pub use self::UnboxedClosureKind::*;
+pub use self::ClosureKind::*;
 pub use self::ast_ty_to_ty_cache_entry::*;
 pub use self::Variance::*;
 pub use self::AutoAdjustment::*;
@@ -81,8 +81,7 @@ use std::collections::{HashMap, HashSet};
 use syntax::abi;
 use syntax::ast::{CrateNum, DefId, Ident, ItemTrait, LOCAL_CRATE};
 use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
-use syntax::ast::{Onceness, StmtExpr, StmtSemi, StructField, UnnamedField};
-use syntax::ast::{Visibility};
+use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility};
 use syntax::ast_util::{self, is_local, lit_is_str, local_def, PostExpansionMethod};
 use syntax::attr::{self, AttrMetaMethods};
 use syntax::codemap::Span;
@@ -433,8 +432,8 @@ pub enum MethodOrigin<'tcx> {
     // fully statically resolved method
     MethodStatic(ast::DefId),
 
-    // fully statically resolved unboxed closure invocation
-    MethodStaticUnboxedClosure(ast::DefId),
+    // fully statically resolved closure invocation
+    MethodStaticClosure(ast::DefId),
 
     // method invoked on a type parameter with a bounded trait
     MethodTypeParam(MethodParam<'tcx>),
@@ -566,10 +565,10 @@ pub enum vtable_origin<'tcx> {
     vtable_param(param_index, uint),
 
     /*
-      Vtable automatically generated for an unboxed closure. The def ID is the
+      Vtable automatically generated for a closure. The def ID is the
       ID of the closure expression.
      */
-    vtable_unboxed_closure(ast::DefId),
+    vtable_closure(ast::DefId),
 
     /*
       Asked to determine the vtable for ty_err. This is the value used
@@ -786,9 +785,9 @@ pub struct ctxt<'tcx> {
 
     pub dependency_formats: RefCell<dependency_format::Dependencies>,
 
-    /// Records the type of each unboxed closure. The def ID is the ID of the
-    /// expression defining the unboxed closure.
-    pub unboxed_closures: RefCell<DefIdMap<UnboxedClosure<'tcx>>>,
+    /// Records the type of each closure. The def ID is the ID of the
+    /// expression defining the closure.
+    pub closures: RefCell<DefIdMap<Closure<'tcx>>>,
 
     pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
                                               lint::LevelSource>>,
@@ -913,7 +912,7 @@ impl<'tcx> ctxt<'tcx> {
         sty_debug_print!(
             self,
             ty_enum, ty_uniq, ty_vec, ty_ptr, ty_rptr, ty_bare_fn, ty_trait,
-            ty_struct, ty_unboxed_closure, ty_tup, ty_param, ty_open, ty_infer, ty_projection);
+            ty_struct, ty_closure, ty_tup, ty_param, ty_open, ty_infer, ty_projection);
 
         println!("Substs interner: #{}", self.substs_interner.borrow().len());
         println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len());
@@ -1376,7 +1375,7 @@ pub enum sty<'tcx> {
     ty_trait(Box<TyTrait<'tcx>>),
     ty_struct(DefId, &'tcx Substs<'tcx>),
 
-    ty_unboxed_closure(DefId, &'tcx Region, &'tcx Substs<'tcx>),
+    ty_closure(DefId, &'tcx Region, &'tcx Substs<'tcx>),
 
     ty_tup(Vec<Ty<'tcx>>),
 
@@ -1535,7 +1534,6 @@ pub struct expected_found<T> {
 pub enum type_err<'tcx> {
     terr_mismatch,
     terr_unsafety_mismatch(expected_found<ast::Unsafety>),
-    terr_onceness_mismatch(expected_found<Onceness>),
     terr_abi_mismatch(expected_found<abi::Abi>),
     terr_mutability,
     terr_box_mutability,
@@ -2264,30 +2262,30 @@ pub struct ItemSubsts<'tcx> {
     pub substs: Substs<'tcx>,
 }
 
-/// Records information about each unboxed closure.
+/// Records information about each closure.
 #[derive(Clone)]
-pub struct UnboxedClosure<'tcx> {
-    /// The type of the unboxed closure.
+pub struct Closure<'tcx> {
+    /// The type of the closure.
     pub closure_type: ClosureTy<'tcx>,
-    /// The kind of unboxed closure this is.
-    pub kind: UnboxedClosureKind,
+    /// The kind of closure this is.
+    pub kind: ClosureKind,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Show)]
-pub enum UnboxedClosureKind {
-    FnUnboxedClosureKind,
-    FnMutUnboxedClosureKind,
-    FnOnceUnboxedClosureKind,
+pub enum ClosureKind {
+    FnClosureKind,
+    FnMutClosureKind,
+    FnOnceClosureKind,
 }
 
-impl UnboxedClosureKind {
+impl ClosureKind {
     pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
         let result = match *self {
-            FnUnboxedClosureKind => cx.lang_items.require(FnTraitLangItem),
-            FnMutUnboxedClosureKind => {
+            FnClosureKind => cx.lang_items.require(FnTraitLangItem),
+            FnMutClosureKind => {
                 cx.lang_items.require(FnMutTraitLangItem)
             }
-            FnOnceUnboxedClosureKind => {
+            FnOnceClosureKind => {
                 cx.lang_items.require(FnOnceTraitLangItem)
             }
         };
@@ -2298,23 +2296,21 @@ impl UnboxedClosureKind {
     }
 }
 
-pub trait UnboxedClosureTyper<'tcx> {
+pub trait ClosureTyper<'tcx> {
     fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
 
-    fn unboxed_closure_kind(&self,
-                            def_id: ast::DefId)
-                            -> ty::UnboxedClosureKind;
+    fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind;
 
-    fn unboxed_closure_type(&self,
-                            def_id: ast::DefId,
-                            substs: &subst::Substs<'tcx>)
-                            -> ty::ClosureTy<'tcx>;
+    fn closure_type(&self,
+                    def_id: ast::DefId,
+                    substs: &subst::Substs<'tcx>)
+                    -> ty::ClosureTy<'tcx>;
 
     // Returns `None` if the upvar types cannot yet be definitively determined.
-    fn unboxed_closure_upvars(&self,
-                              def_id: ast::DefId,
-                              substs: &Substs<'tcx>)
-                              -> Option<Vec<UnboxedClosureUpvar<'tcx>>>;
+    fn closure_upvars(&self,
+                      def_id: ast::DefId,
+                      substs: &Substs<'tcx>)
+                      -> Option<Vec<ClosureUpvar<'tcx>>>;
 }
 
 impl<'tcx> CommonTypes<'tcx> {
@@ -2407,7 +2403,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         extern_const_variants: RefCell::new(DefIdMap()),
         method_map: RefCell::new(FnvHashMap()),
         dependency_formats: RefCell::new(FnvHashMap()),
-        unboxed_closures: RefCell::new(DefIdMap()),
+        closures: RefCell::new(DefIdMap()),
         node_lint_levels: RefCell::new(FnvHashMap()),
         transmute_restrictions: RefCell::new(Vec::new()),
         stability: RefCell::new(stability),
@@ -2454,19 +2450,16 @@ impl<'tcx> ctxt<'tcx> {
         region
     }
 
-    pub fn unboxed_closure_kind(&self,
-                            def_id: ast::DefId)
-                            -> ty::UnboxedClosureKind
-    {
-        self.unboxed_closures.borrow()[def_id].kind
+    pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
+        self.closures.borrow()[def_id].kind
     }
 
-    pub fn unboxed_closure_type(&self,
-                            def_id: ast::DefId,
-                            substs: &subst::Substs<'tcx>)
-                            -> ty::ClosureTy<'tcx>
+    pub fn closure_type(&self,
+                        def_id: ast::DefId,
+                        substs: &subst::Substs<'tcx>)
+                        -> ty::ClosureTy<'tcx>
     {
-        self.unboxed_closures.borrow()[def_id].closure_type.subst(self, substs)
+        self.closures.borrow()[def_id].closure_type.subst(self, substs)
     }
 }
 
@@ -2574,7 +2567,7 @@ impl FlagComputation {
                 }
             }
 
-            &ty_unboxed_closure(_, region, substs) => {
+            &ty_closure(_, region, substs) => {
                 self.add_region(*region);
                 self.add_substs(substs);
             }
@@ -2843,10 +2836,10 @@ pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
     mk_t(cx, ty_struct(struct_id, substs))
 }
 
-pub fn mk_unboxed_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId,
-                                region: &'tcx Region, substs: &'tcx Substs<'tcx>)
-                                -> Ty<'tcx> {
-    mk_t(cx, ty_unboxed_closure(closure_id, region, substs))
+pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId,
+                        region: &'tcx Region, substs: &'tcx Substs<'tcx>)
+                        -> Ty<'tcx> {
+    mk_t(cx, ty_closure(closure_id, region, substs))
 }
 
 pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
@@ -3057,7 +3050,7 @@ pub fn type_is_vec(ty: Ty) -> bool {
 pub fn type_is_structural(ty: Ty) -> bool {
     match ty.sty {
       ty_struct(..) | ty_tup(_) | ty_enum(..) |
-      ty_vec(_, Some(_)) | ty_unboxed_closure(..) => true,
+      ty_vec(_, Some(_)) | ty_closure(..) => true,
       _ => type_is_slice(ty) | type_is_trait(ty)
     }
 }
@@ -3422,11 +3415,10 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
                 apply_lang_items(cx, did, res)
             }
 
-            ty_unboxed_closure(did, r, substs) => {
-                // FIXME(#14449): `borrowed_contents` below assumes `&mut`
-                // unboxed closure.
+            ty_closure(did, r, substs) => {
+                // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
                 let param_env = ty::empty_parameter_environment(cx);
-                let upvars = unboxed_closure_upvars(&param_env, did, substs).unwrap();
+                let upvars = closure_upvars(&param_env, did, substs).unwrap();
                 TypeContents::union(upvars.as_slice(),
                                     |f| tc_ty(cx, f.ty, cache))
                     | borrowed_contents(*r, MutMutable)
@@ -3690,9 +3682,9 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
 
             ty_err |
             ty_infer(_) |
-            ty_unboxed_closure(..) => {
+            ty_closure(..) => {
                 // this check is run on type definitions, so we don't expect to see
-                // inference by-products or unboxed closure types
+                // inference by-products or closure types
                 cx.sess.bug(format!("requires check invoked on inapplicable type: {:?}",
                                     ty).as_slice())
             }
@@ -3784,9 +3776,9 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
 
                 find_nonrepresentable(cx, sp, seen, iter)
             }
-            ty_unboxed_closure(..) => {
-                // this check is run on type definitions, so we don't expect to see
-                // unboxed closure types
+            ty_closure(..) => {
+                // this check is run on type definitions, so we don't expect
+                // to see closure types
                 cx.sess.bug(format!("requires check invoked on inapplicable type: {:?}",
                                     ty).as_slice())
             }
@@ -4698,7 +4690,7 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
         ty_struct(id, _) => {
             format!("struct `{}`", item_path_str(cx, id))
         }
-        ty_unboxed_closure(..) => "closure".to_string(),
+        ty_closure(..) => "closure".to_string(),
         ty_tup(_) => "tuple".to_string(),
         ty_infer(TyVar(_)) => "inferred type".to_string(),
         ty_infer(IntVar(_)) => "integral variable".to_string(),
@@ -4742,11 +4734,6 @@ pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> String {
                     values.expected,
                     values.found)
         }
-        terr_onceness_mismatch(values) => {
-            format!("expected {} fn, found {} fn",
-                    values.expected,
-                    values.found)
-        }
         terr_mutability => "values differ in mutability".to_string(),
         terr_box_mutability => {
             "boxed values differ in mutability".to_string()
@@ -5118,7 +5105,7 @@ pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
             Some(tt.principal_def_id()),
         ty_struct(id, _) |
         ty_enum(id, _) |
-        ty_unboxed_closure(id, _, _) =>
+        ty_closure(id, _, _) =>
             Some(id),
         _ =>
             None
@@ -5626,17 +5613,17 @@ pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
 }
 
 #[derive(Copy, Clone)]
-pub struct UnboxedClosureUpvar<'tcx> {
+pub struct ClosureUpvar<'tcx> {
     pub def: def::Def,
     pub span: Span,
     pub ty: Ty<'tcx>,
 }
 
-// Returns a list of `UnboxedClosureUpvar`s for each upvar.
-pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
-                                    closure_id: ast::DefId,
-                                    substs: &Substs<'tcx>)
-                                    -> Option<Vec<UnboxedClosureUpvar<'tcx>>>
+// Returns a list of `ClosureUpvar`s for each upvar.
+pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
+                            closure_id: ast::DefId,
+                            substs: &Substs<'tcx>)
+                            -> Option<Vec<ClosureUpvar<'tcx>>>
 {
     // Presently an unboxed closure type cannot "escape" out of a
     // function, so we will only encounter ones that originated in the
@@ -5660,9 +5647,9 @@ pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
 
                         match capture_mode {
                             ast::CaptureByValue => {
-                                Some(UnboxedClosureUpvar { def: freevar.def,
-                                                           span: freevar.span,
-                                                           ty: freevar_ty })
+                                Some(ClosureUpvar { def: freevar.def,
+                                                    span: freevar.span,
+                                                    ty: freevar_ty })
                             }
 
                             ast::CaptureByRef => {
@@ -5688,7 +5675,7 @@ pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
                                         freevar_ty
                                     }
                                 };
-                                Some(UnboxedClosureUpvar {
+                                Some(ClosureUpvar {
                                     def: freevar.def,
                                     span: freevar.span,
                                     ty: freevar_ref_ty,
@@ -6240,7 +6227,7 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
                 ty_open(_) => byte!(22),
                 ty_infer(_) => unreachable!(),
                 ty_err => byte!(23),
-                ty_unboxed_closure(d, r, _) => {
+                ty_closure(d, r, _) => {
                     byte!(24);
                     did(state, d);
                     region(state, *r);
@@ -6476,32 +6463,29 @@ impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
     }
 }
 
-impl<'a,'tcx> UnboxedClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
+impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
     fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
         self
     }
 
-    fn unboxed_closure_kind(&self,
-                            def_id: ast::DefId)
-                            -> ty::UnboxedClosureKind
-    {
-        self.tcx.unboxed_closure_kind(def_id)
+    fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
+        self.tcx.closure_kind(def_id)
     }
 
-    fn unboxed_closure_type(&self,
-                            def_id: ast::DefId,
-                            substs: &subst::Substs<'tcx>)
-                            -> ty::ClosureTy<'tcx>
+    fn closure_type(&self,
+                    def_id: ast::DefId,
+                    substs: &subst::Substs<'tcx>)
+                    -> ty::ClosureTy<'tcx>
     {
-        self.tcx.unboxed_closure_type(def_id, substs)
+        self.tcx.closure_type(def_id, substs)
     }
 
-    fn unboxed_closure_upvars(&self,
-                              def_id: ast::DefId,
-                              substs: &Substs<'tcx>)
-                              -> Option<Vec<UnboxedClosureUpvar<'tcx>>>
+    fn closure_upvars(&self,
+                      def_id: ast::DefId,
+                      substs: &Substs<'tcx>)
+                      -> Option<Vec<ClosureUpvar<'tcx>>>
     {
-        unboxed_closure_upvars(self, def_id, substs)
+        closure_upvars(self, def_id, substs)
     }
 }
 
@@ -6533,7 +6517,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
             ty_struct(_, substs) => {
                 accum_substs(accumulator, substs);
             }
-            ty_unboxed_closure(_, region, substs) => {
+            ty_closure(_, region, substs) => {
                 accumulator.push(*region);
                 accum_substs(accumulator, substs);
             }
@@ -6826,8 +6810,8 @@ impl<'tcx> Repr<'tcx> for vtable_origin<'tcx> {
                 format!("vtable_param({:?}, {})", x, y)
             }
 
-            vtable_unboxed_closure(def_id) => {
-                format!("vtable_unboxed_closure({:?})", def_id)
+            vtable_closure(def_id) => {
+                format!("vtable_closure({:?})", def_id)
             }
 
             vtable_error => {
@@ -7064,7 +7048,7 @@ impl<'tcx> HasProjectionTypes for ClosureTy<'tcx> {
     }
 }
 
-impl<'tcx> HasProjectionTypes for UnboxedClosureUpvar<'tcx> {
+impl<'tcx> HasProjectionTypes for ClosureUpvar<'tcx> {
     fn has_projection_types(&self) -> bool {
         self.ty.has_projection_types()
     }
@@ -7285,9 +7269,9 @@ impl<'tcx> Repr<'tcx> for ClosureTy<'tcx> {
     }
 }
 
-impl<'tcx> Repr<'tcx> for UnboxedClosureUpvar<'tcx> {
+impl<'tcx> Repr<'tcx> for ClosureUpvar<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        format!("UnboxedClosureUpvar({},{})",
+        format!("ClosureUpvar({},{})",
                 self.def.repr(tcx),
                 self.ty.repr(tcx))
     }
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 0b8c7786015..86552705963 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -304,8 +304,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::MethodOrigin<'tcx> {
             ty::MethodStatic(def_id) => {
                 ty::MethodStatic(def_id)
             }
-            ty::MethodStaticUnboxedClosure(def_id) => {
-                ty::MethodStaticUnboxedClosure(def_id)
+            ty::MethodStaticClosure(def_id) => {
+                ty::MethodStaticClosure(def_id)
             }
             ty::MethodTypeParam(ref param) => {
                 ty::MethodTypeParam(ty::MethodParam {
@@ -337,8 +337,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::vtable_origin<'tcx> {
             ty::vtable_param(n, b) => {
                 ty::vtable_param(n, b)
             }
-            ty::vtable_unboxed_closure(def_id) => {
-                ty::vtable_unboxed_closure(def_id)
+            ty::vtable_closure(def_id) => {
+                ty::vtable_closure(def_id)
             }
             ty::vtable_error => {
                 ty::vtable_error
@@ -499,8 +499,8 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N>
     fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::Vtable<'tcx, N> {
         match *self {
             traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
-            traits::VtableUnboxedClosure(d, ref s) => {
-                traits::VtableUnboxedClosure(d, s.fold_with(folder))
+            traits::VtableClosure(d, ref s) => {
+                traits::VtableClosure(d, s.fold_with(folder))
             }
             traits::VtableFnPointer(ref d) => {
                 traits::VtableFnPointer(d.fold_with(folder))
@@ -545,9 +545,9 @@ impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U>
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::UnboxedClosureUpvar<'tcx> {
-    fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::UnboxedClosureUpvar<'tcx> {
-        ty::UnboxedClosureUpvar {
+impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
+    fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ClosureUpvar<'tcx> {
+        ty::ClosureUpvar {
             def: self.def,
             span: self.span,
             ty: self.ty.fold_with(folder),
@@ -624,10 +624,10 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
             let substs = substs.fold_with(this);
             ty::ty_struct(did, this.tcx().mk_substs(substs))
         }
-        ty::ty_unboxed_closure(did, ref region, ref substs) => {
+        ty::ty_closure(did, ref region, ref substs) => {
             let r = region.fold_with(this);
             let s = substs.fold_with(this);
-            ty::ty_unboxed_closure(did, this.tcx().mk_region(r), this.tcx().mk_substs(s))
+            ty::ty_closure(did, this.tcx().mk_region(r), this.tcx().mk_substs(s))
         }
         ty::ty_projection(ref data) => {
             ty::ty_projection(data.fold_with(this))
diff --git a/src/librustc/middle/ty_walk.rs b/src/librustc/middle/ty_walk.rs
index 28975c73416..a9121951460 100644
--- a/src/librustc/middle/ty_walk.rs
+++ b/src/librustc/middle/ty_walk.rs
@@ -37,12 +37,15 @@ impl<'tcx> TypeWalker<'tcx> {
             ty::ty_projection(ref data) => {
                 self.push_reversed(data.trait_ref.substs.types.as_slice());
             }
-            ty::ty_trait(box ty::TyTrait { ref principal, .. }) => {
+            ty::ty_trait(box ty::TyTrait { ref principal, ref bounds }) => {
                 self.push_reversed(principal.substs().types.as_slice());
+                self.push_reversed(bounds.projection_bounds.iter().map(|pred| {
+                    pred.0.ty
+                }).collect::<Vec<_>>().as_slice());
             }
             ty::ty_enum(_, ref substs) |
             ty::ty_struct(_, ref substs) |
-            ty::ty_unboxed_closure(_, _, ref substs) => {
+            ty::ty_closure(_, _, ref substs) => {
                 self.push_reversed(substs.types.as_slice());
             }
             ty::ty_tup(ref ts) => {
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 266048fce51..f93f5903e01 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -20,7 +20,7 @@ use middle::ty::{mt, Ty, ParamTy};
 use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum};
 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn};
 use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
-use middle::ty::{ty_unboxed_closure};
+use middle::ty::{ty_closure};
 use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
 use middle::ty;
 use middle::ty_fold::TypeFoldable;
@@ -414,9 +414,8 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
                     data.item_name.user_string(cx))
         }
         ty_str => "str".to_string(),
-        ty_unboxed_closure(ref did, _, substs) => {
-            let unboxed_closures = cx.unboxed_closures.borrow();
-            unboxed_closures.get(did).map(|cl| {
+        ty_closure(ref did, _, substs) => {
+            cx.closures.borrow().get(did).map(|cl| {
                 closure_to_string(cx, &cl.closure_type.subst(cx, substs))
             }).unwrap_or_else(|| {
                 if did.krate == ast::LOCAL_CRATE {
@@ -1021,8 +1020,8 @@ impl<'tcx> Repr<'tcx> for ty::MethodOrigin<'tcx> {
             &ty::MethodStatic(def_id) => {
                 format!("MethodStatic({})", def_id.repr(tcx))
             }
-            &ty::MethodStaticUnboxedClosure(def_id) => {
-                format!("MethodStaticUnboxedClosure({})", def_id.repr(tcx))
+            &ty::MethodStaticClosure(def_id) => {
+                format!("MethodStaticClosure({})", def_id.repr(tcx))
             }
             &ty::MethodTypeParam(ref p) => {
                 p.repr(tcx)
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index 0ade916f639..b66419420e9 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -806,7 +806,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                     mc::cat_upvar(mc::Upvar { kind, .. }) => kind,
                     _ => unreachable!()
                 };
-                if kind == ty::FnUnboxedClosureKind {
+                if kind == ty::FnClosureKind {
                     self.bccx.span_err(
                         assignment_span,
                         &format!("cannot assign to {}",
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index b87fed1601c..449f2a4d006 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -845,7 +845,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                             mc::cat_upvar(mc::Upvar { kind, .. }) => kind,
                             _ => unreachable!()
                         };
-                        if kind == ty::FnUnboxedClosureKind {
+                        if kind == ty::FnClosureKind {
                             self.tcx.sess.span_help(
                                 self.tcx.map.span(upvar_id.closure_expr_id),
                                 "consider changing this closure to take \
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index b6bc484bc10..dbac2358047 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -43,7 +43,7 @@ use rustc::middle::privacy::{ExportedItems, PublicItems, LastPrivateMap};
 use rustc::middle::privacy::{ExternalExports};
 use rustc::middle::ty::{MethodTypeParam, MethodStatic};
 use rustc::middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam};
-use rustc::middle::ty::{MethodStaticUnboxedClosure, MethodObject};
+use rustc::middle::ty::{MethodStaticClosure, MethodObject};
 use rustc::middle::ty::{MethodTraitObject};
 use rustc::middle::ty::{self, Ty};
 use rustc::util::nodemap::{NodeMap, NodeSet};
@@ -819,7 +819,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             MethodStatic(method_id) => {
                 self.check_static_method(span, method_id, ident)
             }
-            MethodStaticUnboxedClosure(_) => {}
+            MethodStaticClosure(_) => {}
             // Trait methods are always all public. The only controlling factor
             // is whether the trait itself is accessible or not.
             MethodTypeParam(MethodParam { ref trait_ref, .. }) |
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index affd2b54135..1d9c701a16c 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -249,7 +249,7 @@ enum RibKind {
 
     // We passed through a closure scope at the given node ID.
     // Translate upvars as appropriate.
-    ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
+    ClosureRibKind(NodeId /* func id */),
 
     // We passed through an impl or trait and are now in one of its
     // methods. Allow references to ty params that impl or trait
@@ -2611,18 +2611,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             DlDef(d @ DefLocal(_)) => {
                 let node_id = d.def_id().node;
                 let mut def = d;
-                let mut last_proc_body_id = ast::DUMMY_NODE_ID;
                 for rib in ribs.iter() {
                     match rib.kind {
                         NormalRibKind => {
                             // Nothing to do. Continue.
                         }
-                        ClosureRibKind(function_id, maybe_proc_body) => {
+                        ClosureRibKind(function_id) => {
                             let prev_def = def;
-                            if maybe_proc_body != ast::DUMMY_NODE_ID {
-                                last_proc_body_id = maybe_proc_body;
-                            }
-                            def = DefUpvar(node_id, function_id, last_proc_body_id);
+                            def = DefUpvar(node_id, function_id);
 
                             let mut seen = self.freevars_seen.borrow_mut();
                             let seen = match seen.entry(function_id) {
@@ -4529,7 +4525,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
             ExprClosure(capture_clause, _, ref fn_decl, ref block) => {
                 self.capture_mode_map.insert(expr.id, capture_clause);
-                self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
+                self.resolve_function(ClosureRibKind(expr.id),
                                       Some(&**fn_decl), NoTypeParameters,
                                       &**block);
             }
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 4aec53711ad..71ca6a4db03 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -920,7 +920,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         let method_callee = &(*method_map)[ty::MethodCall::expr(ex.id)];
         let (def_id, decl_id) = match method_callee.origin {
             ty::MethodStatic(def_id) |
-            ty::MethodStaticUnboxedClosure(def_id) => {
+            ty::MethodStaticClosure(def_id) => {
                 // method invoked on an object with a concrete type (not a static method)
                 let decl_id =
                     match ty::trait_item_of_item(&self.analysis.ty_cx,
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index dcb0b0ef4ea..77ae119a024 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -1228,19 +1228,19 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
     let (vid, field) = match discr.node {
         ast::ExprPath(_) | ast::ExprQPath(_) => match bcx.def(discr.id) {
-            def::DefLocal(vid) | def::DefUpvar(vid, _, _) => (vid, None),
+            def::DefLocal(vid) | def::DefUpvar(vid, _) => (vid, None),
             _ => return false
         },
         ast::ExprField(ref base, field) => {
             let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
-                Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _, _)) => vid,
+                Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::NamedField(field.node.name)))
         },
         ast::ExprTupField(ref base, field) => {
             let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
-                Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _, _)) => vid,
+                Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::PositionalField(field.node)))
diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs
index c98515cff68..519a7e19125 100644
--- a/src/librustc_trans/trans/adt.rs
+++ b/src/librustc_trans/trans/adt.rs
@@ -51,7 +51,7 @@ use std::rc::Rc;
 use llvm::{ValueRef, True, IntEQ, IntNE};
 use back::abi::FAT_PTR_ADDR;
 use middle::subst;
-use middle::ty::{self, Ty, UnboxedClosureTyper};
+use middle::ty::{self, Ty, ClosureTyper};
 use middle::ty::Disr;
 use syntax::ast;
 use syntax::attr;
@@ -169,9 +169,9 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
             Univariant(mk_struct(cx, &ftys[], packed, t), dtor)
         }
-        ty::ty_unboxed_closure(def_id, _, substs) => {
-            let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
-            let upvars = typer.unboxed_closure_upvars(def_id, substs).unwrap();
+        ty::ty_closure(def_id, _, substs) => {
+            let typer = NormalizingClosureTyper::new(cx.tcx());
+            let upvars = typer.closure_upvars(def_id, substs).unwrap();
             let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
             Univariant(mk_struct(cx, &upvar_types[], false, t), false)
         }
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 4c1fdc6140e..230a4c5d427 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -43,7 +43,7 @@ use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
 use middle::subst;
 use middle::weak_lang_items;
 use middle::subst::{Subst, Substs};
-use middle::ty::{self, Ty, UnboxedClosureTyper};
+use middle::ty::{self, Ty, ClosureTyper};
 use session::config::{self, NoDebugInfo};
 use session::Session;
 use trans::_match;
@@ -255,27 +255,25 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>,
     f
 }
 
-pub fn self_type_for_unboxed_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                                               closure_id: ast::DefId,
-                                               fn_ty: Ty<'tcx>)
-                                               -> Ty<'tcx>
+pub fn self_type_for_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
+                                       closure_id: ast::DefId,
+                                       fn_ty: Ty<'tcx>)
+                                       -> Ty<'tcx>
 {
-    let unboxed_closure_kind = ccx.tcx().unboxed_closure_kind(closure_id);
-    match unboxed_closure_kind {
-        ty::FnUnboxedClosureKind => {
+    let closure_kind = ccx.tcx().closure_kind(closure_id);
+    match closure_kind {
+        ty::FnClosureKind => {
             ty::mk_imm_rptr(ccx.tcx(), ccx.tcx().mk_region(ty::ReStatic), fn_ty)
         }
-        ty::FnMutUnboxedClosureKind => {
+        ty::FnMutClosureKind => {
             ty::mk_mut_rptr(ccx.tcx(), ccx.tcx().mk_region(ty::ReStatic), fn_ty)
         }
-        ty::FnOnceUnboxedClosureKind => fn_ty
+        ty::FnOnceClosureKind => fn_ty
     }
 }
 
-pub fn kind_for_unboxed_closure(ccx: &CrateContext, closure_id: ast::DefId)
-                                -> ty::UnboxedClosureKind {
-    let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
-    (*unboxed_closures)[closure_id].kind
+pub fn kind_for_closure(ccx: &CrateContext, closure_id: ast::DefId) -> ty::ClosureKind {
+    ccx.tcx().closures.borrow()[closure_id].kind
 }
 
 pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
@@ -295,10 +293,10 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ty::ty_bare_fn(_, ref f) => {
             (&f.sig, f.abi, None)
         }
-        ty::ty_unboxed_closure(closure_did, _, substs) => {
-            let typer = common::NormalizingUnboxedClosureTyper::new(ccx.tcx());
-            function_type = typer.unboxed_closure_type(closure_did, substs);
-            let self_type = self_type_for_unboxed_closure(ccx, closure_did, fn_ty);
+        ty::ty_closure(closure_did, _, substs) => {
+            let typer = common::NormalizingClosureTyper::new(ccx.tcx());
+            function_type = typer.closure_type(closure_did, substs);
+            let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
             let llenvironment_type = type_of_explicit_arg(ccx, self_type);
             debug!("decl_rust_fn: function_type={} self_type={}",
                    function_type.repr(ccx.tcx()),
@@ -715,10 +713,10 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
               }
           })
       }
-      ty::ty_unboxed_closure(def_id, _, substs) => {
+      ty::ty_closure(def_id, _, substs) => {
           let repr = adt::represent_type(cx.ccx(), t);
-          let typer = common::NormalizingUnboxedClosureTyper::new(cx.tcx());
-          let upvars = typer.unboxed_closure_upvars(def_id, substs).unwrap();
+          let typer = common::NormalizingClosureTyper::new(cx.tcx());
+          let upvars = typer.closure_upvars(def_id, substs).unwrap();
           for (i, upvar) in upvars.iter().enumerate() {
               let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
               cx = f(cx, llupvar, upvar.ty);
@@ -1626,14 +1624,13 @@ fn copy_args_to_allocas<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     bcx
 }
 
-fn copy_unboxed_closure_args_to_allocas<'blk, 'tcx>(
-                                        mut bcx: Block<'blk, 'tcx>,
-                                        arg_scope: cleanup::CustomScopeIndex,
-                                        args: &[ast::Arg],
-                                        arg_datums: Vec<RvalueDatum<'tcx>>,
-                                        monomorphized_arg_types: &[Ty<'tcx>])
-                                        -> Block<'blk, 'tcx> {
-    let _icx = push_ctxt("copy_unboxed_closure_args_to_allocas");
+fn copy_closure_args_to_allocas<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
+                                            arg_scope: cleanup::CustomScopeIndex,
+                                            args: &[ast::Arg],
+                                            arg_datums: Vec<RvalueDatum<'tcx>>,
+                                            monomorphized_arg_types: &[Ty<'tcx>])
+                                            -> Block<'blk, 'tcx> {
+    let _icx = push_ctxt("copy_closure_args_to_allocas");
     let arg_scope_id = cleanup::CustomScope(arg_scope);
 
     assert_eq!(arg_datums.len(), 1);
@@ -1766,12 +1763,6 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
     }
 }
 
-#[derive(Clone, Copy, Eq, PartialEq)]
-pub enum IsUnboxedClosureFlag {
-    NotUnboxedClosure,
-    IsUnboxedClosure,
-}
-
 // trans_closure: Builds an LLVM function out of a source function.
 // If the function closes over its environment a closure will be
 // returned.
@@ -1822,7 +1813,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         }
 
         // Tuple up closure argument types for the "rust-call" ABI.
-        closure::UnboxedClosure(..) => {
+        closure::Closure(..) => {
             vec![ty::mk_tup(ccx.tcx(), monomorphized_arg_types)]
         }
     };
@@ -1850,8 +1841,8 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                  &decl.inputs[],
                                  arg_datums)
         }
-        closure::UnboxedClosure(..) => {
-            copy_unboxed_closure_args_to_allocas(
+        closure::Closure(..) => {
+            copy_closure_args_to_allocas(
                 bcx,
                 arg_scope,
                 &decl.inputs[],
@@ -2430,9 +2421,9 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
     let function_type;
     let (fn_sig, abi, has_env) = match fn_ty.sty {
         ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, false),
-        ty::ty_unboxed_closure(closure_did, _, substs) => {
-            let typer = common::NormalizingUnboxedClosureTyper::new(ccx.tcx());
-            function_type = typer.unboxed_closure_type(closure_did, substs);
+        ty::ty_closure(closure_did, _, substs) => {
+            let typer = common::NormalizingClosureTyper::new(ccx.tcx());
+            function_type = typer.closure_type(closure_did, substs);
             (&function_type.sig, RustCall, true)
         }
         _ => ccx.sess().bug("expected closure or function.")
@@ -2449,7 +2440,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
     // These have an odd calling convention, so we need to manually
     // unpack the input ty's
     let input_tys = match fn_ty.sty {
-        ty::ty_unboxed_closure(_, _, _) => {
+        ty::ty_closure(_, _, _) => {
             assert!(abi == RustCall);
 
             match fn_sig.inputs[0].sty {
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 7ed4727404e..73d174c2c34 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -457,10 +457,8 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
         }
     };
 
-    // If this is an unboxed closure, redirect to it.
-    match closure::get_or_create_declaration_if_unboxed_closure(ccx,
-                                                                def_id,
-                                                                &substs) {
+    // If this is a closure, redirect to it.
+    match closure::get_or_create_declaration_if_closure(ccx, def_id, &substs) {
         None => {}
         Some(llfn) => return llfn,
     }
diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs
index 7a6c0c50dd1..c1914ce94aa 100644
--- a/src/librustc_trans/trans/closure.rs
+++ b/src/librustc_trans/trans/closure.rs
@@ -23,7 +23,7 @@ use trans::debuginfo;
 use trans::expr;
 use trans::monomorphize::{self, MonoId};
 use trans::type_of::*;
-use middle::ty::{self, UnboxedClosureTyper};
+use middle::ty::{self, ClosureTyper};
 use middle::subst::{Substs};
 use session::config::FullDebugInfo;
 
@@ -31,24 +31,23 @@ use syntax::ast;
 use syntax::ast_util;
 
 
-fn load_unboxed_closure_environment<'blk, 'tcx>(
-                                    bcx: Block<'blk, 'tcx>,
-                                    arg_scope_id: ScopeId,
-                                    freevar_mode: ast::CaptureClause,
-                                    freevars: &[ty::Freevar])
-                                    -> Block<'blk, 'tcx> {
-    let _icx = push_ctxt("closure::load_unboxed_closure_environment");
+fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                        arg_scope_id: ScopeId,
+                                        freevar_mode: ast::CaptureClause,
+                                        freevars: &[ty::Freevar])
+                                        -> Block<'blk, 'tcx> {
+    let _icx = push_ctxt("closure::load_closure_environment");
 
     // Special case for small by-value selfs.
     let closure_id = ast_util::local_def(bcx.fcx.id);
-    let self_type = self_type_for_unboxed_closure(bcx.ccx(), closure_id,
+    let self_type = self_type_for_closure(bcx.ccx(), closure_id,
                                                   node_id_type(bcx, closure_id.node));
-    let kind = kind_for_unboxed_closure(bcx.ccx(), closure_id);
-    let llenv = if kind == ty::FnOnceUnboxedClosureKind &&
+    let kind = kind_for_closure(bcx.ccx(), closure_id);
+    let llenv = if kind == ty::FnOnceClosureKind &&
             !arg_is_indirect(bcx.ccx(), self_type) {
         let datum = rvalue_scratch_datum(bcx,
                                          self_type,
-                                         "unboxed_closure_env");
+                                         "closure_env");
         store_ty(bcx, bcx.fcx.llenv.unwrap(), datum.val, self_type);
         datum.val
     } else {
@@ -77,7 +76,7 @@ fn load_unboxed_closure_environment<'blk, 'tcx>(
         let def_id = freevar.def.def_id();
         bcx.fcx.llupvars.borrow_mut().insert(def_id.node, upvar_ptr);
 
-        if kind == ty::FnOnceUnboxedClosureKind && freevar_mode == ast::CaptureByValue {
+        if kind == ty::FnOnceClosureKind && freevar_mode == ast::CaptureByValue {
             bcx.fcx.schedule_drop_mem(arg_scope_id,
                                       upvar_ptr,
                                       node_id_type(bcx, def_id.node))
@@ -100,8 +99,8 @@ fn load_unboxed_closure_environment<'blk, 'tcx>(
 #[derive(PartialEq)]
 pub enum ClosureKind<'tcx> {
     NotClosure,
-    // See load_unboxed_closure_environment.
-    UnboxedClosure(ast::CaptureClause)
+    // See load_closure_environment.
+    Closure(ast::CaptureClause)
 }
 
 pub struct ClosureEnv<'a, 'tcx> {
@@ -127,21 +126,21 @@ impl<'a, 'tcx> ClosureEnv<'a, 'tcx> {
 
         match self.kind {
             NotClosure => bcx,
-            UnboxedClosure(freevar_mode) => {
-                load_unboxed_closure_environment(bcx, arg_scope, freevar_mode, self.freevars)
+            Closure(freevar_mode) => {
+                load_closure_environment(bcx, arg_scope, freevar_mode, self.freevars)
             }
         }
     }
 }
 
-/// Returns the LLVM function declaration for an unboxed closure, creating it
-/// if necessary. If the ID does not correspond to a closure ID, returns None.
-pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                                                              closure_id: ast::DefId,
-                                                              substs: &Substs<'tcx>)
-                                                              -> Option<Datum<'tcx, Rvalue>> {
-    if !ccx.tcx().unboxed_closures.borrow().contains_key(&closure_id) {
-        // Not an unboxed closure.
+/// Returns the LLVM function declaration for a closure, creating it if
+/// necessary. If the ID does not correspond to a closure ID, returns None.
+pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
+                                                      closure_id: ast::DefId,
+                                                      substs: &Substs<'tcx>)
+                                                      -> Option<Datum<'tcx, Rvalue>> {
+    if !ccx.tcx().closures.borrow().contains_key(&closure_id) {
+        // Not a closure.
         return None
     }
 
@@ -152,7 +151,7 @@ pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext
     // duplicate declarations
     let function_type = erase_regions(ccx.tcx(), &function_type);
     let params = match function_type.sty {
-        ty::ty_unboxed_closure(_, _, ref substs) => substs.types.clone(),
+        ty::ty_closure(_, _, ref substs) => substs.types.clone(),
         _ => unreachable!()
     };
     let mono_id = MonoId {
@@ -160,17 +159,16 @@ pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext
         params: params
     };
 
-    match ccx.unboxed_closure_vals().borrow().get(&mono_id) {
+    match ccx.closure_vals().borrow().get(&mono_id) {
         Some(&llfn) => {
-            debug!("get_or_create_declaration_if_unboxed_closure(): found \
-                    closure");
+            debug!("get_or_create_declaration_if_closure(): found closure");
             return Some(Datum::new(llfn, function_type, Rvalue::new(ByValue)))
         }
         None => {}
     }
 
     let symbol = ccx.tcx().map.with_path(closure_id.node, |path| {
-        mangle_internal_name_by_path_and_seq(path, "unboxed_closure")
+        mangle_internal_name_by_path_and_seq(path, "closure")
     });
 
     let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[]);
@@ -178,29 +176,28 @@ pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext
     // set an inline hint for all closures
     set_inline_hint(llfn);
 
-    debug!("get_or_create_declaration_if_unboxed_closure(): inserting new \
+    debug!("get_or_create_declaration_if_closure(): inserting new \
             closure {:?} (type {})",
            mono_id,
            ccx.tn().type_to_string(val_ty(llfn)));
-    ccx.unboxed_closure_vals().borrow_mut().insert(mono_id, llfn);
+    ccx.closure_vals().borrow_mut().insert(mono_id, llfn);
 
     Some(Datum::new(llfn, function_type, Rvalue::new(ByValue)))
 }
 
-pub fn trans_unboxed_closure<'blk, 'tcx>(
-                             mut bcx: Block<'blk, 'tcx>,
-                             decl: &ast::FnDecl,
-                             body: &ast::Block,
-                             id: ast::NodeId,
-                             dest: expr::Dest)
-                             -> Block<'blk, 'tcx>
+pub fn trans_closure_expr<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
+                                      decl: &ast::FnDecl,
+                                      body: &ast::Block,
+                                      id: ast::NodeId,
+                                      dest: expr::Dest)
+                                      -> Block<'blk, 'tcx>
 {
-    let _icx = push_ctxt("closure::trans_unboxed_closure");
+    let _icx = push_ctxt("closure::trans_closure");
 
-    debug!("trans_unboxed_closure()");
+    debug!("trans_closure()");
 
     let closure_id = ast_util::local_def(id);
-    let llfn = get_or_create_declaration_if_unboxed_closure(
+    let llfn = get_or_create_declaration_if_closure(
         bcx.ccx(),
         closure_id,
         bcx.fcx.param_substs).unwrap();
@@ -208,10 +205,10 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
     // Get the type of this closure. Use the current `param_substs` as
     // the closure substitutions. This makes sense because the closure
     // takes the same set of type arguments as the enclosing fn, and
-    // this function (`trans_unboxed_closure`) is invoked at the point
+    // this function (`trans_closure`) is invoked at the point
     // of the closure expression.
-    let typer = NormalizingUnboxedClosureTyper::new(bcx.tcx());
-    let function_type = typer.unboxed_closure_type(closure_id, bcx.fcx.param_substs);
+    let typer = NormalizingClosureTyper::new(bcx.tcx());
+    let function_type = typer.closure_type(closure_id, bcx.fcx.param_substs);
 
     let freevars: Vec<ty::Freevar> =
         ty::with_freevars(bcx.tcx(), id, |fv| fv.iter().map(|&fv| fv).collect());
@@ -229,15 +226,15 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
                   sig.output,
                   function_type.abi,
                   ClosureEnv::new(&freevars[],
-                                  UnboxedClosure(freevar_mode)));
+                                  Closure(freevar_mode)));
 
     // Don't hoist this to the top of the function. It's perfectly legitimate
-    // to have a zero-size unboxed closure (in which case dest will be
-    // `Ignore`) and we must still generate the closure body.
+    // to have a zero-size closure (in which case dest will be `Ignore`) and
+    // we must still generate the closure body.
     let dest_addr = match dest {
         expr::SaveIn(p) => p,
         expr::Ignore => {
-            debug!("trans_unboxed_closure() ignoring result");
+            debug!("trans_closure() ignoring result");
             return bcx
         }
     };
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index 3bc851c5595..a5c4df7dbb9 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -248,7 +248,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
     }
     match ty.sty {
         ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) | ty::ty_vec(_, Some(_)) |
-        ty::ty_unboxed_closure(..) => {
+        ty::ty_closure(..) => {
             let llty = sizing_type_of(ccx, ty);
             llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())
         }
@@ -693,35 +693,32 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
     }
 }
 
-impl<'blk, 'tcx> ty::UnboxedClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
+impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
     fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx> {
         &self.fcx.param_env
     }
 
-    fn unboxed_closure_kind(&self,
-                            def_id: ast::DefId)
-                            -> ty::UnboxedClosureKind
-    {
-        let typer = NormalizingUnboxedClosureTyper::new(self.tcx());
-        typer.unboxed_closure_kind(def_id)
+    fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
+        let typer = NormalizingClosureTyper::new(self.tcx());
+        typer.closure_kind(def_id)
     }
 
-    fn unboxed_closure_type(&self,
-                            def_id: ast::DefId,
-                            substs: &subst::Substs<'tcx>)
-                            -> ty::ClosureTy<'tcx>
+    fn closure_type(&self,
+                    def_id: ast::DefId,
+                    substs: &subst::Substs<'tcx>)
+                    -> ty::ClosureTy<'tcx>
     {
-        let typer = NormalizingUnboxedClosureTyper::new(self.tcx());
-        typer.unboxed_closure_type(def_id, substs)
+        let typer = NormalizingClosureTyper::new(self.tcx());
+        typer.closure_type(def_id, substs)
     }
 
-    fn unboxed_closure_upvars(&self,
-                              def_id: ast::DefId,
-                              substs: &Substs<'tcx>)
-                              -> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
+    fn closure_upvars(&self,
+                      def_id: ast::DefId,
+                      substs: &Substs<'tcx>)
+                      -> Option<Vec<ty::ClosureUpvar<'tcx>>>
     {
-        let typer = NormalizingUnboxedClosureTyper::new(self.tcx());
-        typer.unboxed_closure_upvars(def_id, substs)
+        let typer = NormalizingClosureTyper::new(self.tcx());
+        typer.closure_upvars(def_id, substs)
     }
 }
 
@@ -1011,7 +1008,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     // Do the initial selection for the obligation. This yields the
     // shallow result we are looking for -- that is, what specific impl.
-    let typer = NormalizingUnboxedClosureTyper::new(tcx);
+    let typer = NormalizingClosureTyper::new(tcx);
     let mut selcx = traits::SelectionContext::new(&infcx, &typer);
     let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
                                              trait_ref.to_poly_trait_predicate());
@@ -1056,49 +1053,46 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     vtable
 }
 
-pub struct NormalizingUnboxedClosureTyper<'a,'tcx:'a> {
+pub struct NormalizingClosureTyper<'a,'tcx:'a> {
     param_env: ty::ParameterEnvironment<'a, 'tcx>
 }
 
-impl<'a,'tcx> NormalizingUnboxedClosureTyper<'a,'tcx> {
-    pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingUnboxedClosureTyper<'a,'tcx> {
+impl<'a,'tcx> NormalizingClosureTyper<'a,'tcx> {
+    pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingClosureTyper<'a,'tcx> {
         // Parameter environment is used to give details about type parameters,
         // but since we are in trans, everything is fully monomorphized.
-        NormalizingUnboxedClosureTyper { param_env: ty::empty_parameter_environment(tcx) }
+        NormalizingClosureTyper { param_env: ty::empty_parameter_environment(tcx) }
     }
 }
 
-impl<'a,'tcx> ty::UnboxedClosureTyper<'tcx> for NormalizingUnboxedClosureTyper<'a,'tcx> {
+impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> {
     fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
         &self.param_env
     }
 
-    fn unboxed_closure_kind(&self,
-                            def_id: ast::DefId)
-                            -> ty::UnboxedClosureKind
-    {
-        self.param_env.tcx.unboxed_closure_kind(def_id)
+    fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
+        self.param_env.tcx.closure_kind(def_id)
     }
 
-    fn unboxed_closure_type(&self,
-                            def_id: ast::DefId,
-                            substs: &subst::Substs<'tcx>)
-                            -> ty::ClosureTy<'tcx>
+    fn closure_type(&self,
+                    def_id: ast::DefId,
+                    substs: &subst::Substs<'tcx>)
+                    -> ty::ClosureTy<'tcx>
     {
         // the substitutions in `substs` are already monomorphized,
         // but we still must normalize associated types
-        let closure_ty = self.param_env.tcx.unboxed_closure_type(def_id, substs);
+        let closure_ty = self.param_env.tcx.closure_type(def_id, substs);
         monomorphize::normalize_associated_type(self.param_env.tcx, &closure_ty)
     }
 
-    fn unboxed_closure_upvars(&self,
-                              def_id: ast::DefId,
-                              substs: &Substs<'tcx>)
-                              -> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
+    fn closure_upvars(&self,
+                      def_id: ast::DefId,
+                      substs: &Substs<'tcx>)
+                      -> Option<Vec<ty::ClosureUpvar<'tcx>>>
     {
         // the substitutions in `substs` are already monomorphized,
         // but we still must normalize associated types
-        let result = ty::unboxed_closure_upvars(&self.param_env, def_id, substs);
+        let result = ty::closure_upvars(&self.param_env, def_id, substs);
         monomorphize::normalize_associated_type(self.param_env.tcx, &result)
     }
 }
@@ -1116,7 +1110,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
     // In principle, we only need to do this so long as `result`
     // contains unbound type parameters. It could be a slight
     // optimization to stop iterating early.
-    let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx);
+    let typer = NormalizingClosureTyper::new(infcx.tcx);
     match fulfill_cx.select_all_or_error(infcx, &typer) {
         Ok(()) => { }
         Err(errors) => {
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 10edb72f0e2..09e0c016133 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -138,7 +138,7 @@ pub struct LocalCrateContext<'tcx> {
     builder: BuilderRef_res,
 
     /// Holds the LLVM values for closure IDs.
-    unboxed_closure_vals: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
+    closure_vals: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
 
     dbg_cx: Option<debuginfo::CrateDebugContext<'tcx>>,
 
@@ -414,7 +414,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
                 int_type: Type::from_ref(ptr::null_mut()),
                 opaque_vec_type: Type::from_ref(ptr::null_mut()),
                 builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)),
-                unboxed_closure_vals: RefCell::new(FnvHashMap()),
+                closure_vals: RefCell::new(FnvHashMap()),
                 dbg_cx: dbg_cx,
                 eh_personality: RefCell::new(None),
                 intrinsics: RefCell::new(FnvHashMap()),
@@ -684,8 +684,8 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         self.local.opaque_vec_type
     }
 
-    pub fn unboxed_closure_vals<'a>(&'a self) -> &'a RefCell<FnvHashMap<MonoId<'tcx>,ValueRef>> {
-        &self.local.unboxed_closure_vals
+    pub fn closure_vals<'a>(&'a self) -> &'a RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>> {
+        &self.local.closure_vals
     }
 
     pub fn dbg_cx<'a>(&'a self) -> &'a Option<debuginfo::CrateDebugContext<'tcx>> {
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index b366c7faefa..4c1cf62ce8a 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -197,11 +197,11 @@ use metadata::csearch;
 use middle::subst::{self, Substs};
 use trans::{self, adt, machine, type_of};
 use trans::common::{self, NodeIdAndSpan, CrateContext, FunctionContext, Block,
-                    C_bytes, C_i32, C_i64, NormalizingUnboxedClosureTyper};
+                    C_bytes, C_i32, C_i64, NormalizingClosureTyper};
 use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef};
 use trans::monomorphize;
 use trans::type_::Type;
-use middle::ty::{self, Ty, UnboxedClosureTyper};
+use middle::ty::{self, Ty, ClosureTyper};
 use middle::pat_util;
 use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
 use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
@@ -472,9 +472,9 @@ impl<'tcx> TypeMap<'tcx> {
                     }
                 }
             },
-            ty::ty_unboxed_closure(def_id, _, substs) => {
-                let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
-                let closure_ty = typer.unboxed_closure_type(def_id, substs);
+            ty::ty_closure(def_id, _, substs) => {
+                let typer = NormalizingClosureTyper::new(cx.tcx());
+                let closure_ty = typer.closure_type(def_id, substs);
                 self.get_unique_type_id_of_closure_type(cx,
                                                         closure_ty,
                                                         &mut unique_type_id);
@@ -3035,9 +3035,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         ty::ty_bare_fn(_, ref barefnty) => {
             subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
         }
-        ty::ty_unboxed_closure(def_id, _, substs) => {
-            let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
-            let sig = typer.unboxed_closure_type(def_id, substs).sig;
+        ty::ty_closure(def_id, _, substs) => {
+            let typer = NormalizingClosureTyper::new(cx.tcx());
+            let sig = typer.closure_type(def_id, substs).sig;
             subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
         }
         ty::ty_struct(def_id, substs) => {
@@ -3888,7 +3888,7 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 }
             }
         },
-        ty::ty_unboxed_closure(..) => {
+        ty::ty_closure(..) => {
             output.push_str("closure");
         }
         ty::ty_err |
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index f0b491bdea8..1504c2a7c2d 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -1098,11 +1098,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             tvec::trans_fixed_vstore(bcx, expr, dest)
         }
         ast::ExprClosure(_, _, ref decl, ref body) => {
-            // Check the side-table to see whether this is an unboxed
-            // closure or an older, legacy style closure. Store this
-            // into a variable to ensure the the RefCell-lock is
-            // released before we recurse.
-            closure::trans_unboxed_closure(bcx, &**decl, &**body, expr.id, dest)
+            closure::trans_closure_expr(bcx, &**decl, &**body, expr.id, dest)
         }
         ast::ExprCall(ref f, ref args) => {
             if bcx.tcx().is_method_call(expr.id) {
@@ -1263,7 +1259,7 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_local_var");
 
     match def {
-        def::DefUpvar(nid, _, _) => {
+        def::DefUpvar(nid, _) => {
             // Can't move upvars, so this is never a ZeroMemLastUse.
             let local_ty = node_id_type(bcx, nid);
             match bcx.fcx.llupvars.borrow().get(&nid) {
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index fb2ee55940d..c1d98987991 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -438,7 +438,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
                 }
             }
         }
-        ty::ty_unboxed_closure(..) => {
+        ty::ty_closure(..) => {
             iter_structural_ty(bcx,
                                v0,
                                t,
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index 9356be1b9b4..580a2d5ae3d 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -120,7 +120,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     match origin {
         ty::MethodStatic(did) |
-        ty::MethodStaticUnboxedClosure(did) => {
+        ty::MethodStaticClosure(did) => {
             Callee {
                 bcx: bcx,
                 data: Fn(callee::trans_fn_ref(bcx.ccx(),
@@ -365,7 +365,7 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
             Callee { bcx: bcx, data: Fn(llfn) }
         }
-        traits::VtableUnboxedClosure(closure_def_id, substs) => {
+        traits::VtableClosure(closure_def_id, substs) => {
             // The substitutions should have no type parameters remaining
             // after passing through fulfill_obligation
             let llfn = trans_fn_ref_with_substs(bcx.ccx(),
@@ -727,7 +727,7 @@ pub fn get_vtable<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                     nested: _ }) => {
                 emit_vtable_methods(bcx, id, substs).into_iter()
             }
-            traits::VtableUnboxedClosure(closure_def_id, substs) => {
+            traits::VtableClosure(closure_def_id, substs) => {
                 let llfn = trans_fn_ref_with_substs(
                     bcx.ccx(),
                     closure_def_id,
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index 93076260349..72e41408d8a 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -322,7 +322,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
     // FIXME(#20304) -- cache
 
     let infcx = infer::new_infer_ctxt(tcx);
-    let typer = NormalizingUnboxedClosureTyper::new(tcx);
+    let typer = NormalizingClosureTyper::new(tcx);
     let mut selcx = traits::SelectionContext::new(&infcx, &typer);
     let cause = traits::ObligationCause::dummy();
     let traits::Normalized { value: result, obligations } =
diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs
index 76e0e0d0545..61dbb551435 100644
--- a/src/librustc_trans/trans/type_of.rs
+++ b/src/librustc_trans/trans/type_of.rs
@@ -211,7 +211,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
             Type::nil(cx)
         }
 
-        ty::ty_tup(..) | ty::ty_enum(..) | ty::ty_unboxed_closure(..) => {
+        ty::ty_tup(..) | ty::ty_enum(..) | ty::ty_closure(..) => {
             let repr = adt::represent_type(cx, t);
             adt::sizing_type_of(cx, &*repr, false)
         }
@@ -330,7 +330,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
           let name = llvm_type_name(cx, an_enum, did, tps);
           adt::incomplete_type_of(cx, &*repr, &name[])
       }
-      ty::ty_unboxed_closure(did, _, ref substs) => {
+      ty::ty_closure(did, _, ref substs) => {
           // Only create the named struct, but don't fill it in. We
           // fill it in *after* placing it into the type cache.
           let repr = adt::represent_type(cx, t);
@@ -338,7 +338,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
           // inherited from their environment, so we use entire
           // contents of the VecPerParamSpace to to construct the llvm
           // name
-          let name = llvm_type_name(cx, an_unboxed_closure, did, substs.types.as_slice());
+          let name = llvm_type_name(cx, a_closure, did, substs.types.as_slice());
           adt::incomplete_type_of(cx, &*repr, &name[])
       }
 
@@ -432,7 +432,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
 
     // If this was an enum or struct, fill in the type now.
     match t.sty {
-        ty::ty_enum(..) | ty::ty_struct(..) | ty::ty_unboxed_closure(..)
+        ty::ty_enum(..) | ty::ty_struct(..) | ty::ty_closure(..)
                 if !ty::type_is_simd(cx.tcx(), t) => {
             let repr = adt::represent_type(cx, t);
             adt::finish_type_of(cx, &*repr, &mut llty);
@@ -454,7 +454,7 @@ pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
 pub enum named_ty {
     a_struct,
     an_enum,
-    an_unboxed_closure,
+    a_closure,
 }
 
 pub fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
@@ -465,7 +465,7 @@ pub fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let name = match what {
         a_struct => "struct",
         an_enum => "enum",
-        an_unboxed_closure => return "closure".to_string(),
+        a_closure => return "closure".to_string(),
     };
 
     let base = ty::item_path_str(cx.tcx(), did);
diff --git a/src/librustc_typeck/check/assoc.rs b/src/librustc_typeck/check/assoc.rs
index 26b6d4e0296..0e0a9294640 100644
--- a/src/librustc_typeck/check/assoc.rs
+++ b/src/librustc_typeck/check/assoc.rs
@@ -18,7 +18,7 @@ use syntax::codemap::Span;
 use util::ppaux::Repr;
 
 pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
-                                                typer: &(ty::UnboxedClosureTyper<'tcx>+'a),
+                                                typer: &(ty::ClosureTyper<'tcx>+'a),
                                                 fulfillment_cx: &mut FulfillmentContext<'tcx>,
                                                 span: Span,
                                                 body_id: ast::NodeId,
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index ffec1421f92..2d7a7634472 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -25,7 +25,7 @@ use util::ppaux::Repr;
 pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                                    expr: &ast::Expr,
                                    _capture: ast::CaptureClause,
-                                   opt_kind: Option<ast::UnboxedClosureKind>,
+                                   opt_kind: Option<ast::ClosureKind>,
                                    decl: &ast::FnDecl,
                                    body: &ast::Block,
                                    expected: Expectation<'tcx>) {
@@ -34,7 +34,7 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
            expected.repr(fcx.tcx()));
 
     let expected_sig_and_kind = expected.to_option(fcx).and_then(|ty| {
-        deduce_unboxed_closure_expectations_from_expected_type(fcx, ty)
+        deduce_closure_expectations_from_expected_type(fcx, ty)
     });
 
     match opt_kind {
@@ -42,46 +42,46 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
             // If users didn't specify what sort of closure they want,
             // examine the expected type. For now, if we see explicit
             // evidence than an unboxed closure is desired, we'll use
-            // that, otherwise we'll fall back to boxed closures.
+            // that, otherwise we'll error, requesting an annotation.
             match expected_sig_and_kind {
                 None => { // don't have information about the kind, request explicit annotation
                     // NB We still need to typeck the body, so assume `FnMut` kind just for that
-                    let kind = ty::FnMutUnboxedClosureKind;
+                    let kind = ty::FnMutClosureKind;
 
-                    check_unboxed_closure(fcx, expr, kind, decl, body, None);
+                    check_closure(fcx, expr, kind, decl, body, None);
 
                     span_err!(fcx.ccx.tcx.sess, expr.span, E0187,
                         "can't infer the \"kind\" of the closure; explicitly annotate it; e.g. \
                         `|&:| {{}}`");
                 },
                 Some((sig, kind)) => {
-                    check_unboxed_closure(fcx, expr, kind, decl, body, Some(sig));
+                    check_closure(fcx, expr, kind, decl, body, Some(sig));
                 }
             }
         }
 
         Some(kind) => {
             let kind = match kind {
-                ast::FnUnboxedClosureKind => ty::FnUnboxedClosureKind,
-                ast::FnMutUnboxedClosureKind => ty::FnMutUnboxedClosureKind,
-                ast::FnOnceUnboxedClosureKind => ty::FnOnceUnboxedClosureKind,
+                ast::FnClosureKind => ty::FnClosureKind,
+                ast::FnMutClosureKind => ty::FnMutClosureKind,
+                ast::FnOnceClosureKind => ty::FnOnceClosureKind,
             };
 
             let expected_sig = expected_sig_and_kind.map(|t| t.0);
-            check_unboxed_closure(fcx, expr, kind, decl, body, expected_sig);
+            check_closure(fcx, expr, kind, decl, body, expected_sig);
         }
     }
 }
 
-fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
-                                  expr: &ast::Expr,
-                                  kind: ty::UnboxedClosureKind,
-                                  decl: &ast::FnDecl,
-                                  body: &ast::Block,
-                                  expected_sig: Option<ty::FnSig<'tcx>>) {
+fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                          expr: &ast::Expr,
+                          kind: ty::ClosureKind,
+                          decl: &ast::FnDecl,
+                          body: &ast::Block,
+                          expected_sig: Option<ty::FnSig<'tcx>>) {
     let expr_def_id = ast_util::local_def(expr.id);
 
-    debug!("check_unboxed_closure kind={:?} expected_sig={}",
+    debug!("check_closure kind={:?} expected_sig={}",
            kind,
            expected_sig.repr(fcx.tcx()));
 
@@ -100,11 +100,11 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
         Ok(regions) => regions[0],
     };
 
-    let closure_type = ty::mk_unboxed_closure(fcx.ccx.tcx,
-                                              expr_def_id,
-                                              fcx.ccx.tcx.mk_region(region),
-                                              fcx.ccx.tcx.mk_substs(
-                                                  fcx.inh.param_env.free_substs.clone()));
+    let closure_type = ty::mk_closure(fcx.ccx.tcx,
+                                      expr_def_id,
+                                      fcx.ccx.tcx.mk_region(region),
+                                      fcx.ccx.tcx.mk_substs(
+                                        fcx.inh.param_env.free_substs.clone()));
 
     fcx.write_ty(expr.id, closure_type);
 
@@ -121,39 +121,36 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
              fcx.inh);
 
     // Tuple up the arguments and insert the resulting function type into
-    // the `unboxed_closures` table.
+    // the `closures` table.
     fn_ty.sig.0.inputs = vec![ty::mk_tup(fcx.tcx(), fn_ty.sig.0.inputs)];
 
-    debug!("unboxed_closure for {} --> sig={} kind={:?}",
+    debug!("closure for {} --> sig={} kind={:?}",
            expr_def_id.repr(fcx.tcx()),
            fn_ty.sig.repr(fcx.tcx()),
            kind);
 
-    let unboxed_closure = ty::UnboxedClosure {
+    let closure = ty::Closure {
         closure_type: fn_ty,
         kind: kind,
     };
 
-    fcx.inh
-        .unboxed_closures
-        .borrow_mut()
-        .insert(expr_def_id, unboxed_closure);
+    fcx.inh.closures.borrow_mut().insert(expr_def_id, closure);
 }
 
-fn deduce_unboxed_closure_expectations_from_expected_type<'a,'tcx>(
+fn deduce_closure_expectations_from_expected_type<'a,'tcx>(
     fcx: &FnCtxt<'a,'tcx>,
     expected_ty: Ty<'tcx>)
-    -> Option<(ty::FnSig<'tcx>,ty::UnboxedClosureKind)>
+    -> Option<(ty::FnSig<'tcx>,ty::ClosureKind)>
 {
     match expected_ty.sty {
         ty::ty_trait(ref object_type) => {
             let trait_ref =
                 object_type.principal_trait_ref_with_self_ty(fcx.tcx(),
                                                              fcx.tcx().types.err);
-            deduce_unboxed_closure_expectations_from_trait_ref(fcx, &trait_ref)
+            deduce_closure_expectations_from_trait_ref(fcx, &trait_ref)
         }
         ty::ty_infer(ty::TyVar(vid)) => {
-            deduce_unboxed_closure_expectations_from_obligations(fcx, vid)
+            deduce_closure_expectations_from_obligations(fcx, vid)
         }
         _ => {
             None
@@ -161,14 +158,14 @@ fn deduce_unboxed_closure_expectations_from_expected_type<'a,'tcx>(
     }
 }
 
-fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
+fn deduce_closure_expectations_from_trait_ref<'a,'tcx>(
     fcx: &FnCtxt<'a,'tcx>,
     trait_ref: &ty::PolyTraitRef<'tcx>)
-    -> Option<(ty::FnSig<'tcx>, ty::UnboxedClosureKind)>
+    -> Option<(ty::FnSig<'tcx>, ty::ClosureKind)>
 {
     let tcx = fcx.tcx();
 
-    debug!("deduce_unboxed_closure_expectations_from_object_type({})",
+    debug!("deduce_closure_expectations_from_object_type({})",
            trait_ref.repr(tcx));
 
     let kind = match tcx.lang_items.fn_trait_kind(trait_ref.def_id()) {
@@ -202,10 +199,10 @@ fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
     return Some((fn_sig, kind));
 }
 
-fn deduce_unboxed_closure_expectations_from_obligations<'a,'tcx>(
+fn deduce_closure_expectations_from_obligations<'a,'tcx>(
     fcx: &FnCtxt<'a,'tcx>,
     expected_vid: ty::TyVid)
-    -> Option<(ty::FnSig<'tcx>, ty::UnboxedClosureKind)>
+    -> Option<(ty::FnSig<'tcx>, ty::ClosureKind)>
 {
     // Here `expected_ty` is known to be a type inference variable.
     for obligation in fcx.inh.fulfillment_cx.borrow().pending_obligations().iter() {
@@ -218,7 +215,7 @@ fn deduce_unboxed_closure_expectations_from_obligations<'a,'tcx>(
                     _ => { continue; }
                 }
 
-                match deduce_unboxed_closure_expectations_from_trait_ref(fcx, &trait_ref) {
+                match deduce_closure_expectations_from_trait_ref(fcx, &trait_ref) {
                     Some(e) => { return Some(e); }
                     None => { }
                 }
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 9bbc7b258e2..61332ada506 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -62,7 +62,7 @@ enum CandidateKind<'tcx> {
     ObjectCandidate(/* Trait */ ast::DefId, /* method_num */ uint, /* real_index */ uint),
     ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::TraitRef<'tcx>>,
                            subst::Substs<'tcx>, MethodIndex),
-    UnboxedClosureCandidate(/* Trait */ ast::DefId, MethodIndex),
+    ClosureCandidate(/* Trait */ ast::DefId, MethodIndex),
     WhereClauseCandidate(ty::PolyTraitRef<'tcx>, MethodIndex),
     ProjectionCandidate(ast::DefId, MethodIndex),
 }
@@ -249,7 +249,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             }
             ty::ty_enum(did, _) |
             ty::ty_struct(did, _) |
-            ty::ty_unboxed_closure(did, _, _) => {
+            ty::ty_closure(did, _, _) => {
                 self.assemble_inherent_impl_candidates_for_type(did);
             }
             ty::ty_param(p) => {
@@ -494,9 +494,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                                                            method.clone(),
                                                            matching_index);
 
-        self.assemble_unboxed_closure_candidates(trait_def_id,
-                                                 method.clone(),
-                                                 matching_index);
+        self.assemble_closure_candidates(trait_def_id,
+                                         method.clone(),
+                                         matching_index);
 
         self.assemble_projection_candidates(trait_def_id,
                                             method.clone(),
@@ -571,19 +571,19 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         simplified_steps.contains(&impl_simplified_type)
     }
 
-    fn assemble_unboxed_closure_candidates(&mut self,
-                                           trait_def_id: ast::DefId,
-                                           method_ty: Rc<ty::Method<'tcx>>,
-                                           method_index: uint)
+    fn assemble_closure_candidates(&mut self,
+                                   trait_def_id: ast::DefId,
+                                   method_ty: Rc<ty::Method<'tcx>>,
+                                   method_index: uint)
     {
         // Check if this is one of the Fn,FnMut,FnOnce traits.
         let tcx = self.tcx();
         let kind = if Some(trait_def_id) == tcx.lang_items.fn_trait() {
-            ty::FnUnboxedClosureKind
+            ty::FnClosureKind
         } else if Some(trait_def_id) == tcx.lang_items.fn_mut_trait() {
-            ty::FnMutUnboxedClosureKind
+            ty::FnMutClosureKind
         } else if Some(trait_def_id) == tcx.lang_items.fn_once_trait() {
-            ty::FnOnceUnboxedClosureKind
+            ty::FnOnceClosureKind
         } else {
             return;
         };
@@ -593,17 +593,17 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         let steps = self.steps.clone();
         for step in steps.iter() {
             let (closure_def_id, _, _) = match step.self_ty.sty {
-                ty::ty_unboxed_closure(a, b, ref c) => (a, b, c),
+                ty::ty_closure(a, b, ref c) => (a, b, c),
                 _ => continue,
             };
 
-            let unboxed_closures = self.fcx.inh.unboxed_closures.borrow();
-            let closure_data = match unboxed_closures.get(&closure_def_id) {
+            let closures = self.fcx.inh.closures.borrow();
+            let closure_data = match closures.get(&closure_def_id) {
                 Some(data) => data,
                 None => {
                     self.tcx().sess.span_bug(
                         self.span,
-                        &format!("No entry for unboxed closure: {}",
+                        &format!("No entry for closure: {}",
                                 closure_def_id.repr(self.tcx()))[]);
                 }
             };
@@ -626,7 +626,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             self.inherent_candidates.push(Candidate {
                 xform_self_ty: xform_self_ty,
                 method_ty: method_ty.clone(),
-                kind: UnboxedClosureCandidate(trait_def_id, method_index)
+                kind: ClosureCandidate(trait_def_id, method_index)
             });
         }
     }
@@ -950,7 +950,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
 
                 ProjectionCandidate(..) |
                 ObjectCandidate(..) |
-                UnboxedClosureCandidate(..) |
+                ClosureCandidate(..) |
                 WhereClauseCandidate(..) => {
                     // These have no additional conditions to check.
                     true
@@ -1173,7 +1173,7 @@ impl<'tcx> Candidate<'tcx> {
                 ExtensionImplCandidate(def_id, _, _, index) => {
                     ExtensionImplPick(def_id, index)
                 }
-                UnboxedClosureCandidate(trait_def_id, index) => {
+                ClosureCandidate(trait_def_id, index) => {
                     TraitPick(trait_def_id, index)
                 }
                 WhereClauseCandidate(ref trait_ref, index) => {
@@ -1198,7 +1198,7 @@ impl<'tcx> Candidate<'tcx> {
             InherentImplCandidate(def_id, _) => ImplSource(def_id),
             ObjectCandidate(def_id, _, _) => TraitSource(def_id),
             ExtensionImplCandidate(def_id, _, _, _) => ImplSource(def_id),
-            UnboxedClosureCandidate(trait_def_id, _) => TraitSource(trait_def_id),
+            ClosureCandidate(trait_def_id, _) => TraitSource(trait_def_id),
             WhereClauseCandidate(ref trait_ref, _) => TraitSource(trait_ref.def_id()),
             ProjectionCandidate(trait_def_id, _) => TraitSource(trait_def_id),
         }
@@ -1210,7 +1210,7 @@ impl<'tcx> Candidate<'tcx> {
             ObjectCandidate(..) => {
                 None
             }
-            UnboxedClosureCandidate(trait_def_id, method_num) => {
+            ClosureCandidate(trait_def_id, method_num) => {
                 Some((trait_def_id, method_num))
             }
             ExtensionImplCandidate(_, ref trait_ref, _, method_num) => {
@@ -1244,8 +1244,8 @@ impl<'tcx> Repr<'tcx> for CandidateKind<'tcx> {
             ExtensionImplCandidate(ref a, ref b, ref c, ref d) =>
                 format!("ExtensionImplCandidate({},{},{},{})", a.repr(tcx), b.repr(tcx),
                         c.repr(tcx), d),
-            UnboxedClosureCandidate(ref a, ref b) =>
-                format!("UnboxedClosureCandidate({},{})", a.repr(tcx), b),
+            ClosureCandidate(ref a, ref b) =>
+                format!("ClosureCandidate({},{})", a.repr(tcx), b),
             WhereClauseCandidate(ref a, ref b) =>
                 format!("WhereClauseCandidate({},{})", a.repr(tcx), b),
             ProjectionCandidate(ref a, ref b) =>
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a9f81d3a266..5b172598ebb 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -160,7 +160,7 @@ pub struct Inherited<'a, 'tcx: 'a> {
     adjustments: RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>,
     method_map: MethodMap<'tcx>,
     upvar_borrow_map: RefCell<ty::UpvarBorrowMap>,
-    unboxed_closures: RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>>,
+    closures: RefCell<DefIdMap<ty::Closure<'tcx>>>,
     object_cast_map: ObjectCastMap<'tcx>,
 
     // A mapping from each fn's id to its signature, with all bound
@@ -338,32 +338,29 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> ty::UnboxedClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
+impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
     fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
         &self.inh.param_env
     }
 
-    fn unboxed_closure_kind(&self,
-                            def_id: ast::DefId)
-                            -> ty::UnboxedClosureKind
-    {
-        self.inh.unboxed_closures.borrow()[def_id].kind
+    fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
+        self.inh.closures.borrow()[def_id].kind
     }
 
-    fn unboxed_closure_type(&self,
-                            def_id: ast::DefId,
-                            substs: &subst::Substs<'tcx>)
-                            -> ty::ClosureTy<'tcx>
+    fn closure_type(&self,
+                    def_id: ast::DefId,
+                    substs: &subst::Substs<'tcx>)
+                    -> ty::ClosureTy<'tcx>
     {
-        self.inh.unboxed_closures.borrow()[def_id].closure_type.subst(self.tcx(), substs)
+        self.inh.closures.borrow()[def_id].closure_type.subst(self.tcx(), substs)
     }
 
-    fn unboxed_closure_upvars(&self,
-                              def_id: ast::DefId,
-                              substs: &Substs<'tcx>)
-                              -> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
+    fn closure_upvars(&self,
+                      def_id: ast::DefId,
+                      substs: &Substs<'tcx>)
+                      -> Option<Vec<ty::ClosureUpvar<'tcx>>>
     {
-        ty::unboxed_closure_upvars(self, def_id, substs)
+        ty::closure_upvars(self, def_id, substs)
     }
 }
 
@@ -381,14 +378,14 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
             method_map: RefCell::new(FnvHashMap()),
             object_cast_map: RefCell::new(NodeMap()),
             upvar_borrow_map: RefCell::new(FnvHashMap()),
-            unboxed_closures: RefCell::new(DefIdMap()),
+            closures: RefCell::new(DefIdMap()),
             fn_sig_map: RefCell::new(NodeMap()),
             fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
         }
     }
 
     fn normalize_associated_types_in<T>(&self,
-                                        typer: &ty::UnboxedClosureTyper<'tcx>,
+                                        typer: &ty::ClosureTyper<'tcx>,
                                         span: Span,
                                         body_id: ast::NodeId,
                                         value: &T)
@@ -1635,6 +1632,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     {
         let raw_ty = self.expr_ty(expr);
         let raw_ty = self.infcx().shallow_resolve(raw_ty);
+        let resolve_ty = |&: ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
         ty::adjust_ty(self.tcx(),
                       expr.span,
                       expr.id,
@@ -1642,7 +1640,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                       adjustment,
                       |method_call| self.inh.method_map.borrow()
                                                        .get(&method_call)
-                                                       .map(|method| method.ty))
+                                                       .map(|method| resolve_ty(method.ty)))
     }
 
     pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
@@ -4624,7 +4622,7 @@ pub fn type_scheme_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                      defn: def::Def)
                                      -> TypeScheme<'tcx> {
     match defn {
-      def::DefLocal(nid) | def::DefUpvar(nid, _, _) => {
+      def::DefLocal(nid) | def::DefUpvar(nid, _) => {
           let typ = fcx.local_ty(sp, nid);
           return no_params(typ);
       }
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index af5250805b7..f2a3d660925 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -177,16 +177,9 @@ pub struct Rcx<'a, 'tcx: 'a> {
 fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region {
     let tcx = fcx.tcx();
     match def {
-        def::DefLocal(node_id) => {
+        def::DefLocal(node_id) | def::DefUpvar(node_id, _) => {
             tcx.region_maps.var_region(node_id)
         }
-        def::DefUpvar(node_id, _, body_id) => {
-            if body_id == ast::DUMMY_NODE_ID {
-                tcx.region_maps.var_region(node_id)
-            } else {
-                ReScope(CodeExtent::from_node_id(body_id))
-            }
-        }
         _ => {
             tcx.sess.bug(&format!("unexpected def in region_of_def: {:?}",
                                  def)[])
@@ -748,7 +741,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
     let function_type = rcx.resolve_node_type(expr.id);
 
     match function_type.sty {
-        ty::ty_unboxed_closure(_, region, _) => {
+        ty::ty_closure(_, region, _) => {
             if tcx.capture_modes.borrow()[expr.id].clone() == ast::CaptureByRef {
                 ty::with_freevars(tcx, expr.id, |freevars| {
                     if !freevars.is_empty() {
@@ -768,7 +761,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
     rcx.set_repeating_scope(repeating_scope);
 
     match function_type.sty {
-        ty::ty_unboxed_closure(_, region, _) => {
+        ty::ty_closure(_, region, _) => {
             ty::with_freevars(tcx, expr.id, |freevars| {
                 let bounds = ty::region_existential_bound(*region);
                 ensure_free_variable_types_outlive_closure_bound(rcx, &bounds, expr, freevars);
diff --git a/src/librustc_typeck/check/regionmanip.rs b/src/librustc_typeck/check/regionmanip.rs
index 8730858f66e..58e8a9c6912 100644
--- a/src/librustc_typeck/check/regionmanip.rs
+++ b/src/librustc_typeck/check/regionmanip.rs
@@ -68,8 +68,8 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
                 // No borrowed content reachable here.
             }
 
-            ty::ty_unboxed_closure(_, region, _) => {
-                // An "unboxed closure type" is basically
+            ty::ty_closure(_, region, _) => {
+                // An "closure type" is basically
                 // modeled here as equivalent to a struct like
                 //
                 //     struct TheClosure<'b> {
@@ -79,7 +79,7 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
                 // where the `'b` is the lifetime bound of the
                 // contents (i.e., all contents must outlive 'b).
                 //
-                // Even though unboxed closures are glorified structs
+                // Even though closures are glorified structs
                 // of upvars, we do not need to consider them as they
                 // can't generate any new constraints.  The
                 // substitutions on the closure are equal to the free
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index ec44d765a8e..7fc0a83e34a 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -121,13 +121,8 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> {
                      capture_clause: ast::CaptureClause,
                      _body: &ast::Block)
     {
-        let is_old_skool_closure = match self.fcx.expr_ty(expr).sty {
-            _ => false,
-        };
-
         match capture_clause {
-            ast::CaptureByValue if !is_old_skool_closure => {
-            }
+            ast::CaptureByValue => {}
             _ => {
                 ty::with_freevars(self.tcx(), expr.id, |freevars| {
                     for freevar in freevars.iter() {
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 52e81585875..2fd33983fd3 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -39,7 +39,7 @@ pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) {
     let mut wbcx = WritebackCx::new(fcx);
     wbcx.visit_expr(e);
     wbcx.visit_upvar_borrow_map();
-    wbcx.visit_unboxed_closures();
+    wbcx.visit_closures();
     wbcx.visit_object_cast_map();
 }
 
@@ -60,7 +60,7 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
         }
     }
     wbcx.visit_upvar_borrow_map();
-    wbcx.visit_unboxed_closures();
+    wbcx.visit_closures();
     wbcx.visit_object_cast_map();
 }
 
@@ -195,27 +195,19 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         }
     }
 
-    fn visit_unboxed_closures(&self) {
+    fn visit_closures(&self) {
         if self.fcx.writeback_errors.get() {
             return
         }
 
-        for (def_id, unboxed_closure) in self.fcx
-                                             .inh
-                                             .unboxed_closures
-                                             .borrow()
-                                             .iter() {
-            let closure_ty = self.resolve(&unboxed_closure.closure_type,
-                                          ResolvingUnboxedClosure(*def_id));
-            let unboxed_closure = ty::UnboxedClosure {
+        for (def_id, closure) in self.fcx.inh.closures.borrow().iter() {
+            let closure_ty = self.resolve(&closure.closure_type,
+                                          ResolvingClosure(*def_id));
+            let closure = ty::Closure {
                 closure_type: closure_ty,
-                kind: unboxed_closure.kind,
+                kind: closure.kind,
             };
-            self.fcx
-                .tcx()
-                .unboxed_closures
-                .borrow_mut()
-                .insert(*def_id, unboxed_closure);
+            self.fcx.tcx().closures.borrow_mut().insert(*def_id, closure);
         }
     }
 
@@ -331,7 +323,7 @@ enum ResolveReason {
     ResolvingLocal(Span),
     ResolvingPattern(Span),
     ResolvingUpvar(ty::UpvarId),
-    ResolvingUnboxedClosure(ast::DefId),
+    ResolvingClosure(ast::DefId),
 }
 
 impl ResolveReason {
@@ -343,7 +335,7 @@ impl ResolveReason {
             ResolvingUpvar(upvar_id) => {
                 ty::expr_span(tcx, upvar_id.closure_expr_id)
             }
-            ResolvingUnboxedClosure(did) => {
+            ResolvingClosure(did) => {
                 if did.krate == ast::LOCAL_CRATE {
                     ty::expr_span(tcx, did.node)
                 } else {
@@ -414,11 +406,10 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
                         infer::fixup_err_to_string(e));
                 }
 
-                ResolvingUnboxedClosure(_) => {
+                ResolvingClosure(_) => {
                     let span = self.reason.span(self.tcx);
                     span_err!(self.tcx.sess, span, E0196,
-                                           "cannot determine a type for this \
-                                            unboxed closure")
+                              "cannot determine a type for this closure")
                 }
             }
         }
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 7d59c3f9d3f..9760d5f05df 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -26,7 +26,7 @@ use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
 use middle::ty::{ty_param, TypeScheme, ty_ptr};
 use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
 use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
-use middle::ty::{ty_uint, ty_unboxed_closure, ty_uniq, ty_bare_fn};
+use middle::ty::{ty_uint, ty_closure, ty_uniq, ty_bare_fn};
 use middle::ty::{ty_projection};
 use middle::ty;
 use CrateCtxt;
@@ -80,7 +80,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
             None
         }
 
-        ty_infer(..) | ty_unboxed_closure(..) => {
+        ty_infer(..) | ty_closure(..) => {
             // `ty` comes from a user declaration so we should only expect types
             // that the user can type
             inference_context.tcx.sess.span_bug(
@@ -410,7 +410,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             match self_type.ty.sty {
                 ty::ty_enum(type_def_id, _) |
                 ty::ty_struct(type_def_id, _) |
-                ty::ty_unboxed_closure(type_def_id, _, _) => {
+                ty::ty_closure(type_def_id, _, _) => {
                     tcx.destructor_for_type
                        .borrow_mut()
                        .insert(type_def_id, method_def_id.def_id());
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 3627fa41160..680ff2fcda6 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -113,7 +113,7 @@ register_diagnostics! {
            // involving type parameters
     E0194,
     E0195, // lifetime parameters or bounds on method do not match the trait declaration
-    E0196, // cannot determine a type for this unboxed closure
+    E0196, // cannot determine a type for this closure
     E0197, // inherent impls cannot be declared as unsafe
     E0198, // negative implementations are not unsafe
     E0199, // implementing trait is not unsafe
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index 6ed18368738..ed8a50110e5 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -740,8 +740,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 /* leaf type -- noop */
             }
 
-            ty::ty_unboxed_closure(..) => {
-                self.tcx().sess.bug("Unexpected unboxed closure type in variance computation");
+            ty::ty_closure(..) => {
+                self.tcx().sess.bug("Unexpected closure type in variance computation");
             }
 
             ty::ty_rptr(region, ref mt) => {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 07b5586e691..c12726c8868 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1604,7 +1604,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
 
             ty::ty_param(ref p) => Generic(token::get_name(p.name).to_string()),
 
-            ty::ty_unboxed_closure(..) => Tuple(vec![]), // FIXME(pcwalton)
+            ty::ty_closure(..) => Tuple(vec![]), // FIXME(pcwalton)
 
             ty::ty_infer(..) => panic!("ty_infer"),
             ty::ty_open(..) => panic!("ty_open"),
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 25a30b5e8e2..4f6cd8ad356 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -35,7 +35,6 @@ pub use self::MacStmtStyle::*;
 pub use self::MetaItem_::*;
 pub use self::Method_::*;
 pub use self::Mutability::*;
-pub use self::Onceness::*;
 pub use self::Pat_::*;
 pub use self::PathListItem_::*;
 pub use self::PatWildKind::*;
@@ -49,7 +48,7 @@ pub use self::TraitItem::*;
 pub use self::Ty_::*;
 pub use self::TyParamBound::*;
 pub use self::UintTy::*;
-pub use self::UnboxedClosureKind::*;
+pub use self::ClosureKind::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
 pub use self::VariantKind::*;
@@ -734,7 +733,7 @@ pub enum Expr_ {
     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprLoop(P<Block>, Option<Ident>),
     ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
-    ExprClosure(CaptureClause, Option<UnboxedClosureKind>, P<FnDecl>, P<Block>),
+    ExprClosure(CaptureClause, Option<ClosureKind>, P<FnDecl>, P<Block>),
     ExprBlock(P<Block>),
 
     ExprAssign(P<Expr>, P<Expr>),
@@ -1222,31 +1221,6 @@ pub enum PrimTy {
     TyChar
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, Show)]
-pub enum Onceness {
-    Once,
-    Many
-}
-
-impl fmt::Display for Onceness {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(match *self {
-            Once => "once",
-            Many => "many",
-        }, f)
-    }
-}
-
-/// Represents the type of a closure
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
-pub struct ClosureTy {
-    pub lifetimes: Vec<LifetimeDef>,
-    pub unsafety: Unsafety,
-    pub onceness: Onceness,
-    pub decl: P<FnDecl>,
-    pub bounds: TyParamBounds,
-}
-
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
 pub struct BareFnTy {
     pub unsafety: Unsafety,
@@ -1710,10 +1684,10 @@ impl ForeignItem_ {
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
-pub enum UnboxedClosureKind {
-    FnUnboxedClosureKind,
-    FnMutUnboxedClosureKind,
-    FnOnceUnboxedClosureKind,
+pub enum ClosureKind {
+    FnClosureKind,
+    FnMutClosureKind,
+    FnOnceClosureKind,
 }
 
 /// The data we save and restore about an inlined item or method.  This is not
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 9cfdc942c21..dd89153d497 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -467,6 +467,8 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
                                     ext::log_syntax::expand_syntax_ext));
     syntax_expanders.insert(intern("derive"),
                             Decorator(box ext::deriving::expand_meta_derive));
+    syntax_expanders.insert(intern("deriving"),
+                            Decorator(box ext::deriving::expand_deprecated_deriving));
 
     if ecfg.enable_quotes {
         // Quasi-quoting expanders
diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs
index 8ac7e57bb81..9c85d3d28a7 100644
--- a/src/libsyntax/ext/deriving/bounds.rs
+++ b/src/libsyntax/ext/deriving/bounds.rs
@@ -51,7 +51,8 @@ pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
         path: Path::new(vec!("std", "marker", name)),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
-        methods: vec!()
+        methods: Vec::new(),
+        associated_types: Vec::new(),
     };
 
     trait_def.expand(cx, mitem, item, push)
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index 6498e8d2d58..e1dcc887778 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -44,7 +44,8 @@ pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
                     cs_clone("Clone", c, s, sub)
                 }),
             }
-        )
+        ),
+        associated_types: Vec::new(),
     };
 
     trait_def.expand(cx, mitem, item, push)
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index c550c26c745..00971b96e92 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -88,7 +88,8 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
         methods: vec!(
             md!("eq", cs_eq),
             md!("ne", cs_ne)
-        )
+        ),
+        associated_types: Vec::new(),
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 9f1850145b6..1f92f8d7b37 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -78,7 +78,8 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
             md!("le", true, true),
             md!("gt", false, false),
             md!("ge", false, true)
-        ]
+        ],
+        associated_types: Vec::new(),
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs
index 9a2af6a3e0b..0429db3643b 100644
--- a/src/libsyntax/ext/deriving/cmp/totaleq.rs
+++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs
@@ -61,7 +61,8 @@ pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
                     cs_total_eq_assert(a, b, c)
                 })
             }
-        )
+        ),
+        associated_types: Vec::new(),
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index 29d327142a6..e90c1aa6fce 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -45,7 +45,8 @@ pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
                     cs_cmp(a, b, c)
                 }),
             }
-        )
+        ),
+        associated_types: Vec::new(),
     };
 
     trait_def.expand(cx, mitem, item, push)
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index e458bd58e8b..9552dff941d 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -79,7 +79,9 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt,
                 combine_substructure: combine_substructure(box |a, b, c| {
                     decodable_substructure(a, b, c, krate)
                 }),
-            })
+            }
+        ),
+        associated_types: Vec::new(),
     };
 
     trait_def.expand(cx, mitem, item, push)
diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs
index f8fdd8575bd..27f3c46c48f 100644
--- a/src/libsyntax/ext/deriving/default.rs
+++ b/src/libsyntax/ext/deriving/default.rs
@@ -43,7 +43,9 @@ pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
                 combine_substructure: combine_substructure(box |a, b, c| {
                     default_substructure(a, b, c)
                 })
-            })
+            }
+        ),
+        associated_types: Vec::new(),
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 4c78a7b6a0c..d0b2c2faf37 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -155,7 +155,9 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt,
                 combine_substructure: combine_substructure(box |a, b, c| {
                     encodable_substructure(a, b, c)
                 }),
-            })
+            }
+        ),
+        associated_types: Vec::new(),
     };
 
     trait_def.expand(cx, mitem, item, push)
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index f8812f4d28d..56ff455a02b 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -228,6 +228,8 @@ pub struct TraitDef<'a> {
     pub generics: LifetimeBounds<'a>,
 
     pub methods: Vec<MethodDef<'a>>,
+
+    pub associated_types: Vec<(ast::Ident, Ty<'a>)>,
 }
 
 
@@ -387,6 +389,22 @@ impl<'a> TraitDef<'a> {
                            methods: Vec<P<ast::Method>>) -> P<ast::Item> {
         let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
 
+        // Transform associated types from `deriving::ty::Ty` into `ast::Typedef`
+        let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| {
+            P(ast::Typedef {
+                id: ast::DUMMY_NODE_ID,
+                span: self.span,
+                ident: ident,
+                vis: ast::Inherited,
+                attrs: Vec::new(),
+                typ: type_def.to_ty(cx,
+                    self.span,
+                    type_ident,
+                    generics
+                ),
+            })
+        });
+
         let Generics { mut lifetimes, ty_params, mut where_clause } =
             self.generics.to_generics(cx, self.span, type_ident, generics);
         let mut ty_params = ty_params.into_vec();
@@ -494,7 +512,11 @@ impl<'a> TraitDef<'a> {
                           methods.into_iter()
                                  .map(|method| {
                                      ast::MethodImplItem(method)
-                                 }).collect()))
+                                 }).chain(
+                                     associated_types.map(|type_| {
+                                         ast::TypeImplItem(type_)
+                                     })
+                                 ).collect()))
     }
 
     fn expand_struct_def(&self,
diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs
index 8dac864c2ae..e7f546b2691 100644
--- a/src/libsyntax/ext/deriving/hash.rs
+++ b/src/libsyntax/ext/deriving/hash.rs
@@ -54,7 +54,8 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
                     hash_substructure(a, b, c)
                 })
             }
-        )
+        ),
+        associated_types: Vec::new(),
     };
 
     hash_trait_def.expand(cx, mitem, item, push);
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index e52a2b513ce..ddec517a78e 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -40,6 +40,14 @@ pub mod totalord;
 
 pub mod generic;
 
+pub fn expand_deprecated_deriving(cx: &mut ExtCtxt,
+                                  span: Span,
+                                  _: &MetaItem,
+                                  _: &Item,
+                                  _: Box<FnMut(P<Item>)>) {
+    cx.span_err(span, "`deriving` has been renamed to `derive`");
+}
+
 pub fn expand_meta_derive(cx: &mut ExtCtxt,
                           _span: Span,
                           mitem: &MetaItem,
diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs
index c45fe1ceb20..c694b054ba3 100644
--- a/src/libsyntax/ext/deriving/primitive.rs
+++ b/src/libsyntax/ext/deriving/primitive.rs
@@ -65,7 +65,9 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
                 combine_substructure: combine_substructure(box |c, s, sub| {
                     cs_from("u64", c, s, sub)
                 }),
-            })
+            }
+        ),
+        associated_types: Vec::new(),
     };
 
     trait_def.expand(cx, mitem, item, push)
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index bb902d7059c..9fd5091e194 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -49,7 +49,8 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
                     rand_substructure(a, b, c)
                 })
             }
-        )
+        ),
+        associated_types: Vec::new(),
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index f5b5d4dda19..ec5941f58f3 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -35,10 +35,10 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "fmt", "Debug")),
+        path: Path::new(vec!["std", "fmt", "Debug"]),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
-        methods: vec!(
+        methods: vec![
             MethodDef {
                 name: "fmt",
                 generics: LifetimeBounds::empty(),
@@ -50,7 +50,8 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
                     show_substructure(a, b, c)
                 })
             }
-        )
+        ],
+        associated_types: Vec::new(),
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 759e5e8229a..eab24574bb1 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -28,8 +28,8 @@ use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprQPath};
 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
 use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
-use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
-use ast::{FnOnceUnboxedClosureKind};
+use ast::{FnClosureKind, FnMutClosureKind};
+use ast::{FnOnceClosureKind};
 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
 use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
@@ -57,7 +57,7 @@ use ast::{TyFixedLengthVec, TyBareFn};
 use ast::{TyTypeof, TyInfer, TypeMethod};
 use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath};
 use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
-use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
+use ast::{TypeImplItem, TypeTraitItem, Typedef, ClosureKind};
 use ast::{UnnamedField, UnsafeBlock};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause};
@@ -1133,27 +1133,26 @@ impl<'a> Parser<'a> {
         TyInfer
     }
 
-    /// Parses an optional unboxed closure kind (`&:`, `&mut:`, or `:`).
-    pub fn parse_optional_unboxed_closure_kind(&mut self)
-                                               -> Option<UnboxedClosureKind> {
+    /// Parses an optional closure kind (`&:`, `&mut:`, or `:`).
+    pub fn parse_optional_closure_kind(&mut self) -> Option<ClosureKind> {
         if self.check(&token::BinOp(token::And)) &&
                 self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) &&
                 self.look_ahead(2, |t| *t == token::Colon) {
             self.bump();
             self.bump();
             self.bump();
-            return Some(FnMutUnboxedClosureKind)
+            return Some(FnMutClosureKind)
         }
 
         if self.token == token::BinOp(token::And) &&
                     self.look_ahead(1, |t| *t == token::Colon) {
             self.bump();
             self.bump();
-            return Some(FnUnboxedClosureKind)
+            return Some(FnClosureKind)
         }
 
         if self.eat(&token::Colon) {
-            return Some(FnOnceUnboxedClosureKind)
+            return Some(FnOnceClosureKind)
         }
 
         return None
@@ -3023,8 +3022,7 @@ impl<'a> Parser<'a> {
                              -> P<Expr>
     {
         let lo = self.span.lo;
-        let (decl, optional_unboxed_closure_kind) =
-            self.parse_fn_block_decl();
+        let (decl, optional_closure_kind) = self.parse_fn_block_decl();
         let body = self.parse_expr();
         let fakeblock = P(ast::Block {
             id: ast::DUMMY_NODE_ID,
@@ -3037,7 +3035,7 @@ impl<'a> Parser<'a> {
         self.mk_expr(
             lo,
             fakeblock.span.hi,
-            ExprClosure(capture_clause, optional_unboxed_closure_kind, decl, fakeblock))
+            ExprClosure(capture_clause, optional_closure_kind, decl, fakeblock))
     }
 
     pub fn parse_else_expr(&mut self) -> P<Expr> {
@@ -4506,22 +4504,21 @@ impl<'a> Parser<'a> {
     }
 
     // parse the |arg, arg| header on a lambda
-    fn parse_fn_block_decl(&mut self)
-                           -> (P<FnDecl>, Option<UnboxedClosureKind>) {
-        let (optional_unboxed_closure_kind, inputs_captures) = {
+    fn parse_fn_block_decl(&mut self) -> (P<FnDecl>, Option<ClosureKind>) {
+        let (optional_closure_kind, inputs_captures) = {
             if self.eat(&token::OrOr) {
                 (None, Vec::new())
             } else {
                 self.expect(&token::BinOp(token::Or));
-                let optional_unboxed_closure_kind =
-                    self.parse_optional_unboxed_closure_kind();
+                let optional_closure_kind =
+                    self.parse_optional_closure_kind();
                 let args = self.parse_seq_to_before_end(
                     &token::BinOp(token::Or),
                     seq_sep_trailing_allowed(token::Comma),
                     |p| p.parse_fn_block_arg()
                 );
                 self.bump();
-                (optional_unboxed_closure_kind, args)
+                (optional_closure_kind, args)
             }
         };
         let output = self.parse_ret_ty();
@@ -4530,7 +4527,7 @@ impl<'a> Parser<'a> {
             inputs: inputs_captures,
             output: output,
             variadic: false
-        }), optional_unboxed_closure_kind)
+        }), optional_closure_kind)
     }
 
     /// Parses the `(arg, arg) -> return_type` header on a procedure.
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 699b4f43b14..d06ac50920e 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -11,11 +11,11 @@
 pub use self::AnnNode::*;
 
 use abi;
-use ast::{self, FnUnboxedClosureKind, FnMutUnboxedClosureKind};
-use ast::{FnOnceUnboxedClosureKind};
+use ast::{self, FnClosureKind, FnMutClosureKind};
+use ast::{FnOnceClosureKind};
 use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
 use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem};
-use ast::{UnboxedClosureKind};
+use ast::{ClosureKind};
 use ast_util;
 use owned_slice::OwnedSlice;
 use attr::{AttrMetaMethods, AttributeMethods};
@@ -703,14 +703,11 @@ impl<'a> State<'a> {
                         predicates: Vec::new(),
                     },
                 };
-                try!(self.print_ty_fn(Some(f.abi),
-                                      None,
+                try!(self.print_ty_fn(f.abi,
                                       f.unsafety,
-                                      ast::Many,
                                       &*f.decl,
                                       None,
-                                      &OwnedSlice::empty(),
-                                      Some(&generics),
+                                      &generics,
                                       None));
             }
             ast::TyPath(ref path, _) => {
@@ -1215,14 +1212,11 @@ impl<'a> State<'a> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(m.span.lo));
         try!(self.print_outer_attributes(&m.attrs[]));
-        try!(self.print_ty_fn(None,
-                              None,
+        try!(self.print_ty_fn(m.abi,
                               m.unsafety,
-                              ast::Many,
                               &*m.decl,
                               Some(m.ident),
-                              &OwnedSlice::empty(),
-                              Some(&m.generics),
+                              &m.generics,
                               Some(&m.explicit_self.node)));
         word(&mut self.s, ";")
     }
@@ -2300,7 +2294,7 @@ impl<'a> State<'a> {
                     opt_explicit_self: Option<&ast::ExplicitSelf_>,
                     vis: ast::Visibility) -> IoResult<()> {
         try!(self.head(""));
-        try!(self.print_fn_header_info(opt_explicit_self, unsafety, abi, vis));
+        try!(self.print_fn_header_info(unsafety, abi, vis));
         try!(self.nbsp());
         try!(self.print_ident(name));
         try!(self.print_generics(generics));
@@ -2357,14 +2351,14 @@ impl<'a> State<'a> {
     pub fn print_fn_block_args(
             &mut self,
             decl: &ast::FnDecl,
-            unboxed_closure_kind: Option<UnboxedClosureKind>)
+            closure_kind: Option<ClosureKind>)
             -> IoResult<()> {
         try!(word(&mut self.s, "|"));
-        match unboxed_closure_kind {
+        match closure_kind {
             None => {}
-            Some(FnUnboxedClosureKind) => try!(self.word_space("&:")),
-            Some(FnMutUnboxedClosureKind) => try!(self.word_space("&mut:")),
-            Some(FnOnceUnboxedClosureKind) => try!(self.word_space(":")),
+            Some(FnClosureKind) => try!(self.word_space("&:")),
+            Some(FnMutClosureKind) => try!(self.word_space("&mut:")),
+            Some(FnOnceClosureKind) => try!(self.word_space(":")),
         }
         try!(self.print_fn_args(decl, None));
         try!(word(&mut self.s, "|"));
@@ -2396,31 +2390,6 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_proc_args(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
-        try!(word(&mut self.s, "proc"));
-        try!(word(&mut self.s, "("));
-        try!(self.print_fn_args(decl, None));
-        try!(word(&mut self.s, ")"));
-
-        if let ast::DefaultReturn(..) = decl.output {
-            return Ok(());
-        }
-
-        try!(self.space_if_not_bol());
-        try!(self.word_space("->"));
-        match decl.output {
-            ast::Return(ref ty) => {
-                try!(self.print_type(&**ty));
-                self.maybe_print_comment(ty.span.lo)
-            }
-            ast::DefaultReturn(..) => unreachable!(),
-            ast::NoReturn(span) => {
-                try!(self.word_nbsp("!"));
-                self.maybe_print_comment(span.lo)
-            }
-        }
-    }
-
     pub fn print_bounds(&mut self,
                         prefix: &str,
                         bounds: &[ast::TyParamBound])
@@ -2696,31 +2665,15 @@ impl<'a> State<'a> {
     }
 
     pub fn print_ty_fn(&mut self,
-                       opt_abi: Option<abi::Abi>,
-                       opt_sigil: Option<char>,
+                       abi: abi::Abi,
                        unsafety: ast::Unsafety,
-                       onceness: ast::Onceness,
                        decl: &ast::FnDecl,
                        id: Option<ast::Ident>,
-                       bounds: &OwnedSlice<ast::TyParamBound>,
-                       generics: Option<&ast::Generics>,
+                       generics: &ast::Generics,
                        opt_explicit_self: Option<&ast::ExplicitSelf_>)
                        -> IoResult<()> {
         try!(self.ibox(indent_unit));
-
-        // Duplicates the logic in `print_fn_header_info()`.  This is because that
-        // function prints the sigil in the wrong place.  That should be fixed.
-        if opt_sigil == Some('~') && onceness == ast::Once {
-            try!(word(&mut self.s, "proc"));
-        } else if opt_sigil == Some('&') {
-            try!(self.print_unsafety(unsafety));
-            try!(self.print_extern_opt_abi(opt_abi));
-        } else {
-            assert!(opt_sigil.is_none());
-            try!(self.print_unsafety(unsafety));
-            try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
-            try!(word(&mut self.s, "fn"));
-        }
+        try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited));
 
         match id {
             Some(id) => {
@@ -2730,35 +2683,10 @@ impl<'a> State<'a> {
             _ => ()
         }
 
-        match generics { Some(g) => try!(self.print_generics(g)), _ => () }
+        try!(self.print_generics(generics));
         try!(zerobreak(&mut self.s));
-
-        if opt_sigil == Some('&') {
-            try!(word(&mut self.s, "|"));
-        } else {
-            try!(self.popen());
-        }
-
-        try!(self.print_fn_args(decl, opt_explicit_self));
-
-        if opt_sigil == Some('&') {
-            try!(word(&mut self.s, "|"));
-        } else {
-            if decl.variadic {
-                try!(word(&mut self.s, ", ..."));
-            }
-            try!(self.pclose());
-        }
-
-        try!(self.print_bounds(":", &bounds[]));
-
-        try!(self.print_fn_output(decl));
-
-        match generics {
-            Some(generics) => try!(self.print_where_clause(generics)),
-            None => {}
-        }
-
+        try!(self.print_fn_args_and_ret(decl, opt_explicit_self));
+        try!(self.print_where_clause(generics));
         self.end()
     }
 
@@ -3015,7 +2943,6 @@ impl<'a> State<'a> {
     }
 
     pub fn print_fn_header_info(&mut self,
-                                _opt_explicit_self: Option<&ast::ExplicitSelf_>,
                                 opt_unsafety: Option<ast::Unsafety>,
                                 abi: abi::Abi,
                                 vis: ast::Visibility) -> IoResult<()> {
diff --git a/src/test/compile-fail/deriving-is-deprecated.rs b/src/test/compile-fail/deriving-is-deprecated.rs
new file mode 100644
index 00000000000..060e178eef2
--- /dev/null
+++ b/src/test/compile-fail/deriving-is-deprecated.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 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.
+
+
+#[deriving(Clone)] //~ ERROR `deriving` has been renamed to `derive`
+struct Foo;
+
+fn main() {}
diff --git a/src/test/compile-fail/missing_debug_impls.rs b/src/test/compile-fail/missing_debug_impls.rs
new file mode 100644
index 00000000000..4adae2f3680
--- /dev/null
+++ b/src/test/compile-fail/missing_debug_impls.rs
@@ -0,0 +1,48 @@
+// Copyright 2015 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.
+
+// compile-flags: --crate-type lib
+#![deny(missing_debug_implementations)]
+#![allow(unused, unstable, missing_copy_implementations)]
+
+use std::fmt;
+
+pub enum A {} //~ ERROR type does not implement `fmt::Debug`
+
+#[derive(Debug)]
+pub enum B {}
+
+pub enum C {}
+
+impl fmt::Debug for C {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        Ok(())
+    }
+}
+
+pub struct Foo; //~ ERROR type does not implement `fmt::Debug`
+
+#[derive(Debug)]
+pub struct Bar;
+
+pub struct Baz;
+
+impl fmt::Debug for Baz {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        Ok(())
+    }
+}
+
+struct PrivateStruct;
+
+enum PrivateEnum {}
+
+#[derive(Debug)]
+struct GenericType<T>(T);
diff --git a/src/test/run-pass/issue-21306.rs b/src/test/run-pass/issue-21306.rs
new file mode 100644
index 00000000000..c75abd88963
--- /dev/null
+++ b/src/test/run-pass/issue-21306.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+use std::sync::Arc;
+
+fn main() {
+    let x = 5us;
+    let command = Arc::new(Box::new(|&:| { x*2 }));
+    assert_eq!(command(), 10);
+}
diff --git a/src/test/run-pass/issue-21363.rs b/src/test/run-pass/issue-21363.rs
new file mode 100644
index 00000000000..2fc1d9fd643
--- /dev/null
+++ b/src/test/run-pass/issue-21363.rs
@@ -0,0 +1,21 @@
+// 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.
+
+#![no_implicit_prelude]
+
+trait Iterator {
+    type Item;
+}
+
+impl<'a, T> Iterator for &'a mut (Iterator<Item=T> + 'a) {
+    type Item = T;
+}
+
+fn main() {}
diff --git a/src/test/run-pass/unboxed-closures-unique-type-id.rs b/src/test/run-pass/unboxed-closures-unique-type-id.rs
index 4fdfb8cf02a..a04301931da 100644
--- a/src/test/run-pass/unboxed-closures-unique-type-id.rs
+++ b/src/test/run-pass/unboxed-closures-unique-type-id.rs
@@ -12,7 +12,7 @@
 //
 //    error: internal compiler error: get_unique_type_id_of_type() -
 //    unexpected type: closure,
-//    ty_unboxed_closure(syntax::ast::DefId{krate: 0u32, node: 66u32},
+//    ty_closure(syntax::ast::DefId{krate: 0u32, node: 66u32},
 //    ReScope(63u32))
 //
 // This is a regression test for issue #17021.