about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-28 13:49:35 +0000
committerbors <bors@rust-lang.org>2015-02-28 13:49:35 +0000
commit8a69110c3b1122596ddc8999bb2403a5777bb8ed (patch)
tree9fb065fb1a4875074ca1a9795c0136d0f44da2a3 /src
parent6f8d83140618721e7b72a78f2e53a08e71e1d4cb (diff)
parent077595943193ed8f0ae81e93a8e06781f79351ec (diff)
downloadrust-8a69110c3b1122596ddc8999bb2403a5777bb8ed.tar.gz
rust-8a69110c3b1122596ddc8999bb2403a5777bb8ed.zip
Auto merge of #22895 - Manishearth:rollup, r=Manishearth
r? @Manishearth
Diffstat (limited to 'src')
-rw-r--r--src/compiletest/compiletest.rs1
-rw-r--r--src/doc/intro.md4
-rw-r--r--src/doc/reference.md4
-rw-r--r--src/doc/trpl/installing-rust.md4
-rw-r--r--src/doc/trpl/plugins.md8
-rw-r--r--src/libcore/iter.rs54
-rw-r--r--src/liblog/lib.rs1
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/const_eval.rs2
-rw-r--r--src/librustc_back/lib.rs1
-rw-r--r--src/librustc_driver/lib.rs2
-rw-r--r--src/librustc_trans/lib.rs1
-rw-r--r--src/librustc_typeck/check/dropck.rs2
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/libstd/env.rs267
-rw-r--r--src/libstd/sys/unix/process2.rs2
-rw-r--r--src/libstd/sys/windows/process2.rs2
-rw-r--r--src/libsyntax/diagnostics/plugin.rs11
-rw-r--r--src/libsyntax/ext/asm.rs2
-rw-r--r--src/libsyntax/ext/base.rs116
-rw-r--r--src/libsyntax/ext/cfg.rs2
-rw-r--r--src/libsyntax/ext/concat.rs2
-rw-r--r--src/libsyntax/ext/concat_idents.rs2
-rw-r--r--src/libsyntax/ext/env.rs4
-rw-r--r--src/libsyntax/ext/format.rs2
-rw-r--r--src/libsyntax/ext/quote.rs16
-rw-r--r--src/libsyntax/ext/source_util.rs14
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/parse/parser.rs1
-rw-r--r--src/libterm/lib.rs1
-rw-r--r--src/libtest/lib.rs1
-rw-r--r--src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs7
-rw-r--r--src/test/auxiliary/macro_crate_test.rs6
-rw-r--r--src/test/auxiliary/plugin_args.rs4
-rw-r--r--src/test/auxiliary/roman_numerals.rs4
-rw-r--r--src/test/auxiliary/syntax_extension_with_dll_deps_2.rs2
-rw-r--r--src/test/parse-fail/obsolete-closure-kind.rs18
37 files changed, 247 insertions, 327 deletions
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index 417e050c8b8..4993dd140d3 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -20,7 +20,6 @@
 #![feature(std_misc)]
 #![feature(test)]
 #![feature(unicode)]
-#![feature(env)]
 #![feature(core)]
 
 #![deny(warnings)]
diff --git a/src/doc/intro.md b/src/doc/intro.md
index c9d834ee123..07a90959deb 100644
--- a/src/doc/intro.md
+++ b/src/doc/intro.md
@@ -536,7 +536,7 @@ use std::thread::Thread;
 
 fn main() {
     let numbers = vec![1, 2, 3];
-    
+
     let guards: Vec<_> = (0..3).map(|i| {
         Thread::scoped(move || {
             println!("{}", numbers[i]);
@@ -565,7 +565,7 @@ while retaining safety. The answer is iterators:
 ```{rust}
 let vec = vec![1, 2, 3];
 
-for x in vec.iter() {
+for x in &vec {
     println!("{}", x);
 }
 ```
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 87130c08991..2f047d2c173 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -3765,9 +3765,9 @@ An example of creating and calling a closure:
 ```rust
 let captured_var = 10;
 
-let closure_no_args = |&:| println!("captured_var={}", captured_var);
+let closure_no_args = || println!("captured_var={}", captured_var);
 
-let closure_args = |&: arg: i32| -> i32 {
+let closure_args = |arg: i32| -> i32 {
   println!("captured_var={}, arg={}", captured_var, arg);
   arg // Note lack of semicolon after 'arg'
 };
diff --git a/src/doc/trpl/installing-rust.md b/src/doc/trpl/installing-rust.md
index 5bc33d0a232..6aa4bba6fa6 100644
--- a/src/doc/trpl/installing-rust.md
+++ b/src/doc/trpl/installing-rust.md
@@ -70,10 +70,10 @@ If you've got Rust installed, you can open up a shell, and type this:
 $ rustc --version
 ```
 
-You should see some output that looks something like this:
+You should see the version number, commit hash, commit date and build date:
 
 ```bash
-rustc 1.0.0-nightly (f11f3e7ba 2015-01-04 20:02:14 +0000)
+rustc 1.0.0-nightly (f11f3e7ba 2015-01-04) (built 2015-01-06)
 ```
 
 If you did, Rust has been installed successfully! Congrats!
diff --git a/src/doc/trpl/plugins.md b/src/doc/trpl/plugins.md
index f609a0a918a..a093b97eefb 100644
--- a/src/doc/trpl/plugins.md
+++ b/src/doc/trpl/plugins.md
@@ -71,8 +71,8 @@ extern crate rustc;
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::ast::{TokenTree, TtToken};
-use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
-use syntax::ext::build::AstBuilder;  // trait for expr_uint
+use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
+use syntax::ext::build::AstBuilder;  // trait for expr_usize
 use rustc::plugin::Registry;
 
 fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
@@ -107,7 +107,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         }
     }
 
-    MacExpr::new(cx.expr_uint(sp, total))
+    MacEager::expr(cx.expr_usize(sp, total))
 }
 
 #[plugin_registrar]
@@ -183,7 +183,7 @@ with
 [`syntax::print::pprust::*_to_string`](http://doc.rust-lang.org/syntax/print/pprust/index.html#functions).
 
 The example above produced an integer literal using
-[`AstBuilder::expr_uint`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint).
+[`AstBuilder::expr_usize`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_usize).
 As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of
 [quasiquote macros](../syntax/ext/quote/index.html).  They are undocumented and
 very rough around the edges.  However, the implementation may be a good
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 94cc933d844..4c9e8f47d0e 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -2874,10 +2874,10 @@ pub mod order {
     use super::Iterator;
 
     /// Compare `a` and `b` for equality using `Eq`
-    pub fn equals<A, T, S>(mut a: T, mut b: S) -> bool where
+    pub fn equals<A, L, R>(mut a: L, mut b: R) -> bool where
         A: Eq,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+        L: Iterator<Item=A>,
+        R: Iterator<Item=A>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2889,10 +2889,10 @@ pub mod order {
     }
 
     /// Order `a` and `b` lexicographically using `Ord`
-    pub fn cmp<A, T, S>(mut a: T, mut b: S) -> cmp::Ordering where
+    pub fn cmp<A, L, R>(mut a: L, mut b: R) -> cmp::Ordering where
         A: Ord,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+        L: Iterator<Item=A>,
+        R: Iterator<Item=A>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2908,10 +2908,8 @@ pub mod order {
     }
 
     /// Order `a` and `b` lexicographically using `PartialOrd`
-    pub fn partial_cmp<A, T, S>(mut a: T, mut b: S) -> Option<cmp::Ordering> where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn partial_cmp<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> Option<cmp::Ordering> where
+        L::Item: PartialOrd<R::Item>
     {
         loop {
             match (a.next(), b.next()) {
@@ -2927,10 +2925,8 @@ pub mod order {
     }
 
     /// Compare `a` and `b` for equality (Using partial equality, `PartialEq`)
-    pub fn eq<A, B, L, R>(mut a: L, mut b: R) -> bool where
-        A: PartialEq<B>,
-        L: Iterator<Item=A>,
-        R: Iterator<Item=B>,
+    pub fn eq<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialEq<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2942,10 +2938,8 @@ pub mod order {
     }
 
     /// Compare `a` and `b` for nonequality (Using partial equality, `PartialEq`)
-    pub fn ne<A, B, L, R>(mut a: L, mut b: R) -> bool where
-        A: PartialEq<B>,
-        L: Iterator<Item=A>,
-        R: Iterator<Item=B>,
+    pub fn ne<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialEq<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2957,10 +2951,8 @@ pub mod order {
     }
 
     /// Return `a` < `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn lt<A, T, S>(mut a: T, mut b: S) -> bool where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn lt<R: Iterator, L: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialOrd<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2973,10 +2965,8 @@ pub mod order {
     }
 
     /// Return `a` <= `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn le<A, T, S>(mut a: T, mut b: S) -> bool where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn le<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialOrd<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2989,10 +2979,8 @@ pub mod order {
     }
 
     /// Return `a` > `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn gt<A, T, S>(mut a: T, mut b: S) -> bool where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn gt<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialOrd<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -3005,10 +2993,8 @@ pub mod order {
     }
 
     /// Return `a` >= `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn ge<A, T, S>(mut a: T, mut b: S) -> bool where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn ge<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialOrd<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
index 5e80bc5db2e..d0105bb6577 100644
--- a/src/liblog/lib.rs
+++ b/src/liblog/lib.rs
@@ -174,7 +174,6 @@
 #![feature(core)]
 #![feature(old_io)]
 #![feature(std_misc)]
-#![feature(env)]
 
 use std::boxed;
 use std::cell::RefCell;
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 0b95b38722c..aa51320ee7f 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -31,7 +31,6 @@
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(libc)]
-#![feature(env)]
 #![feature(old_path)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index f793d3ce2fb..0c9f9d2a530 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -257,7 +257,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
             }
           }
           (Ok(const_int(a)), Ok(const_int(b))) => {
-            let is_a_min_value = |&:| {
+            let is_a_min_value = || {
                 let int_ty = match ty::expr_ty_opt(tcx, e).map(|ty| &ty.sty) {
                     Some(&ty::ty_int(int_ty)) => int_ty,
                     _ => return false
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index 711f937d2f3..9005c666afb 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -40,7 +40,6 @@
 #![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(env)]
 #![feature(path)]
 
 extern crate syntax;
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index f0c7777b0af..d08fb2b313e 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -26,7 +26,6 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(env)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(libc)]
@@ -38,6 +37,7 @@
 #![feature(unsafe_destructor)]
 #![feature(staged_api)]
 #![feature(unicode)]
+#![feature(exit_status)]
 
 extern crate arena;
 extern crate flate;
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 3deca436a1f..71317d5875b 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -30,7 +30,6 @@
 #![feature(core)]
 #![feature(int_uint)]
 #![feature(old_io)]
-#![feature(env)]
 #![feature(libc)]
 #![feature(old_path)]
 #![feature(quote)]
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index ce67369ca9d..083523f7ba9 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -45,7 +45,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
     scope: region::CodeExtent,
     depth: uint)
 {
-    let origin = |&:| infer::SubregionOrigin::SafeDestructor(span);
+    let origin = || infer::SubregionOrigin::SafeDestructor(span);
     let mut walker = ty_root.walk();
     let opt_phantom_data_def_id = rcx.tcx().lang_items.phantom_data();
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index fcad91bf14a..e58239a82c6 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -22,7 +22,7 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(env)]
+#![feature(exit_status)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(libc)]
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index e2849ec92e0..1968ca4b9e7 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -14,7 +14,7 @@
 //! environment varibles, process arguments, the current directory, and various
 //! other important directories.
 
-#![unstable(feature = "env", reason = "recently added via RFC 578")]
+#![stable(feature = "env", since = "1.0.0")]
 
 use prelude::v1::*;
 
@@ -47,6 +47,7 @@ use sys::os as os_imp;
 /// let p = env::current_dir().unwrap();
 /// println!("The current directory is {}", p.display());
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn current_dir() -> io::Result<PathBuf> {
     os_imp::getcwd()
 }
@@ -64,6 +65,7 @@ pub fn current_dir() -> io::Result<PathBuf> {
 /// assert!(env::set_current_dir(&root).is_ok());
 /// println!("Successfully changed working directory to {}!", root.display());
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn set_current_dir<P: AsPath + ?Sized>(p: &P) -> io::Result<()> {
     os_imp::chdir(p.as_path())
 }
@@ -74,12 +76,14 @@ static ENV_LOCK: StaticMutex = MUTEX_INIT;
 ///
 /// This iterator is created through `std::env::vars()` and yields `(String,
 /// String)` pairs.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct Vars { inner: VarsOs }
 
 /// An iterator over a snapshot of the environment variables of this process.
 ///
 /// This iterator is created through `std::env::vars_os()` and yields
 /// `(OsString, OsString)` pairs.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct VarsOs { inner: os_imp::Env }
 
 /// Returns an iterator of (variable, value) pairs of strings, for all the
@@ -106,6 +110,7 @@ pub struct VarsOs { inner: os_imp::Env }
 ///     println!("{}: {}", key, value);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn vars() -> Vars {
     Vars { inner: vars_os() }
 }
@@ -128,11 +133,13 @@ pub fn vars() -> Vars {
 ///     println!("{:?}: {:?}", key, value);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn vars_os() -> VarsOs {
     let _g = ENV_LOCK.lock();
     VarsOs { inner: os_imp::env() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Iterator for Vars {
     type Item = (String, String);
     fn next(&mut self) -> Option<(String, String)> {
@@ -143,6 +150,7 @@ impl Iterator for Vars {
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Iterator for VarsOs {
     type Item = (OsString, OsString);
     fn next(&mut self) -> Option<(OsString, OsString)> { self.inner.next() }
@@ -166,6 +174,7 @@ impl Iterator for VarsOs {
 ///     Err(e) => println!("couldn't interpret {}: {}", key, e),
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsOsStr {
     match var_os(key) {
         Some(s) => s.into_string().map_err(VarError::NotUnicode),
@@ -187,6 +196,7 @@ pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsOsStr {
 ///     None => println!("{} is not defined in the environment.", key)
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn var_os<K: ?Sized>(key: &K) -> Option<OsString> where K: AsOsStr {
     let _g = ENV_LOCK.lock();
     os_imp::getenv(key.as_os_str())
@@ -194,17 +204,21 @@ pub fn var_os<K: ?Sized>(key: &K) -> Option<OsString> where K: AsOsStr {
 
 /// Possible errors from the `env::var` method.
 #[derive(Debug, PartialEq, Eq, Clone)]
+#[stable(feature = "env", since = "1.0.0")]
 pub enum VarError {
     /// The specified environment variable was not present in the current
     /// process's environment.
+    #[stable(feature = "env", since = "1.0.0")]
     NotPresent,
 
     /// The specified environment variable was found, but it did not contain
     /// valid unicode data. The found data is returned as a payload of this
     /// variant.
+    #[stable(feature = "env", since = "1.0.0")]
     NotUnicode(OsString),
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl fmt::Display for VarError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -216,6 +230,7 @@ impl fmt::Display for VarError {
     }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Error for VarError {
     fn description(&self) -> &str {
         match *self {
@@ -237,6 +252,7 @@ impl Error for VarError {
 /// env::set_var(key, "VALUE");
 /// assert_eq!(env::var(key), Ok("VALUE".to_string()));
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn set_var<K: ?Sized, V: ?Sized>(k: &K, v: &V)
     where K: AsOsStr, V: AsOsStr
 {
@@ -245,6 +261,7 @@ pub fn set_var<K: ?Sized, V: ?Sized>(k: &K, v: &V)
 }
 
 /// Remove a variable from the environment entirely.
+#[stable(feature = "env", since = "1.0.0")]
 pub fn remove_var<K: ?Sized>(k: &K) where K: AsOsStr {
     let _g = ENV_LOCK.lock();
     os_imp::unsetenv(k.as_os_str())
@@ -254,6 +271,7 @@ pub fn remove_var<K: ?Sized>(k: &K) where K: AsOsStr {
 /// according to platform-specific conventions.
 ///
 /// This structure is returned from `std::env::split_paths`.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a> }
 
 /// Parses input according to platform conventions for the `PATH`
@@ -276,10 +294,12 @@ pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a> }
 ///     None => println!("{} is not defined in the environment.", key)
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn split_paths<T: AsOsStr + ?Sized>(unparsed: &T) -> SplitPaths {
     SplitPaths { inner: os_imp::split_paths(unparsed.as_os_str()) }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl<'a> Iterator for SplitPaths<'a> {
     type Item = PathBuf;
     fn next(&mut self) -> Option<PathBuf> { self.inner.next() }
@@ -289,6 +309,7 @@ impl<'a> Iterator for SplitPaths<'a> {
 /// Error type returned from `std::env::join_paths` when paths fail to be
 /// joined.
 #[derive(Debug)]
+#[stable(feature = "env", since = "1.0.0")]
 pub struct JoinPathsError {
     inner: os_imp::JoinPathsError
 }
@@ -315,6 +336,7 @@ pub struct JoinPathsError {
 ///     env::set_var("PATH", &new_path);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
     where I: Iterator<Item=T>, T: AsOsStr
 {
@@ -323,12 +345,14 @@ pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
     })
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl fmt::Display for JoinPathsError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.inner.fmt(f)
     }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Error for JoinPathsError {
     fn description(&self) -> &str { self.inner.description() }
 }
@@ -357,6 +381,7 @@ impl Error for JoinPathsError {
 ///     None => println!("Impossible to get your home dir!")
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn home_dir() -> Option<PathBuf> {
     os_imp::home_dir()
 }
@@ -371,6 +396,7 @@ pub fn home_dir() -> Option<PathBuf> {
 /// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
 /// 'USERPROFILE' environment variable  if any are set and not the empty
 /// string. Otherwise, tmpdir returns the path to the Windows directory.
+#[stable(feature = "env", since = "1.0.0")]
 pub fn temp_dir() -> PathBuf {
     os_imp::temp_dir()
 }
@@ -398,6 +424,7 @@ pub fn temp_dir() -> PathBuf {
 ///     Err(e) => println!("failed to get current exe path: {}", e),
 /// };
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn current_exe() -> io::Result<PathBuf> {
     os_imp::current_exe()
 }
@@ -412,12 +439,14 @@ static EXIT_STATUS: AtomicIsize = ATOMIC_ISIZE_INIT;
 /// ignored and the process exits with the default panic status.
 ///
 /// Note that this is not synchronized against modifications of other threads.
+#[unstable(feature = "exit_status", reason = "managing the exit status may change")]
 pub fn set_exit_status(code: i32) {
     EXIT_STATUS.store(code as isize, Ordering::SeqCst)
 }
 
 /// Fetches the process's current exit code. This defaults to 0 and can change
 /// by calling `set_exit_status`.
+#[unstable(feature = "exit_status", reason = "managing the exit status may change")]
 pub fn get_exit_status() -> i32 {
     EXIT_STATUS.load(Ordering::SeqCst) as i32
 }
@@ -426,12 +455,14 @@ pub fn get_exit_status() -> i32 {
 /// for each argument.
 ///
 /// This structure is created through the `std::env::args` method.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct Args { inner: ArgsOs }
 
 /// An iterator over the arguments of a process, yielding an `OsString` value
 /// for each argument.
 ///
 /// This structure is created through the `std::env::args_os` method.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct ArgsOs { inner: os_imp::Args }
 
 /// Returns the arguments which this program was started with (normally passed
@@ -457,6 +488,7 @@ pub struct ArgsOs { inner: os_imp::Args }
 ///     println!("{}", argument);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn args() -> Args {
     Args { inner: args_os() }
 }
@@ -478,10 +510,12 @@ pub fn args() -> Args {
 ///     println!("{:?}", argument);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn args_os() -> ArgsOs {
     ArgsOs { inner: os_imp::args() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Iterator for Args {
     type Item = String;
     fn next(&mut self) -> Option<String> {
@@ -490,333 +524,200 @@ impl Iterator for Args {
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl ExactSizeIterator for Args {
     fn len(&self) -> usize { self.inner.len() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Iterator for ArgsOs {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> { self.inner.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl ExactSizeIterator for ArgsOs {
     fn len(&self) -> usize { self.inner.len() }
 }
 
 /// Returns the page size of the current architecture in bytes.
+#[unstable(feature = "page_size", reason = "naming and/or location may change")]
 pub fn page_size() -> usize {
     os_imp::page_size()
 }
 
 /// Constants associated with the current target
-#[cfg(target_os = "linux")]
+#[stable(feature = "env", since = "1.0.0")]
 pub mod consts {
-    pub use super::arch_consts::ARCH;
+    /// A string describing the architecture of the CPU that this is currently
+    /// in use.
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const ARCH: &'static str = super::arch::ARCH;
 
-    pub const FAMILY: &'static str = "unix";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const FAMILY: &'static str = super::os::FAMILY;
 
     /// A string describing the specific operating system in use: in this
     /// case, `linux`.
-    pub const OS: &'static str = "linux";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const OS: &'static str = super::os::OS;
 
     /// Specifies the filename prefix used for shared libraries on this
     /// platform: in this case, `lib`.
-    pub const DLL_PREFIX: &'static str = "lib";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const DLL_PREFIX: &'static str = super::os::DLL_PREFIX;
 
     /// Specifies the filename suffix used for shared libraries on this
     /// platform: in this case, `.so`.
-    pub const DLL_SUFFIX: &'static str = ".so";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const DLL_SUFFIX: &'static str = super::os::DLL_SUFFIX;
 
     /// Specifies the file extension used for shared libraries on this
     /// platform that goes after the dot: in this case, `so`.
-    pub const DLL_EXTENSION: &'static str = "so";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const DLL_EXTENSION: &'static str = super::os::DLL_EXTENSION;
 
     /// Specifies the filename suffix used for executable binaries on this
     /// platform: in this case, the empty string.
-    pub const EXE_SUFFIX: &'static str = "";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const EXE_SUFFIX: &'static str = super::os::EXE_SUFFIX;
 
     /// Specifies the file extension, if any, used for executable binaries
     /// on this platform: in this case, the empty string.
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const EXE_EXTENSION: &'static str = super::os::EXE_EXTENSION;
+
+}
+
+#[cfg(target_os = "linux")]
+mod os {
+    pub const FAMILY: &'static str = "unix";
+    pub const OS: &'static str = "linux";
+    pub const DLL_PREFIX: &'static str = "lib";
+    pub const DLL_SUFFIX: &'static str = ".so";
+    pub const DLL_EXTENSION: &'static str = "so";
+    pub const EXE_SUFFIX: &'static str = "";
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "macos")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `macos`.
     pub const OS: &'static str = "macos";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.dylib`.
     pub const DLL_SUFFIX: &'static str = ".dylib";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `dylib`.
     pub const DLL_EXTENSION: &'static str = "dylib";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "ios")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `ios`.
     pub const OS: &'static str = "ios";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "freebsd")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `freebsd`.
     pub const OS: &'static str = "freebsd";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
     pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
     pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "dragonfly")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `dragonfly`.
     pub const OS: &'static str = "dragonfly";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
     pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
     pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "bitrig")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `bitrig`.
     pub const OS: &'static str = "bitrig";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
     pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
     pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "openbsd")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `openbsd`.
     pub const OS: &'static str = "openbsd";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
     pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
     pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "android")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `android`.
     pub const OS: &'static str = "android";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
     pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
     pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "windows")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "windows";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `windows`.
     pub const OS: &'static str = "windows";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, the empty string.
     pub const DLL_PREFIX: &'static str = "";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.dll`.
     pub const DLL_SUFFIX: &'static str = ".dll";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `dll`.
     pub const DLL_EXTENSION: &'static str = "dll";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, `.exe`.
     pub const EXE_SUFFIX: &'static str = ".exe";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, `exe`.
     pub const EXE_EXTENSION: &'static str = "exe";
 }
 
 #[cfg(target_arch = "x86")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "x86";
 }
 
 #[cfg(target_arch = "x86_64")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "x86_64";
 }
 
 #[cfg(target_arch = "arm")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "arm";
 }
 
 #[cfg(target_arch = "aarch64")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "aarch64";
 }
 
 #[cfg(target_arch = "mips")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "mips";
 }
 
 #[cfg(target_arch = "mipsel")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "mipsel";
 }
 
 #[cfg(target_arch = "powerpc")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "powerpc";
 }
 
diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs
index a7d0a864a08..1ae59139bc4 100644
--- a/src/libstd/sys/unix/process2.rs
+++ b/src/libstd/sys/unix/process2.rs
@@ -274,7 +274,7 @@ impl Process {
                 // file descriptor. Otherwise, the first file descriptor opened
                 // up in the child would be numbered as one of the stdio file
                 // descriptors, which is likely to wreak havoc.
-                let setup = |&: src: Option<AnonPipe>, dst: c_int| {
+                let setup = |src: Option<AnonPipe>, dst: c_int| {
                     let src = match src {
                         None => {
                             let flags = if dst == libc::STDIN_FILENO {
diff --git a/src/libstd/sys/windows/process2.rs b/src/libstd/sys/windows/process2.rs
index d4c6e85489f..8a6a485cbbe 100644
--- a/src/libstd/sys/windows/process2.rs
+++ b/src/libstd/sys/windows/process2.rs
@@ -160,7 +160,7 @@ impl Process {
             // Similarly to unix, we don't actually leave holes for the stdio file
             // descriptors, but rather open up /dev/null equivalents. These
             // equivalents are drawn from libuv's windows process spawning.
-            let set_fd = |&: fd: &Option<AnonPipe>, slot: &mut HANDLE,
+            let set_fd = |fd: &Option<AnonPipe>, slot: &mut HANDLE,
                           is_stdin: bool| {
                 match *fd {
                     None => {
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index b3afc3fc4dd..59fe3658437 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -14,10 +14,11 @@ use std::collections::BTreeMap;
 use ast;
 use ast::{Ident, Name, TokenTree};
 use codemap::Span;
-use ext::base::{ExtCtxt, MacExpr, MacResult, MacItems};
+use ext::base::{ExtCtxt, MacEager, MacResult};
 use ext::build::AstBuilder;
 use parse::token;
 use ptr::P;
+use util::small_vector::SmallVector;
 
 thread_local! {
     static REGISTERED_DIAGNOSTICS: RefCell<BTreeMap<Name, Option<Name>>> = {
@@ -73,7 +74,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
             ));
         }
     });
-    MacExpr::new(quote_expr!(ecx, ()))
+    MacEager::expr(quote_expr!(ecx, ()))
 }
 
 pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
@@ -101,7 +102,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
     let sym = Ident::new(token::gensym(&(
         "__register_diagnostic_".to_string() + &token::get_ident(*code)
     )));
-    MacItems::new(vec![quote_item!(ecx, mod $sym {}).unwrap()].into_iter())
+    MacEager::items(SmallVector::many(vec![quote_item!(ecx, mod $sym {}).unwrap()]))
 }
 
 pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
@@ -126,7 +127,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
             (descriptions.len(), ecx.expr_vec(span, descriptions))
         });
 
-    MacItems::new(vec![quote_item!(ecx,
+    MacEager::items(SmallVector::many(vec![quote_item!(ecx,
         pub static $name: [(&'static str, &'static str); $count] = $expr;
-    ).unwrap()].into_iter())
+    ).unwrap()]))
 }
diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs
index 009bfef8623..ae48084947e 100644
--- a/src/libsyntax/ext/asm.rs
+++ b/src/libsyntax/ext/asm.rs
@@ -217,7 +217,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         },
     });
 
-    MacExpr::new(P(ast::Expr {
+    MacEager::expr(P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
         node: ast::ExprInlineAsm(ast::InlineAsm {
             asm: token::intern_and_get_ident(&asm),
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 2ef90f04f75..e5d1fe2388c 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -28,6 +28,7 @@ use fold::Folder;
 
 use std::collections::HashMap;
 use std::rc::Rc;
+use std::default::Default;
 
 pub trait ItemDecorator {
     fn expand(&self,
@@ -226,9 +227,17 @@ impl<F> IdentMacroExpander for F
     }
 }
 
+// Use a macro because forwarding to a simple function has type system issues
+macro_rules! make_stmt_default {
+    ($me:expr) => {
+        $me.make_expr().map(|e| {
+            P(codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID)))
+        })
+    }
+}
+
 /// The result of a macro expansion. The return values of the various
-/// methods are spliced into the AST at the callsite of the macro (or
-/// just into the compiler's internal macro table, for `make_def`).
+/// methods are spliced into the AST at the callsite of the macro.
 pub trait MacResult {
     /// Create an expression.
     fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
@@ -254,63 +263,76 @@ pub trait MacResult {
     /// By default this attempts to create an expression statement,
     /// returning None if that fails.
     fn make_stmt(self: Box<Self>) -> Option<P<ast::Stmt>> {
-        self.make_expr()
-            .map(|e| P(codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID))))
+        make_stmt_default!(self)
     }
 }
 
-/// A convenience type for macros that return a single expression.
-pub struct MacExpr {
-    e: P<ast::Expr>
-}
-impl MacExpr {
-    pub fn new(e: P<ast::Expr>) -> Box<MacResult+'static> {
-        box MacExpr { e: e } as Box<MacResult+'static>
-    }
-}
-impl MacResult for MacExpr {
-    fn make_expr(self: Box<MacExpr>) -> Option<P<ast::Expr>> {
-        Some(self.e)
-    }
-    fn make_pat(self: Box<MacExpr>) -> Option<P<ast::Pat>> {
-        match self.e.node {
-            ast::ExprLit(_) => Some(P(ast::Pat {
-                id: ast::DUMMY_NODE_ID,
-                span: self.e.span,
-                node: ast::PatLit(self.e)
-            })),
-            _ => None
+macro_rules! make_MacEager {
+    ( $( $fld:ident: $t:ty, )* ) => {
+        /// `MacResult` implementation for the common case where you've already
+        /// built each form of AST that you might return.
+        #[derive(Default)]
+        pub struct MacEager {
+            $(
+                pub $fld: Option<$t>,
+            )*
+        }
+
+        impl MacEager {
+            $(
+                pub fn $fld(v: $t) -> Box<MacResult> {
+                    box MacEager {
+                        $fld: Some(v),
+                        ..Default::default()
+                    } as Box<MacResult>
+                }
+            )*
         }
     }
 }
-/// A convenience type for macros that return a single pattern.
-pub struct MacPat {
-    p: P<ast::Pat>
+
+make_MacEager! {
+    expr: P<ast::Expr>,
+    pat: P<ast::Pat>,
+    items: SmallVector<P<ast::Item>>,
+    methods: SmallVector<P<ast::Method>>,
+    stmt: P<ast::Stmt>,
 }
-impl MacPat {
-    pub fn new(p: P<ast::Pat>) -> Box<MacResult+'static> {
-        box MacPat { p: p } as Box<MacResult+'static>
+
+impl MacResult for MacEager {
+    fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
+        self.expr
     }
-}
-impl MacResult for MacPat {
-    fn make_pat(self: Box<MacPat>) -> Option<P<ast::Pat>> {
-        Some(self.p)
+
+    fn make_items(self: Box<Self>) -> Option<SmallVector<P<ast::Item>>> {
+        self.items
     }
-}
-/// A type for macros that return multiple items.
-pub struct MacItems {
-    items: SmallVector<P<ast::Item>>
-}
 
-impl MacItems {
-    pub fn new<I: Iterator<Item=P<ast::Item>>>(it: I) -> Box<MacResult+'static> {
-        box MacItems { items: it.collect() } as Box<MacResult+'static>
+    fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::Method>>> {
+        self.methods
     }
-}
 
-impl MacResult for MacItems {
-    fn make_items(self: Box<MacItems>) -> Option<SmallVector<P<ast::Item>>> {
-        Some(self.items)
+    fn make_stmt(self: Box<Self>) -> Option<P<ast::Stmt>> {
+        match self.stmt {
+            None => make_stmt_default!(self),
+            s => s,
+        }
+    }
+
+    fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
+        if let Some(p) = self.pat {
+            return Some(p);
+        }
+        if let Some(e) = self.expr {
+            if let ast::ExprLit(_) = e.node {
+                return Some(P(ast::Pat {
+                    id: ast::DUMMY_NODE_ID,
+                    span: e.span,
+                    node: ast::PatLit(e),
+                }));
+            }
+        }
+        None
     }
 }
 
diff --git a/src/libsyntax/ext/cfg.rs b/src/libsyntax/ext/cfg.rs
index 7216602071b..6a2209bf0ae 100644
--- a/src/libsyntax/ext/cfg.rs
+++ b/src/libsyntax/ext/cfg.rs
@@ -35,5 +35,5 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
     }
 
     let matches_cfg = attr::cfg_matches(&cx.parse_sess.span_diagnostic, &cx.cfg, &*cfg);
-    MacExpr::new(cx.expr_bool(sp, matches_cfg))
+    MacEager::expr(cx.expr_bool(sp, matches_cfg))
 }
diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs
index 84f786e9780..754c73a9d78 100644
--- a/src/libsyntax/ext/concat.rs
+++ b/src/libsyntax/ext/concat.rs
@@ -60,7 +60,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
             }
         }
     }
-    base::MacExpr::new(cx.expr_str(
+    base::MacEager::expr(cx.expr_str(
             sp,
             token::intern_and_get_ident(&accumulator[..])))
 }
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 2303eb9645b..e350ce61017 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -67,5 +67,5 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
         ),
         span: sp,
     });
-    MacExpr::new(e)
+    MacEager::expr(e)
 }
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 93f8ee5042b..f72303985e7 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -59,7 +59,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
                                           &s[..]))))
       }
     };
-    MacExpr::new(e)
+    MacEager::expr(e)
 }
 
 pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
@@ -108,5 +108,5 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         }
         Ok(s) => cx.expr_str(sp, token::intern_and_get_ident(&s))
     };
-    MacExpr::new(e)
+    MacEager::expr(e)
 }
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 91262556abd..0eaca9af4f0 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -633,7 +633,7 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, sp: Span,
 
     match parse_args(ecx, sp, tts) {
         Some((efmt, args, order, names)) => {
-            MacExpr::new(expand_preparsed_format_args(ecx, sp, efmt,
+            MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt,
                                                       args, order, names))
         }
         None => DummyResult::expr(sp)
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 554529b5cb2..544fb15dcde 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -402,7 +402,7 @@ pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt,
                                 -> Box<base::MacResult+'cx> {
     let (cx_expr, expr) = expand_tts(cx, sp, tts);
     let expanded = expand_wrapper(cx, sp, cx_expr, expr);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
@@ -410,7 +410,7 @@ pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
                               tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
     let expanded = expand_parse_call(cx, sp, "parse_expr", Vec::new(), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt,
@@ -419,7 +419,7 @@ pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt,
                               -> Box<base::MacResult+'cx> {
     let expanded = expand_parse_call(cx, sp, "parse_item_with_outer_attributes",
                                     vec!(), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
@@ -427,7 +427,7 @@ pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
                              tts: &[ast::TokenTree])
                              -> Box<base::MacResult+'cx> {
     let expanded = expand_parse_call(cx, sp, "parse_pat", vec!(), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_arm(cx: &mut ExtCtxt,
@@ -435,7 +435,7 @@ pub fn expand_quote_arm(cx: &mut ExtCtxt,
                         tts: &[ast::TokenTree])
                         -> Box<base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_arm", vec!(), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_ty(cx: &mut ExtCtxt,
@@ -443,7 +443,7 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt,
                        tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_ty", vec!(), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_method(cx: &mut ExtCtxt,
@@ -452,7 +452,7 @@ pub fn expand_quote_method(cx: &mut ExtCtxt,
                            -> Box<base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_method_with_outer_attributes",
                                      vec!(), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_stmt(cx: &mut ExtCtxt,
@@ -462,7 +462,7 @@ pub fn expand_quote_stmt(cx: &mut ExtCtxt,
     let e_attrs = cx.expr_vec_ng(sp);
     let expanded = expand_parse_call(cx, sp, "parse_stmt",
                                     vec!(e_attrs), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 fn ids_ext(strs: Vec<String> ) -> Vec<ast::Ident> {
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index af43f5a1501..ba3743cdb33 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -35,7 +35,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     let topmost = cx.original_span_in_file();
     let loc = cx.codemap().lookup_char_pos(topmost.lo);
 
-    base::MacExpr::new(cx.expr_u32(topmost, loc.line as u32))
+    base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
 }
 
 /* column!(): expands to the current column number */
@@ -46,7 +46,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     let topmost = cx.original_span_in_file();
     let loc = cx.codemap().lookup_char_pos(topmost.lo);
 
-    base::MacExpr::new(cx.expr_u32(topmost, loc.col.to_usize() as u32))
+    base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
 }
 
 /// file!(): expands to the current filename */
@@ -59,13 +59,13 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     let topmost = cx.original_span_in_file();
     let loc = cx.codemap().lookup_char_pos(topmost.lo);
     let filename = token::intern_and_get_ident(&loc.file.name);
-    base::MacExpr::new(cx.expr_str(topmost, filename))
+    base::MacEager::expr(cx.expr_str(topmost, filename))
 }
 
 pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult+'static> {
     let s = pprust::tts_to_string(tts);
-    base::MacExpr::new(cx.expr_str(sp,
+    base::MacEager::expr(cx.expr_str(sp,
                                    token::intern_and_get_ident(&s[..])))
 }
 
@@ -77,7 +77,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    .map(|x| token::get_ident(*x).to_string())
                    .collect::<Vec<String>>()
                    .connect("::");
-    base::MacExpr::new(cx.expr_str(
+    base::MacEager::expr(cx.expr_str(
             sp,
             token::intern_and_get_ident(&string[..])))
 }
@@ -155,7 +155,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             let interned = token::intern_and_get_ident(&src[..]);
             cx.codemap().new_filemap(filename, src);
 
-            base::MacExpr::new(cx.expr_str(sp, interned))
+            base::MacEager::expr(cx.expr_str(sp, interned))
         }
         Err(_) => {
             cx.span_err(sp,
@@ -181,7 +181,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         }
         Ok(bytes) => {
             let bytes = bytes.iter().cloned().collect();
-            base::MacExpr::new(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
+            base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
         }
     }
 }
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 3a7fa54edbd..7acbd10ef03 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -27,7 +27,6 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(env)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(libc)]
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f171e8279f4..9de7b0ede78 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1163,7 +1163,6 @@ impl<'a> Parser<'a> {
         {
             self.bump();
             self.bump();
-            return;
         } else if
             self.eat(&token::Colon)
         {
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 823d2879236..756d67b5db1 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -59,7 +59,6 @@
 #![feature(staged_api)]
 #![feature(unicode)]
 #![feature(std_misc)]
-#![feature(env)]
 #![feature(os)]
 #![cfg_attr(windows, feature(libc))]
 
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 7c7f1fd478a..a144904903e 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -36,7 +36,6 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(env)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(old_path)]
diff --git a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
index bb57b4a98bb..f5a9063e1de 100644
--- a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
+++ b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
@@ -19,7 +19,8 @@ extern crate rustc;
 
 use syntax::ast;
 use syntax::codemap;
-use syntax::ext::base::{ExtCtxt, MacResult, MacItems};
+use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
+use syntax::util::small_vector::SmallVector;
 use rustc::plugin::Registry;
 
 #[plugin_registrar]
@@ -28,8 +29,8 @@ pub fn plugin_registrar(reg: &mut Registry) {
 }
 
 fn expand(cx: &mut ExtCtxt, _: codemap::Span, _: &[ast::TokenTree]) -> Box<MacResult+'static> {
-    MacItems::new(vec![
+    MacEager::items(SmallVector::many(vec![
         quote_item!(cx, struct Struct1;).unwrap(),
         quote_item!(cx, struct Struct2;).unwrap()
-    ].into_iter())
+    ]))
 }
diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs
index d545a42ae19..01bfbd3dbce 100644
--- a/src/test/auxiliary/macro_crate_test.rs
+++ b/src/test/auxiliary/macro_crate_test.rs
@@ -47,7 +47,7 @@ fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
     if !tts.is_empty() {
         cx.span_fatal(sp, "make_a_1 takes no arguments");
     }
-    MacExpr::new(quote_expr!(cx, 1))
+    MacEager::expr(quote_expr!(cx, 1))
 }
 
 // See Issue #15750
@@ -57,7 +57,7 @@ fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree])
     let mut parser = parse::new_parser_from_tts(cx.parse_sess(),
         cx.cfg(), tts.to_vec());
     let expr = parser.parse_expr();
-    MacExpr::new(quote_expr!(&mut *cx, $expr))
+    MacEager::expr(quote_expr!(&mut *cx, $expr))
 }
 
 fn expand_into_foo(cx: &mut ExtCtxt, sp: Span, attr: &MetaItem, it: P<Item>)
@@ -114,7 +114,7 @@ fn expand_forged_ident(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<Mac
         let mut parser = new_parser_from_tts(parse_sess, cfg, tt);
         parser.parse_expr()
     };
-    MacExpr::new(expr)
+    MacEager::expr(expr)
 }
 
 pub fn foo() {}
diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs
index d0ab944813a..1775bbf4af2 100644
--- a/src/test/auxiliary/plugin_args.rs
+++ b/src/test/auxiliary/plugin_args.rs
@@ -20,7 +20,7 @@ use std::borrow::ToOwned;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::ext::build::AstBuilder;
-use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacExpr, NormalTT};
+use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager, NormalTT};
 use syntax::parse::token;
 use syntax::print::pprust;
 use syntax::ptr::P;
@@ -38,7 +38,7 @@ impl TTMacroExpander for Expander {
         let args = self.args.iter().map(|i| pprust::meta_item_to_string(&*i))
             .collect::<Vec<_>>().connect(", ");
         let interned = token::intern_and_get_ident(&args[..]);
-        MacExpr::new(ecx.expr_str(sp, interned))
+        MacEager::expr(ecx.expr_str(sp, interned))
     }
 }
 
diff --git a/src/test/auxiliary/roman_numerals.rs b/src/test/auxiliary/roman_numerals.rs
index e05aa16ba5f..e5c42111105 100644
--- a/src/test/auxiliary/roman_numerals.rs
+++ b/src/test/auxiliary/roman_numerals.rs
@@ -19,7 +19,7 @@ extern crate rustc;
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::ast::{TokenTree, TtToken};
-use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
+use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax::ext::build::AstBuilder;  // trait for expr_usize
 use rustc::plugin::Registry;
 
@@ -61,7 +61,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         }
     }
 
-    MacExpr::new(cx.expr_usize(sp, total))
+    MacEager::expr(cx.expr_usize(sp, total))
 }
 
 #[plugin_registrar]
diff --git a/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs b/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
index 7a24dd76f32..07f3b863af8 100644
--- a/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
+++ b/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
@@ -30,5 +30,5 @@ pub fn plugin_registrar(reg: &mut Registry) {
 fn expand_foo(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
               -> Box<MacResult+'static> {
     let answer = other::the_answer();
-    MacExpr::new(quote_expr!(cx, $answer))
+    MacEager::expr(quote_expr!(cx, $answer))
 }
diff --git a/src/test/parse-fail/obsolete-closure-kind.rs b/src/test/parse-fail/obsolete-closure-kind.rs
new file mode 100644
index 00000000000..89134e806a7
--- /dev/null
+++ b/src/test/parse-fail/obsolete-closure-kind.rs
@@ -0,0 +1,18 @@
+// 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.
+
+// Test that we generate obsolete syntax errors around usages of closure kinds: `|:|`, `|&:|` and
+// `|&mut:|`.
+
+fn main() {
+    let a = |:| {};  //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:`
+    let a = |&:| {};  //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:`
+    let a = |&mut:| {};  //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:`
+}