about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-02 20:26:39 +0000
committerbors <bors@rust-lang.org>2015-03-02 20:26:39 +0000
commit2ca6eaedae9ec4bff2a63f81f473aba653e46ac5 (patch)
treec0f79ec53e9f9ca46755b5ddccc42e67ebbb69a7
parent1cc8b6ec664f30b43f75551e95299d943c8a4e6a (diff)
parentc4b1500fec44c4ed967542fda3cd9c104addbb80 (diff)
downloadrust-2ca6eaedae9ec4bff2a63f81f473aba653e46ac5.tar.gz
rust-2ca6eaedae9ec4bff2a63f81f473aba653e46ac5.zip
Auto merge of #22963 - Manishearth:rollup, r=Manishearth
-rw-r--r--src/doc/intro.md8
-rw-r--r--src/doc/trpl/guessing-game.md18
-rw-r--r--src/libcollections/fmt.rs2
-rw-r--r--src/librustc/metadata/tydecode.rs4
-rw-r--r--src/librustc/metadata/tyencode.rs3
-rw-r--r--src/librustc/middle/fast_reject.rs2
-rw-r--r--src/librustc/middle/infer/combine.rs7
-rw-r--r--src/librustc/middle/liveness.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs2
-rw-r--r--src/librustc/middle/region.rs2
-rw-r--r--src/librustc/middle/traits/project.rs2
-rw-r--r--src/librustc/middle/traits/select.rs8
-rw-r--r--src/librustc/middle/ty.rs24
-rw-r--r--src/librustc/middle/ty_fold.rs5
-rw-r--r--src/librustc/middle/ty_walk.rs2
-rw-r--r--src/librustc/util/ppaux.rs2
-rw-r--r--src/librustc_trans/trans/adt.rs2
-rw-r--r--src/librustc_trans/trans/base.rs8
-rw-r--r--src/librustc_trans/trans/closure.rs2
-rw-r--r--src/librustc_trans/trans/debuginfo.rs4
-rw-r--r--src/librustc_trans/trans/glue.rs3
-rw-r--r--src/librustc_typeck/check/callee.rs2
-rw-r--r--src/librustc_typeck/check/closure.rs10
-rw-r--r--src/librustc_typeck/check/implicator.rs34
-rw-r--r--src/librustc_typeck/check/method/probe.rs6
-rw-r--r--src/librustc_typeck/check/regionck.rs171
-rw-r--r--src/librustc_typeck/coherence/mod.rs2
-rw-r--r--src/libstd/thread.rs38
-rw-r--r--src/libsyntax/feature_gate.rs1
-rw-r--r--src/test/compile-fail/issue-4335.rs4
-rw-r--r--src/test/compile-fail/regions-proc-bound-capture.rs2
-rw-r--r--src/test/compile-fail/regions-steal-closure.rs4
-rwxr-xr-xsrc/test/compile-fail/send-is-not-static-ensures-scoping.rs5
-rw-r--r--src/test/compile-fail/unboxed-closure-region.rs2
34 files changed, 125 insertions, 268 deletions
diff --git a/src/doc/intro.md b/src/doc/intro.md
index 07a90959deb..d145eaada2b 100644
--- a/src/doc/intro.md
+++ b/src/doc/intro.md
@@ -510,10 +510,10 @@ numbers[1] is 3
 numbers[0] is 2
 ```
 
-Each time, we can get a slithtly different output because the threads
-are not quaranteed to run in any set order. If you get the same order
-every time it is because each of these threads are very small and
-complete too fast for their indeterminate behavior to surface.
+Each time, we can get a slightly different output because the threads are not
+guaranteed to run in any set order. If you get the same order every time it is
+because each of these threads are very small and complete too fast for their
+indeterminate behavior to surface.
 
 The important part here is that the Rust compiler was able to use ownership to
 give us assurance _at compile time_ that we weren't doing something incorrect
diff --git a/src/doc/trpl/guessing-game.md b/src/doc/trpl/guessing-game.md
index a40374fe30f..4e7222269a8 100644
--- a/src/doc/trpl/guessing-game.md
+++ b/src/doc/trpl/guessing-game.md
@@ -422,11 +422,11 @@ In this case, we say `x` is a `u32` explicitly, so Rust is able to properly
 tell `random()` what to generate. In a similar fashion, both of these work:
 
 ```{rust,ignore}
-let input_num = "5".parse::<u32>(); // input_num: Option<u32>
-let input_num: Result<u32, _> = "5".parse(); // input_num: Result<u32, <u32 as FromStr>::Err>
+let input_num_option = "5".parse::<u32>().ok(); // input_num: Option<u32>
+let input_num_result: Result<u32, _> = "5".parse(); // input_num: Result<u32, <u32 as FromStr>::Err>
 ```
 
-Here we're converting the `Result` returned by `parse` to an `Option` by using
+Above, we're converting the `Result` returned by `parse` to an `Option` by using
 the `ok` method as well.  Anyway, with us now converting our input to a number,
 our code looks like this:
 
@@ -470,14 +470,14 @@ Let's try it out!
 ```bash
 $ cargo build
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-src/main.rs:22:15: 22:24 error: mismatched types: expected `u32` but found `core::option::Option<u32>` (expected u32 but found enum core::option::Option)
-src/main.rs:22     match cmp(input_num, secret_number) {
+src/main.rs:21:15: 21:24 error: mismatched types: expected `u32`, found `core::result::Result<u32, core::num::ParseIntError>` (expected u32, found enum `core::result::Result`) [E0308]
+src/main.rs:21     match cmp(input_num, secret_number) {
                              ^~~~~~~~~
 error: aborting due to previous error
 ```
 
-Oh yeah! Our `input_num` has the type `Option<u32>`, rather than `u32`. We
-need to unwrap the Option. If you remember from before, `match` is a great way
+Oh yeah! Our `input_num` has the type `Result<u32, <some error>>`, rather than `u32`. We
+need to unwrap the Result. If you remember from before, `match` is a great way
 to do that. Try this code:
 
 ```{rust,no_run}
@@ -500,7 +500,7 @@ fn main() {
     let input_num: Result<u32, _> = input.parse();
 
     let num = match input_num {
-        Ok(num) => num,
+        Ok(n) => n,
         Err(_) => {
             println!("Please input a number!");
             return;
@@ -524,7 +524,7 @@ fn cmp(a: u32, b: u32) -> Ordering {
 }
 ```
 
-We use a `match` to either give us the `u32` inside of the `Option`, or else
+We use a `match` to either give us the `u32` inside of the `Result`, or else
 print an error message and return. Let's give this a shot:
 
 ```bash
diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs
index 98673af3c68..5a20ba4b49f 100644
--- a/src/libcollections/fmt.rs
+++ b/src/libcollections/fmt.rs
@@ -364,7 +364,7 @@
 //!     * `o` - precedes the argument with a "0o"
 //! * '0' - This is used to indicate for integer formats that the padding should
 //!         both be done with a `0` character as well as be sign-aware. A format
-//!         like `{:08d}` would yield `00000001` for the integer `1`, while the
+//!         like `{:08}` would yield `00000001` for the integer `1`, while the
 //!         same format would yield `-0000001` for the integer `-1`. Notice that
 //!         the negative version has one fewer zero than the positive version.
 //!
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index baecfb7eb22..b33839f33e8 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -555,11 +555,9 @@ 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, ClosureSource, conv);
-          let region = parse_region_(st, conv);
           let substs = parse_substs_(st, conv);
           assert_eq!(next(st), ']');
-          return ty::mk_closure(st.tcx, did,
-                  st.tcx.mk_region(region), st.tcx.mk_substs(substs));
+          return ty::mk_closure(st.tcx, did, st.tcx.mk_substs(substs));
       }
       'P' => {
           assert_eq!(next(st), '[');
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 76a365259aa..ebb4153e32b 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -139,9 +139,8 @@ 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_closure(def, region, substs) => {
+        ty::ty_closure(def, substs) => {
             mywrite!(w, "k[{}|", (cx.ds)(def));
-            enc_region(w, cx, *region);
             enc_substs(w, cx, substs);
             mywrite!(w, "]");
         }
diff --git a/src/librustc/middle/fast_reject.rs b/src/librustc/middle/fast_reject.rs
index 7584a2e44cc..063845c6c34 100644
--- a/src/librustc/middle/fast_reject.rs
+++ b/src/librustc/middle/fast_reject.rs
@@ -74,7 +74,7 @@ pub fn simplify_type(tcx: &ty::ctxt,
             let def_id = tcx.lang_items.owned_box().unwrap();
             Some(StructSimplifiedType(def_id))
         }
-        ty::ty_closure(def_id, _, _) => {
+        ty::ty_closure(def_id, _) => {
             Some(ClosureSimplifiedType(def_id))
         }
         ty::ty_tup(ref tys) => {
diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index b782a655d89..be94a73df37 100644
--- a/src/librustc/middle/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -503,15 +503,14 @@ pub fn super_tys<'tcx, C>(this: &C,
             Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs)))
         }
 
-        (&ty::ty_closure(a_id, a_region, a_substs),
-         &ty::ty_closure(b_id, b_region, b_substs))
+        (&ty::ty_closure(a_id, a_substs),
+         &ty::ty_closure(b_id, b_substs))
           if a_id == b_id => {
             // 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_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs)))
+            Ok(ty::mk_closure(tcx, a_id, tcx.mk_substs(substs)))
         }
 
         (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 5cb034667cc..224a568c77f 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1496,7 +1496,7 @@ 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_closure(closure_def_id, _, substs) =>
+            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 c4446b87855..1f02f13a4a1 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -607,7 +607,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           def::DefUpvar(var_id, fn_node_id) => {
               let ty = try!(self.node_ty(fn_node_id));
               match ty.sty {
-                  ty::ty_closure(closure_id, _, _) => {
+                  ty::ty_closure(closure_id, _) => {
                       match self.typer.closure_kind(closure_id) {
                           Some(kind) => {
                               self.cat_upvar(id, span, var_id, fn_node_id, kind)
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 7db1138ac72..b4db3aba786 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -320,8 +320,10 @@ impl InnermostEnclosingExpr {
 
 #[derive(Debug, Copy)]
 pub struct Context {
+    /// the scope that contains any new variables declared
     var_parent: InnermostDeclaringBlock,
 
+    /// region parent of expressions etc
     parent: InnermostEnclosingExpr,
 }
 
diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs
index 7d4febb38e6..b9a863f4fe4 100644
--- a/src/librustc/middle/traits/project.rs
+++ b/src/librustc/middle/traits/project.rs
@@ -154,7 +154,7 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
     debug!("consider_unification_despite_ambiguity: self_ty.sty={:?}",
            self_ty.sty);
     match self_ty.sty {
-        ty::ty_closure(closure_def_id, _, substs) => {
+        ty::ty_closure(closure_def_id, substs) => {
             let closure_typer = selcx.closure_typer();
             let closure_type = closure_typer.closure_type(closure_def_id, substs);
             let ty::Binder((_, ret_type)) =
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index d8c62780a78..470315c78f8 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -293,7 +293,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // lifetimes can appear inside the self-type.
         let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
         let (closure_def_id, substs) = match self_ty.sty {
-            ty::ty_closure(id, _, ref substs) => (id, substs.clone()),
+            ty::ty_closure(id, ref substs) => (id, substs.clone()),
             _ => { return; }
         };
         assert!(!substs.has_escaping_regions());
@@ -1054,7 +1054,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_closure(id, _, ref substs) => (id, substs.clone()),
+            ty::ty_closure(id, ref substs) => (id, substs.clone()),
             ty::ty_infer(ty::TyVar(_)) => {
                 debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
                 candidates.ambiguous = true;
@@ -1533,7 +1533,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
             ty::ty_tup(ref tys) => Ok(If(tys.clone())),
 
-            ty::ty_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
@@ -1687,7 +1687,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 Some(tys.clone())
             }
 
-            ty::ty_closure(def_id, _, substs) => {
+            ty::ty_closure(def_id, substs) => {
                 assert_eq!(def_id.krate, ast::LOCAL_CRATE);
 
                 match self.closure_typer.closure_upvars(def_id, substs) {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 635ec09d339..aaba840825e 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -1367,7 +1367,7 @@ pub enum sty<'tcx> {
     ty_trait(Box<TyTrait<'tcx>>),
     ty_struct(DefId, &'tcx Substs<'tcx>),
 
-    ty_closure(DefId, &'tcx Region, &'tcx Substs<'tcx>),
+    ty_closure(DefId, &'tcx Substs<'tcx>),
 
     ty_tup(Vec<Ty<'tcx>>),
 
@@ -2658,8 +2658,7 @@ impl FlagComputation {
                 }
             }
 
-            &ty_closure(_, region, substs) => {
-                self.add_region(*region);
+            &ty_closure(_, substs) => {
                 self.add_substs(substs);
             }
 
@@ -2927,10 +2926,9 @@ pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
     mk_t(cx, ty_struct(struct_id, substs))
 }
 
-pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId,
-                        region: &'tcx Region, substs: &'tcx Substs<'tcx>)
+pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>)
                         -> Ty<'tcx> {
-    mk_t(cx, ty_closure(closure_id, region, substs))
+    mk_t(cx, ty_closure(closure_id, substs))
 }
 
 pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
@@ -3513,13 +3511,11 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
                 apply_lang_items(cx, did, res)
             }
 
-            ty_closure(did, r, substs) => {
+            ty_closure(did, substs) => {
                 // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
                 let param_env = ty::empty_parameter_environment(cx);
                 let upvars = closure_upvars(&param_env, did, substs).unwrap();
-                TypeContents::union(&upvars,
-                                    |f| tc_ty(cx, &f.ty, cache))
-                    | borrowed_contents(*r, MutMutable)
+                TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
             }
 
             ty_tup(ref tys) => {
@@ -5175,7 +5171,7 @@ pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
             Some(tt.principal_def_id()),
         ty_struct(id, _) |
         ty_enum(id, _) |
-        ty_closure(id, _, _) =>
+        ty_closure(id, _) =>
             Some(id),
         _ =>
             None
@@ -6301,10 +6297,9 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
                 }
                 ty_infer(_) => unreachable!(),
                 ty_err => byte!(21),
-                ty_closure(d, r, _) => {
+                ty_closure(d, _) => {
                     byte!(22);
                     did(state, d);
-                    region(state, *r);
                 }
                 ty_projection(ref data) => {
                     byte!(23);
@@ -6618,8 +6613,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
             ty_struct(_, substs) => {
                 accum_substs(accumulator, substs);
             }
-            ty_closure(_, region, substs) => {
-                accumulator.push(*region);
+            ty_closure(_, substs) => {
                 accum_substs(accumulator, substs);
             }
             ty_bool |
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 4bf47c3a75f..1b904aacc30 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -650,10 +650,9 @@ 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_closure(did, ref region, ref substs) => {
-            let r = region.fold_with(this);
+        ty::ty_closure(did, ref substs) => {
             let s = substs.fold_with(this);
-            ty::ty_closure(did, this.tcx().mk_region(r), this.tcx().mk_substs(s))
+            ty::ty_closure(did, 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 3336e7ee8bf..5b5eac45178 100644
--- a/src/librustc/middle/ty_walk.rs
+++ b/src/librustc/middle/ty_walk.rs
@@ -45,7 +45,7 @@ impl<'tcx> TypeWalker<'tcx> {
             }
             ty::ty_enum(_, ref substs) |
             ty::ty_struct(_, ref substs) |
-            ty::ty_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 15b3c6d9d06..0eeb746022c 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -406,7 +406,7 @@ 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_closure(ref did, _, substs) => {
+        ty_closure(ref did, substs) => {
             let closure_tys = cx.closure_tys.borrow();
             closure_tys.get(did).map(|closure_type| {
                 closure_to_string(cx, &closure_type.subst(cx, substs))
diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs
index 3ea14d3c589..2fb0488cd70 100644
--- a/src/librustc_trans/trans/adt.rs
+++ b/src/librustc_trans/trans/adt.rs
@@ -169,7 +169,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
             Univariant(mk_struct(cx, &ftys[..], packed, t), dtor)
         }
-        ty::ty_closure(def_id, _, substs) => {
+        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<_>>();
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 1f578ac0bdb..7a6960d3790 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -291,7 +291,7 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ty::ty_bare_fn(_, ref f) => {
             (&f.sig, f.abi, None)
         }
-        ty::ty_closure(closure_did, _, substs) => {
+        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);
@@ -685,7 +685,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
               }
           })
       }
-      ty::ty_closure(def_id, _, substs) => {
+      ty::ty_closure(def_id, substs) => {
           let repr = adt::represent_type(cx.ccx(), t);
           let typer = common::NormalizingClosureTyper::new(cx.tcx());
           let upvars = typer.closure_upvars(def_id, substs).unwrap();
@@ -2437,7 +2437,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
     let function_type;
     let (fn_sig, abi, env_ty) = match fn_ty.sty {
         ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, None),
-        ty::ty_closure(closure_did, _, substs) => {
+        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);
@@ -2454,7 +2454,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_closure(_, _, _) => {
+        ty::ty_closure(..) => {
             assert!(abi == RustCall);
 
             match fn_sig.inputs[0].sty {
diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs
index 1d4bbd79d71..7fa26a7c128 100644
--- a/src/librustc_trans/trans/closure.rs
+++ b/src/librustc_trans/trans/closure.rs
@@ -138,7 +138,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
     // duplicate declarations
     let function_type = erase_regions(ccx.tcx(), &function_type);
     let params = match function_type.sty {
-        ty::ty_closure(_, _, substs) => &substs.types,
+        ty::ty_closure(_, substs) => &substs.types,
         _ => unreachable!()
     };
     let mono_id = MonoId {
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index d70a904b811..f3b7058336b 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -472,7 +472,7 @@ impl<'tcx> TypeMap<'tcx> {
                     }
                 }
             },
-            ty::ty_closure(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,
@@ -2983,7 +2983,7 @@ 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_closure(def_id, _, substs) => {
+        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)
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index 9491c8377a6..1151b11d21f 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -313,8 +313,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                      ty::mk_nil(bcx.tcx()));
         let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[..], dtor_ty, DebugLoc::None);
 
-        variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope);
-        variant_cx
+        variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope)
     })
 }
 
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 0ad15456df9..f9495af79c5 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -137,7 +137,7 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             return Some(CallStep::Builtin);
         }
 
-        ty::ty_closure(def_id, _, substs) => {
+        ty::ty_closure(def_id, substs) => {
             assert_eq!(def_id.krate, ast::LOCAL_CRATE);
 
             // Check whether this is a call to a closure where we
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 0b7c5b04aaa..0d4edc01a4c 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -16,7 +16,6 @@ use astconv;
 use middle::region;
 use middle::subst;
 use middle::ty::{self, ToPolyTraitRef, Ty};
-use rscope::RegionScope;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_util;
@@ -61,17 +60,8 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
         abi::RustCall,
         expected_sig);
 
-    let region = match fcx.anon_regions(expr.span, 1) {
-        Err(_) => {
-            fcx.ccx.tcx.sess.span_bug(expr.span,
-                                      "can't make anon regions here?!")
-        }
-        Ok(regions) => regions[0],
-    };
-
     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()));
 
diff --git a/src/librustc_typeck/check/implicator.rs b/src/librustc_typeck/check/implicator.rs
index f65e585d23e..f99ba894029 100644
--- a/src/librustc_typeck/check/implicator.rs
+++ b/src/librustc_typeck/check/implicator.rs
@@ -29,6 +29,7 @@ use util::ppaux::Repr;
 pub enum Implication<'tcx> {
     RegionSubRegion(Option<Ty<'tcx>>, ty::Region, ty::Region),
     RegionSubGeneric(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>),
+    RegionSubClosure(Option<Ty<'tcx>>, ty::Region, ast::DefId, &'tcx Substs<'tcx>),
     Predicate(ast::DefId, ty::Predicate<'tcx>),
 }
 
@@ -91,29 +92,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
                 // No borrowed content reachable here.
             }
 
-            ty::ty_closure(_, region, _) => {
-                // An "closure type" is basically
-                // modeled here as equivalent to a struct like
-                //
-                //     struct TheClosure<'b> {
-                //         ...
-                //     }
-                //
-                // where the `'b` is the lifetime bound of the
-                // contents (i.e., all contents must outlive 'b).
-                //
-                // 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
-                // substitutions of the enclosing parameter
-                // environment.  An upvar captured by value has the
-                // same type as the original local variable which is
-                // already checked for consistency.  If the upvar is
-                // captured by reference it must also outlive the
-                // region bound on the closure, but this is explicitly
-                // handled by logic in regionck.
-                self.push_region_constraint_from_top(*region);
+            ty::ty_closure(def_id, substs) => {
+                let &(r_a, opt_ty) = self.stack.last().unwrap();
+                self.out.push(Implication::RegionSubClosure(opt_ty, r_a, def_id, substs));
             }
 
             ty::ty_trait(ref t) => {
@@ -448,6 +429,13 @@ impl<'tcx> Repr<'tcx> for Implication<'tcx> {
                         p.repr(tcx))
             }
 
+            Implication::RegionSubClosure(_, ref a, ref b, ref c) => {
+                format!("RegionSubClosure({}, {}, {})",
+                        a.repr(tcx),
+                        b.repr(tcx),
+                        c.repr(tcx))
+            }
+
             Implication::Predicate(ref def_id, ref p) => {
                 format!("Predicate({}, {})",
                         def_id.repr(tcx),
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index f24da78bc7d..fbf002b709e 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -278,7 +278,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             }
             ty::ty_enum(did, _) |
             ty::ty_struct(did, _) |
-            ty::ty_closure(did, _, _) => {
+            ty::ty_closure(did, _) => {
                 self.assemble_inherent_impl_candidates_for_type(did);
             }
             ty::ty_uniq(_) => {
@@ -641,8 +641,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         // If so, add "synthetic impls".
         let steps = self.steps.clone();
         for step in &*steps {
-            let (closure_def_id, _, _) = match step.self_ty.sty {
-                ty::ty_closure(a, b, ref c) => (a, b, c),
+            let closure_def_id = match step.self_ty.sty {
+                ty::ty_closure(a, _) => a,
                 _ => continue,
             };
 
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 1518a09e7dc..a3e98b0c4c6 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -87,12 +87,11 @@ use check::dropck;
 use check::FnCtxt;
 use check::implicator;
 use check::vtable;
-use middle::def;
 use middle::mem_categorization as mc;
 use middle::region::CodeExtent;
+use middle::subst::Substs;
 use middle::traits;
-use middle::ty::{ReScope};
-use middle::ty::{self, Ty, MethodCall};
+use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall};
 use middle::infer::{self, GenericKind};
 use middle::pat_util;
 use util::ppaux::{ty_to_string, Repr};
@@ -179,20 +178,6 @@ pub struct Rcx<'a, 'tcx: 'a> {
 
 }
 
-/// Returns the validity region of `def` -- that is, how long is `def` valid?
-fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region {
-    let tcx = fcx.tcx();
-    match def {
-        def::DefLocal(node_id) | def::DefUpvar(node_id, _) => {
-            tcx.region_maps.var_region(node_id)
-        }
-        _ => {
-            tcx.sess.bug(&format!("unexpected def in region_of_def: {:?}",
-                                 def))
-        }
-    }
-}
-
 struct RepeatingScope(ast::NodeId);
 pub enum SubjectNode { Subject(ast::NodeId), None }
 
@@ -368,7 +353,15 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
                                                              ty::ReInfer(ty::ReVar(vid_b))) => {
                         self.fcx.inh.infcx.add_given(free_a, vid_b);
                     }
-                    implicator::Implication::RegionSubRegion(..) => {
+                    implicator::Implication::RegionSubGeneric(_, r_a, ref generic_b) => {
+                        debug!("RegionSubGeneric: {} <= {}",
+                               r_a.repr(tcx), generic_b.repr(tcx));
+
+                        self.region_bound_pairs.push((r_a, generic_b.clone()));
+                    }
+                    implicator::Implication::RegionSubRegion(..) |
+                    implicator::Implication::RegionSubClosure(..) |
+                    implicator::Implication::Predicate(..) => {
                         // In principle, we could record (and take
                         // advantage of) every relationship here, but
                         // we are also free not to -- it simply means
@@ -379,13 +372,6 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
                         // relationship that arises here, but
                         // presently we do not.)
                     }
-                    implicator::Implication::RegionSubGeneric(_, r_a, ref generic_b) => {
-                        debug!("RegionSubGeneric: {} <= {}",
-                               r_a.repr(tcx), generic_b.repr(tcx));
-
-                        self.region_bound_pairs.push((r_a, generic_b.clone()));
-                    }
-                    implicator::Implication::Predicate(..) => { }
                 }
             }
         }
@@ -792,124 +778,9 @@ fn constrain_cast(rcx: &mut Rcx,
 fn check_expr_fn_block(rcx: &mut Rcx,
                        expr: &ast::Expr,
                        body: &ast::Block) {
-    let tcx = rcx.fcx.tcx();
-    let function_type = rcx.resolve_node_type(expr.id);
-
-    match function_type.sty {
-        ty::ty_closure(_, region, _) => {
-            ty::with_freevars(tcx, expr.id, |freevars| {
-                constrain_captured_variables(rcx, *region, expr, freevars);
-            })
-        }
-        _ => { }
-    }
-
     let repeating_scope = rcx.set_repeating_scope(body.id);
     visit::walk_expr(rcx, expr);
     rcx.set_repeating_scope(repeating_scope);
-
-    match function_type.sty {
-        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);
-            })
-        }
-        _ => {}
-    }
-
-    /// Make sure that the type of all free variables referenced inside a closure/proc outlive the
-    /// closure/proc's lifetime bound. This is just a special case of the usual rules about closed
-    /// over values outliving the object's lifetime bound.
-    fn ensure_free_variable_types_outlive_closure_bound(
-        rcx: &mut Rcx,
-        bounds: &ty::ExistentialBounds,
-        expr: &ast::Expr,
-        freevars: &[ty::Freevar])
-    {
-        let tcx = rcx.fcx.ccx.tcx;
-
-        debug!("ensure_free_variable_types_outlive_closure_bound({}, {})",
-               bounds.region_bound.repr(tcx), expr.repr(tcx));
-
-        for freevar in freevars {
-            let var_node_id = {
-                let def_id = freevar.def.def_id();
-                assert!(def_id.krate == ast::LOCAL_CRATE);
-                def_id.node
-            };
-
-            // Compute the type of the field in the environment that
-            // represents `var_node_id`.  For a by-value closure, this
-            // will be the same as the type of the variable.  For a
-            // by-reference closure, this will be `&T` where `T` is
-            // the type of the variable.
-            let raw_var_ty = rcx.resolve_node_type(var_node_id);
-            let upvar_id = ty::UpvarId { var_id: var_node_id,
-                                         closure_expr_id: expr.id };
-            let var_ty = match rcx.fcx.inh.upvar_capture_map.borrow()[upvar_id] {
-                ty::UpvarCapture::ByRef(ref upvar_borrow) => {
-                    ty::mk_rptr(rcx.tcx(),
-                                rcx.tcx().mk_region(upvar_borrow.region),
-                                ty::mt { mutbl: upvar_borrow.kind.to_mutbl_lossy(),
-                                         ty: raw_var_ty })
-                }
-                ty::UpvarCapture::ByValue => raw_var_ty,
-            };
-
-            // Check that the type meets the criteria of the existential bounds:
-            for builtin_bound in &bounds.builtin_bounds {
-                let code = traits::ClosureCapture(var_node_id, expr.span, builtin_bound);
-                let cause = traits::ObligationCause::new(freevar.span, rcx.fcx.body_id, code);
-                rcx.fcx.register_builtin_bound(var_ty, builtin_bound, cause);
-            }
-
-            type_must_outlive(
-                rcx, infer::FreeVariable(expr.span, var_node_id),
-                var_ty, bounds.region_bound);
-        }
-    }
-
-    /// Make sure that all free variables referenced inside the closure outlive the closure's
-    /// lifetime bound. Also, create an entry in the upvar_borrows map with a region.
-    fn constrain_captured_variables(
-        rcx: &mut Rcx,
-        region_bound: ty::Region,
-        expr: &ast::Expr,
-        freevars: &[ty::Freevar])
-    {
-        let tcx = rcx.fcx.ccx.tcx;
-        debug!("constrain_captured_variables({}, {})",
-               region_bound.repr(tcx), expr.repr(tcx));
-        for freevar in freevars {
-            debug!("constrain_captured_variables: freevar.def={:?}", freevar.def);
-
-            // Identify the variable being closed over and its node-id.
-            let def = freevar.def;
-            let var_node_id = {
-                let def_id = def.def_id();
-                assert!(def_id.krate == ast::LOCAL_CRATE);
-                def_id.node
-            };
-            let upvar_id = ty::UpvarId { var_id: var_node_id,
-                                         closure_expr_id: expr.id };
-
-            match rcx.fcx.inh.upvar_capture_map.borrow()[upvar_id] {
-                ty::UpvarCapture::ByValue => { }
-                ty::UpvarCapture::ByRef(upvar_borrow) => {
-                    rcx.fcx.mk_subr(infer::FreeVariable(freevar.span, var_node_id),
-                                    region_bound, upvar_borrow.region);
-
-                    // Guarantee that the closure does not outlive the variable itself.
-                    let enclosing_region = region_of_def(rcx.fcx, def);
-                    debug!("constrain_captured_variables: enclosing_region = {}",
-                           enclosing_region.repr(tcx));
-                    rcx.fcx.mk_subr(infer::FreeVariable(freevar.span, var_node_id),
-                                    region_bound, enclosing_region);
-                }
-            }
-        }
-    }
 }
 
 fn constrain_callee(rcx: &mut Rcx,
@@ -1538,6 +1409,9 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                 let o1 = infer::ReferenceOutlivesReferent(ty, origin.span());
                 generic_must_outlive(rcx, o1, r_a, generic_b);
             }
+            implicator::Implication::RegionSubClosure(_, r_a, def_id, substs) => {
+                closure_must_outlive(rcx, origin.clone(), r_a, def_id, substs);
+            }
             implicator::Implication::Predicate(def_id, predicate) => {
                 let cause = traits::ObligationCause::new(origin.span(),
                                                          rcx.body_id,
@@ -1549,6 +1423,23 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
     }
 }
 
+fn closure_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
+                                  origin: infer::SubregionOrigin<'tcx>,
+                                  region: ty::Region,
+                                  def_id: ast::DefId,
+                                  substs: &'tcx Substs<'tcx>) {
+    debug!("closure_must_outlive(region={}, def_id={}, substs={})",
+           region.repr(rcx.tcx()), def_id.repr(rcx.tcx()), substs.repr(rcx.tcx()));
+
+    let upvars = rcx.fcx.closure_upvars(def_id, substs).unwrap();
+    for upvar in upvars {
+        let var_id = upvar.def.def_id().local_id();
+        type_must_outlive(
+            rcx, infer::FreeVariable(origin.span(), var_id),
+            upvar.ty, region);
+    }
+}
+
 fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
                                   origin: infer::SubregionOrigin<'tcx>,
                                   region: ty::Region,
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 1913b55f1d8..58b67d31ab5 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -397,7 +397,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_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/libstd/thread.rs b/src/libstd/thread.rs
index 5dd4be336ec..883c1bbbbe5 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -28,25 +28,25 @@
 //! a thread will unwind the stack, running destructors and freeing
 //! owned resources. Thread panic is unrecoverable from within
 //! the panicking thread (i.e. there is no 'try/catch' in Rust), but
-//! panic may optionally be detected from a different thread. If
-//! the main thread panics the application will exit with a non-zero
+//! the panic may optionally be detected from a different thread. If
+//! the main thread panics, the application will exit with a non-zero
 //! exit code.
 //!
 //! When the main thread of a Rust program terminates, the entire program shuts
 //! down, even if other threads are still running. However, this module provides
 //! convenient facilities for automatically waiting for the termination of a
-//! child thread (i.e., join), described below.
+//! child thread (i.e., join).
 //!
 //! ## The `Thread` type
 //!
-//! Already-running threads are represented via the `Thread` type, which you can
+//! Threads are represented via the `Thread` type, which you can
 //! get in one of two ways:
 //!
-//! * By spawning a new thread, e.g. using the `thread::spawn` constructor;
+//! * By spawning a new thread, e.g. using the `thread::spawn` function.
 //! * By requesting the current thread, using the `thread::current` function.
 //!
 //! Threads can be named, and provide some built-in support for low-level
-//! synchronization described below.
+//! synchronization (described below).
 //!
 //! The `thread::current()` function is available even for threads not spawned
 //! by the APIs of this module.
@@ -59,29 +59,27 @@
 //! use std::thread;
 //!
 //! thread::spawn(move || {
-//!     println!("Hello, World!");
-//!     // some computation here
+//!     // some work here
 //! });
 //! ```
 //!
 //! In this example, the spawned thread is "detached" from the current
-//! thread, meaning that it can outlive the thread that spawned
-//! it. (Note, however, that when the main thread terminates all
-//! detached threads are terminated as well.)
+//! thread. This means that it can outlive its parent (the thread that spawned
+//! it), unless this parent is the main thread.
 //!
 //! ## Scoped threads
 //!
 //! Often a parent thread uses a child thread to perform some particular task,
 //! and at some point must wait for the child to complete before continuing.
-//! For this scenario, use the `scoped` constructor:
+//! For this scenario, use the `thread::scoped` function:
 //!
 //! ```rust
 //! use std::thread;
 //!
 //! let guard = thread::scoped(move || {
-//!     println!("Hello, World!");
-//!     // some computation here
+//!     // some work here
 //! });
+//!
 //! // do some other work in the meantime
 //! let output = guard.join();
 //! ```
@@ -92,11 +90,7 @@
 //! terminates) when it is dropped. You can join the child thread in
 //! advance by calling the `join` method on the guard, which will also
 //! return the result produced by the thread.  A handle to the thread
-//! itself is available via the `thread` method on the join guard.
-//!
-//! (Note: eventually, the `scoped` constructor will allow the parent and child
-//! threads to data that lives on the parent thread's stack, but some language
-//! changes are needed before this is possible.)
+//! itself is available via the `thread` method of the join guard.
 //!
 //! ## Configuring threads
 //!
@@ -108,7 +102,7 @@
 //! use std::thread;
 //!
 //! thread::Builder::new().name("child1".to_string()).spawn(move || {
-//!     println!("Hello, world!")
+//!     println!("Hello, world!");
 //! });
 //! ```
 //!
@@ -121,7 +115,7 @@
 //! initially not present:
 //!
 //! * The `thread::park()` function blocks the current thread unless or until
-//!   the token is available for its thread handle, at which point It atomically
+//!   the token is available for its thread handle, at which point it atomically
 //!   consumes the token. It may also return *spuriously*, without consuming the
 //!   token. `thread::park_timeout()` does the same, but allows specifying a
 //!   maximum time to block the thread for.
@@ -143,7 +137,7 @@
 //! * It avoids the need to allocate mutexes and condvars when building new
 //!   synchronization primitives; the threads already provide basic blocking/signaling.
 //!
-//! * It can be implemented highly efficiently on many platforms.
+//! * It can be implemented very efficiently on many platforms.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index ffc136d5a1d..8043bd9bd70 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -173,6 +173,7 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
     ("plugin_registrar", Normal),
 
     ("cfg", Normal),
+    ("cfg_attr", Normal),
     ("main", Normal),
     ("start", Normal),
     ("test", Normal),
diff --git a/src/test/compile-fail/issue-4335.rs b/src/test/compile-fail/issue-4335.rs
index d0da51373d9..85298e4c6e0 100644
--- a/src/test/compile-fail/issue-4335.rs
+++ b/src/test/compile-fail/issue-4335.rs
@@ -14,7 +14,9 @@
 fn id<T>(t: T) -> T { t }
 
 fn f<'r, T>(v: &'r T) -> Box<FnMut() -> T + 'r> {
-    id(box || *v) //~ ERROR cannot infer
+    id(box || *v)
+        //~^ ERROR `v` does not live long enough
+        //~| ERROR cannot move out of borrowed content
 }
 
 fn main() {
diff --git a/src/test/compile-fail/regions-proc-bound-capture.rs b/src/test/compile-fail/regions-proc-bound-capture.rs
index 7ea4d1c7507..cc33d112417 100644
--- a/src/test/compile-fail/regions-proc-bound-capture.rs
+++ b/src/test/compile-fail/regions-proc-bound-capture.rs
@@ -18,7 +18,7 @@ fn borrowed_proc<'a>(x: &'a isize) -> Box<FnMut()->(isize) + 'a> {
 
 fn static_proc(x: &isize) -> Box<FnMut()->(isize) + 'static> {
     // This is illegal, because the region bound on `proc` is 'static.
-    box move|| { *x } //~ ERROR cannot infer
+    box move|| { *x } //~ ERROR captured variable `x` does not outlive the enclosing closure
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/regions-steal-closure.rs b/src/test/compile-fail/regions-steal-closure.rs
index 97b51fdb325..c9b378d1df2 100644
--- a/src/test/compile-fail/regions-steal-closure.rs
+++ b/src/test/compile-fail/regions-steal-closure.rs
@@ -20,9 +20,9 @@ fn box_it<'r>(x: Box<FnMut() + 'r>) -> closure_box<'r> {
 }
 
 fn main() {
-    let cl_box = {
+    let mut cl_box = {
         let mut i = 3;
-        box_it(box || i += 1) //~ ERROR cannot infer
+        box_it(box || i += 1) //~ ERROR `i` does not live long enough
     };
     cl_box.cl.call_mut(());
 }
diff --git a/src/test/compile-fail/send-is-not-static-ensures-scoping.rs b/src/test/compile-fail/send-is-not-static-ensures-scoping.rs
index abbcd7e4590..fe03ca8353d 100755
--- a/src/test/compile-fail/send-is-not-static-ensures-scoping.rs
+++ b/src/test/compile-fail/send-is-not-static-ensures-scoping.rs
@@ -13,9 +13,10 @@ use std::thread;
 fn main() {
     let bad = {
         let x = 1;
-        let y = &x;
+        let y = &x; //~ ERROR `x` does not live long enough
 
-        thread::scoped(|| { //~ ERROR cannot infer an appropriate lifetime
+        thread::scoped(|| {
+            //~^ ERROR `y` does not live long enough
             let _z = y;
         })
     };
diff --git a/src/test/compile-fail/unboxed-closure-region.rs b/src/test/compile-fail/unboxed-closure-region.rs
index 59c84953718..5f4bf0d33be 100644
--- a/src/test/compile-fail/unboxed-closure-region.rs
+++ b/src/test/compile-fail/unboxed-closure-region.rs
@@ -15,6 +15,6 @@
 fn main() {
     let _f = {
         let x = 0_usize;
-        || x //~ ERROR cannot infer an appropriate lifetime due to conflicting requirements
+        || x //~ ERROR `x` does not live long enough
     };
 }