about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiletest/runtest.rs5
-rw-r--r--src/doc/complement-design-faq.md2
-rw-r--r--src/doc/trpl/guessing-game.md8
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/libcollections/lib.rs1
-rw-r--r--src/libcollections/vec.rs49
-rw-r--r--src/libcore/fmt/mod.rs43
-rw-r--r--src/libcore/slice.rs30
-rw-r--r--src/liblibc/lib.rs1
-rw-r--r--src/librustc/diagnostics.rs1
-rw-r--r--src/librustc/metadata/encoder.rs6
-rw-r--r--src/librustc/middle/check_static_recursion.rs174
-rw-r--r--src/librustc/util/common.rs45
-rw-r--r--src/librustc_driver/driver.rs4
-rw-r--r--src/librustc_driver/lib.rs20
-rw-r--r--src/librustc_resolve/lib.rs5
-rw-r--r--src/librustc_trans/back/link.rs266
-rw-r--r--src/librustc_trans/back/linker.rs16
-rw-r--r--src/librustc_trans/back/lto.rs39
-rw-r--r--src/librustc_trans/back/write.rs95
-rw-r--r--src/librustc_typeck/diagnostics.rs69
-rw-r--r--src/libstd/io/buffered.rs21
-rw-r--r--src/libstd/io/mod.rs12
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libsyntax/visit.rs7
-rw-r--r--src/test/auxiliary/issue-14344-1.rs15
-rw-r--r--src/test/auxiliary/issue-14344-2.rs13
-rw-r--r--src/test/auxiliary/issue-25185-1.rs18
-rw-r--r--src/test/auxiliary/issue-25185-2.rs13
-rw-r--r--src/test/compile-fail/issue-23302.rs24
-rw-r--r--src/test/run-make/execution-engine/Makefile6
-rw-r--r--src/test/run-make/extern-fn-reachable/Makefile4
-rw-r--r--src/test/run-make/extra-filename-with-temp-outputs/Makefile2
-rw-r--r--src/test/run-pass/issue-14344.rs20
-rw-r--r--src/test/run-pass/issue-25185.rs21
35 files changed, 698 insertions, 359 deletions
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 39d99af8d6a..93054f39790 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -1702,8 +1702,11 @@ fn run_codegen_test(config: &Config, props: &TestProps, testfile: &Path) {
 }
 
 fn charset() -> &'static str {
-    if cfg!(any(target_os = "bitrig", target_os = "freebsd")) {
+    // FreeBSD 10.1 defaults to GDB 6.1.1 which doesn't support "auto" charset
+    if cfg!(target_os = "bitrig") {
         "auto"
+    } else if cfg!(target_os = "freebsd") {
+        "ISO-8859-1"
     } else {
         "UTF-8"
     }
diff --git a/src/doc/complement-design-faq.md b/src/doc/complement-design-faq.md
index e887ed0cc52..5e99876f5da 100644
--- a/src/doc/complement-design-faq.md
+++ b/src/doc/complement-design-faq.md
@@ -99,7 +99,7 @@ Second, it makes cost explicit. In general, the only safe way to have a
 non-exhaustive match would be to panic the thread if nothing is matched, though
 it could fall through if the type of the `match` expression is `()`. This sort
 of hidden cost and special casing is against the language's philosophy. It's
-easy to ignore certain cases by using the `_` wildcard:
+easy to ignore all unspecified cases by using the `_` wildcard:
 
 ```rust,ignore
 match val.do_something() {
diff --git a/src/doc/trpl/guessing-game.md b/src/doc/trpl/guessing-game.md
index a599b8a855e..1784c253f7f 100644
--- a/src/doc/trpl/guessing-game.md
+++ b/src/doc/trpl/guessing-game.md
@@ -360,10 +360,12 @@ rand="0.3.0"
 The `[dependencies]` section of `Cargo.toml` is like the `[package]` section:
 everything that follows it is part of it, until the next section starts.
 Cargo uses the dependencies section to know what dependencies on external
-crates you have, and what versions you require. In this case, we’ve used version `0.3.0`.
+crates you have, and what versions you require. In this case, we’ve specified version `0.3.0`,
+which Cargo understands to be any release that’s compatible with this specific version.
 Cargo understands [Semantic Versioning][semver], which is a standard for writing version
-numbers. If we wanted to use the latest version we could use `*` or we could use a range
-of versions. [Cargo’s documentation][cargodoc] contains more details.
+numbers. If we wanted to use only `0.3.0` exactly, we could use `=0.3.0`. If we
+wanted to use the latest version we could use `*`; We could use a range of
+versions. [Cargo’s documentation][cargodoc] contains more details.
 
 [semver]: http://semver.org
 [cargodoc]: http://doc.crates.io/crates-io.html
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 7dcf7a76da0..905012bbb64 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -148,4 +148,5 @@ pub fn oom() -> ! {
 //                optimize it out).
 #[doc(hidden)]
 #[unstable(feature = "issue_14344_fixme")]
+#[cfg(stage0)]
 pub fn fixme_14344_be_sure_to_link_to_collections() {}
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 42adbe10e50..3c90a2c54e1 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -138,6 +138,7 @@ pub mod btree_set {
 // FIXME(#14344) this shouldn't be necessary
 #[doc(hidden)]
 #[unstable(feature = "issue_14344_fixme")]
+#[cfg(stage0)]
 pub fn fixme_14344_be_sure_to_link_to_collections() {}
 
 #[cfg(not(test))]
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index c032471b6b6..3848263c530 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -67,7 +67,7 @@ use core::cmp::Ordering;
 use core::fmt;
 use core::hash::{self, Hash};
 use core::intrinsics::{arith_offset, assume};
-use core::iter::{repeat, FromIterator};
+use core::iter::FromIterator;
 use core::marker::PhantomData;
 use core::mem;
 use core::ops::{Index, IndexMut, Deref};
@@ -1106,12 +1106,35 @@ impl<T: Clone> Vec<T> {
         let len = self.len();
 
         if new_len > len {
-            self.extend(repeat(value).take(new_len - len));
+            self.extend_with_element(new_len - len, value);
         } else {
             self.truncate(new_len);
         }
     }
 
+    /// Extend the vector by `n` additional clones of `value`.
+    fn extend_with_element(&mut self, n: usize, value: T) {
+        self.reserve(n);
+
+        unsafe {
+            let len = self.len();
+            let mut ptr = self.as_mut_ptr().offset(len as isize);
+            // Write all elements except the last one
+            for i in 1..n {
+                ptr::write(ptr, value.clone());
+                ptr = ptr.offset(1);
+                // Increment the length in every step in case clone() panics
+                self.set_len(len + i);
+            }
+
+            if n > 0 {
+                // We can write the last element directly without cloning needlessly
+                ptr::write(ptr, value);
+                self.set_len(len + n);
+            }
+        }
+    }
+
     /// Appends all elements in a slice to the `Vec`.
     ///
     /// Iterates over the slice `other`, clones each element, and then appends
@@ -1294,25 +1317,9 @@ unsafe fn dealloc<T>(ptr: *mut T, len: usize) {
 #[doc(hidden)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
-    unsafe {
-        let mut v = Vec::with_capacity(n);
-        let mut ptr = v.as_mut_ptr();
-
-        // Write all elements except the last one
-        for i in 1..n {
-            ptr::write(ptr, Clone::clone(&elem));
-            ptr = ptr.offset(1);
-            v.set_len(i); // Increment the length in every step in case Clone::clone() panics
-        }
-
-        if n > 0 {
-            // We can write the last element directly without cloning needlessly
-            ptr::write(ptr, elem);
-            v.set_len(n);
-        }
-
-        v
-    }
+    let mut v = Vec::with_capacity(n);
+    v.extend_with_element(n, elem);
+    v
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 0bb519ec095..47030bf0fb3 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -273,6 +273,8 @@ impl<'a> Display for Arguments<'a> {
 ///
 /// Generally speaking, you should just `derive` a `Debug` implementation.
 ///
+/// When used with the alternate format specifier `#?`, the output is pretty-printed.
+///
 /// For more information on formatters, see [the module-level documentation][module].
 ///
 /// [module]: ../index.html
@@ -314,6 +316,12 @@ impl<'a> Display for Arguments<'a> {
 /// println!("The origin is: {:?}", origin);
 /// ```
 ///
+/// This outputs:
+///
+/// ```text
+/// The origin is: Point { x: 0, y: 0 }
+/// ```
+///
 /// There are a number of `debug_*` methods on `Formatter` to help you with manual
 /// implementations, such as [`debug_struct`][debug_struct].
 ///
@@ -321,6 +329,29 @@ impl<'a> Display for Arguments<'a> {
 /// on `Formatter` support pretty printing using the alternate flag: `{:#?}`.
 ///
 /// [debug_struct]: ../std/fmt/struct.Formatter.html#method.debug_struct
+///
+/// Pretty printing with `#?`:
+///
+/// ```
+/// #[derive(Debug)]
+/// struct Point {
+///     x: i32,
+///     y: i32,
+/// }
+///
+/// let origin = Point { x: 0, y: 0 };
+///
+/// println!("The origin is: {:#?}", origin);
+/// ```
+///
+/// This outputs:
+///
+/// ```text
+/// The origin is: Point {
+///     x: 0,
+///     y: 0
+/// }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \
                             defined in your crate, add `#[derive(Debug)]` or \
@@ -379,6 +410,8 @@ pub trait Display {
 ///
 /// The `Octal` trait should format its output as a number in base-8.
 ///
+/// The alternate flag, `#`, adds a `0o` in front of the output.
+///
 /// For more information on formatters, see [the module-level documentation][module].
 ///
 /// [module]: ../index.html
@@ -391,6 +424,7 @@ pub trait Display {
 /// let x = 42; // 42 is '52' in octal
 ///
 /// assert_eq!(format!("{:o}", x), "52");
+/// assert_eq!(format!("{:#o}", x), "0o52");
 /// ```
 ///
 /// Implementing `Octal` on a type:
@@ -423,6 +457,8 @@ pub trait Octal {
 ///
 /// The `Binary` trait should format its output as a number in binary.
 ///
+/// The alternate flag, `#`, adds a `0b` in front of the output.
+///
 /// For more information on formatters, see [the module-level documentation][module].
 ///
 /// [module]: ../index.html
@@ -435,6 +471,7 @@ pub trait Octal {
 /// let x = 42; // 42 is '101010' in binary
 ///
 /// assert_eq!(format!("{:b}", x), "101010");
+/// assert_eq!(format!("{:#b}", x), "0b101010");
 /// ```
 ///
 /// Implementing `Binary` on a type:
@@ -468,6 +505,8 @@ pub trait Binary {
 /// The `LowerHex` trait should format its output as a number in hexidecimal, with `a` through `f`
 /// in lower case.
 ///
+/// The alternate flag, `#`, adds a `0x` in front of the output.
+///
 /// For more information on formatters, see [the module-level documentation][module].
 ///
 /// [module]: ../index.html
@@ -480,6 +519,7 @@ pub trait Binary {
 /// let x = 42; // 42 is '2a' in hex
 ///
 /// assert_eq!(format!("{:x}", x), "2a");
+/// assert_eq!(format!("{:#x}", x), "0x2a");
 /// ```
 ///
 /// Implementing `LowerHex` on a type:
@@ -513,6 +553,8 @@ pub trait LowerHex {
 /// The `UpperHex` trait should format its output as a number in hexidecimal, with `A` through `F`
 /// in upper case.
 ///
+/// The alternate flag, `#`, adds a `0x` in front of the output.
+///
 /// For more information on formatters, see [the module-level documentation][module].
 ///
 /// [module]: ../index.html
@@ -525,6 +567,7 @@ pub trait LowerHex {
 /// let x = 42; // 42 is '2A' in hex
 ///
 /// assert_eq!(format!("{:X}", x), "2A");
+/// assert_eq!(format!("{:#X}", x), "0x2A");
 /// ```
 ///
 /// Implementing `UpperHex` on a type:
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index a8c995f37cc..00e7ff3c4df 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -1368,10 +1368,14 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
 ///
 /// The `len` argument is the number of **elements**, not the number of bytes.
 ///
+/// # Unsafety
+///
 /// This function is unsafe as there is no guarantee that the given pointer is
 /// valid for `len` elements, nor whether the lifetime inferred is a suitable
 /// lifetime for the returned slice.
 ///
+/// `p` must be non-null, even for zero-length slices.
+///
 /// # Caveat
 ///
 /// The lifetime for the returned slice is inferred from its usage. To
@@ -1459,12 +1463,30 @@ pub mod bytes {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
     fn eq(&self, other: &[B]) -> bool {
-        self.len() == other.len() &&
-            order::eq(self.iter(), other.iter())
+        if self.len() != other.len() {
+            return false;
+        }
+
+        for i in 0..self.len() {
+            if !self[i].eq(&other[i]) {
+                return false;
+            }
+        }
+
+        true
     }
     fn ne(&self, other: &[B]) -> bool {
-        self.len() != other.len() ||
-            order::ne(self.iter(), other.iter())
+        if self.len() != other.len() {
+            return true;
+        }
+
+        for i in 0..self.len() {
+            if self[i].ne(&other[i]) {
+                return true;
+            }
+        }
+
+        false
     }
 }
 
diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs
index 2c5ebc25f6b..102894bec13 100644
--- a/src/liblibc/lib.rs
+++ b/src/liblibc/lib.rs
@@ -6431,6 +6431,7 @@ pub mod funcs {
 }
 
 #[doc(hidden)]
+#[cfg(stage0)]
 pub fn issue_14344_workaround() {} // FIXME #14344 force linkage to happen correctly
 
 #[test] fn work_on_windows() { } // FIXME #10872 needed for a happy windows
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index c329f2fb012..3dbc80d352d 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -1211,7 +1211,6 @@ register_diagnostics! {
     E0138,
     E0139,
     E0264, // unknown external lang item
-    E0266, // expected item
     E0269, // not all control paths return a value
     E0270, // computation may converge in a function marked as diverging
     E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index b677e7b8570..a9e9f17bdce 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -2136,11 +2136,7 @@ fn encode_metadata_inner(wr: &mut Cursor<Vec<u8>>,
     let mut rbml_w = Encoder::new(wr);
 
     encode_crate_name(&mut rbml_w, &ecx.link_meta.crate_name);
-    encode_crate_triple(&mut rbml_w,
-                        &tcx.sess
-                           .opts
-                           .target_triple
-                           );
+    encode_crate_triple(&mut rbml_w, &tcx.sess.opts.target_triple);
     encode_hash(&mut rbml_w, &ecx.link_meta.crate_hash);
     encode_dylib_dependency_formats(&mut rbml_w, &ecx);
 
diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs
index 41beabc9588..312a4708e8d 100644
--- a/src/librustc/middle/check_static_recursion.rs
+++ b/src/librustc/middle/check_static_recursion.rs
@@ -13,68 +13,90 @@
 
 use ast_map;
 use session::Session;
-use middle::def::{DefStatic, DefConst, DefAssociatedConst, DefMap};
+use middle::def::{DefStatic, DefConst, DefAssociatedConst, DefVariant, DefMap};
+use util::nodemap::NodeMap;
 
 use syntax::{ast, ast_util};
 use syntax::codemap::Span;
 use syntax::visit::Visitor;
 use syntax::visit;
 
+use std::cell::RefCell;
+
 struct CheckCrateVisitor<'a, 'ast: 'a> {
     sess: &'a Session,
     def_map: &'a DefMap,
-    ast_map: &'a ast_map::Map<'ast>
+    ast_map: &'a ast_map::Map<'ast>,
+    // `discriminant_map` is a cache that associates the `NodeId`s of local
+    // variant definitions with the discriminant expression that applies to
+    // each one. If the variant uses the default values (starting from `0`),
+    // then `None` is stored.
+    discriminant_map: RefCell<NodeMap<Option<&'ast ast::Expr>>>,
 }
 
-impl<'v, 'a, 'ast> Visitor<'v> for CheckCrateVisitor<'a, 'ast> {
-    fn visit_item(&mut self, it: &ast::Item) {
+impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
+    fn visit_item(&mut self, it: &'ast ast::Item) {
         match it.node {
-            ast::ItemStatic(_, _, ref expr) |
-            ast::ItemConst(_, ref expr) => {
+            ast::ItemStatic(..) |
+            ast::ItemConst(..) => {
                 let mut recursion_visitor =
                     CheckItemRecursionVisitor::new(self, &it.span);
                 recursion_visitor.visit_item(it);
-                visit::walk_expr(self, &*expr)
             },
-            _ => visit::walk_item(self, it)
+            ast::ItemEnum(ref enum_def, ref generics) => {
+                // We could process the whole enum, but handling the variants
+                // with discriminant expressions one by one gives more specific,
+                // less redundant output.
+                for variant in &enum_def.variants {
+                    if let Some(_) = variant.node.disr_expr {
+                        let mut recursion_visitor =
+                            CheckItemRecursionVisitor::new(self, &variant.span);
+                        recursion_visitor.populate_enum_discriminants(enum_def);
+                        recursion_visitor.visit_variant(variant, generics);
+                    }
+                }
+            }
+            _ => {}
         }
+        visit::walk_item(self, it)
     }
 
-    fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
+    fn visit_trait_item(&mut self, ti: &'ast ast::TraitItem) {
         match ti.node {
             ast::ConstTraitItem(_, ref default) => {
-                if let Some(ref expr) = *default {
+                if let Some(_) = *default {
                     let mut recursion_visitor =
                         CheckItemRecursionVisitor::new(self, &ti.span);
                     recursion_visitor.visit_trait_item(ti);
-                    visit::walk_expr(self, &*expr)
                 }
             }
-            _ => visit::walk_trait_item(self, ti)
+            _ => {}
         }
+        visit::walk_trait_item(self, ti)
     }
 
-    fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
+    fn visit_impl_item(&mut self, ii: &'ast ast::ImplItem) {
         match ii.node {
-            ast::ConstImplItem(_, ref expr) => {
+            ast::ConstImplItem(..) => {
                 let mut recursion_visitor =
                     CheckItemRecursionVisitor::new(self, &ii.span);
                 recursion_visitor.visit_impl_item(ii);
-                visit::walk_expr(self, &*expr)
             }
-            _ => visit::walk_impl_item(self, ii)
+            _ => {}
         }
+        visit::walk_impl_item(self, ii)
     }
 }
 
 pub fn check_crate<'ast>(sess: &Session,
-                         krate: &ast::Crate,
+                         krate: &'ast ast::Crate,
                          def_map: &DefMap,
                          ast_map: &ast_map::Map<'ast>) {
     let mut visitor = CheckCrateVisitor {
         sess: sess,
         def_map: def_map,
-        ast_map: ast_map
+        ast_map: ast_map,
+        discriminant_map: RefCell::new(NodeMap()),
     };
     visit::walk_crate(&mut visitor, krate);
     sess.abort_if_errors();
@@ -85,23 +107,25 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
     sess: &'a Session,
     ast_map: &'a ast_map::Map<'ast>,
     def_map: &'a DefMap,
-    idstack: Vec<ast::NodeId>
+    discriminant_map: &'a RefCell<NodeMap<Option<&'ast ast::Expr>>>,
+    idstack: Vec<ast::NodeId>,
 }
 
 impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
-    fn new(v: &CheckCrateVisitor<'a, 'ast>, span: &'a Span)
+    fn new(v: &'a CheckCrateVisitor<'a, 'ast>, span: &'a Span)
            -> CheckItemRecursionVisitor<'a, 'ast> {
         CheckItemRecursionVisitor {
             root_span: span,
             sess: v.sess,
             ast_map: v.ast_map,
             def_map: v.def_map,
-            idstack: Vec::new()
+            discriminant_map: &v.discriminant_map,
+            idstack: Vec::new(),
         }
     }
     fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F)
           where F: Fn(&mut Self) {
-        if self.idstack.iter().any(|x| x == &(id)) {
+        if self.idstack.iter().any(|x| *x == id) {
             span_err!(self.sess, *self.root_span, E0265, "recursive constant");
             return;
         }
@@ -109,29 +133,94 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
         f(self);
         self.idstack.pop();
     }
+    // If a variant has an expression specifying its discriminant, then it needs
+    // to be checked just like a static or constant. However, if there are more
+    // variants with no explicitly specified discriminant, those variants will
+    // increment the same expression to get their values.
+    //
+    // So for every variant, we need to track whether there is an expression
+    // somewhere in the enum definition that controls its discriminant. We do
+    // this by starting from the end and searching backward.
+    fn populate_enum_discriminants(&self, enum_definition: &'ast ast::EnumDef) {
+        // Get the map, and return if we already processed this enum or if it
+        // has no variants.
+        let mut discriminant_map = self.discriminant_map.borrow_mut();
+        match enum_definition.variants.first() {
+            None => { return; }
+            Some(variant) if discriminant_map.contains_key(&variant.node.id) => {
+                return;
+            }
+            _ => {}
+        }
+
+        // Go through all the variants.
+        let mut variant_stack: Vec<ast::NodeId> = Vec::new();
+        for variant in enum_definition.variants.iter().rev() {
+            variant_stack.push(variant.node.id);
+            // When we find an expression, every variant currently on the stack
+            // is affected by that expression.
+            if let Some(ref expr) = variant.node.disr_expr {
+                for id in &variant_stack {
+                    discriminant_map.insert(*id, Some(expr));
+                }
+                variant_stack.clear()
+            }
+        }
+        // If we are at the top, that always starts at 0, so any variant on the
+        // stack has a default value and does not need to be checked.
+        for id in &variant_stack {
+            discriminant_map.insert(*id, None);
+        }
+    }
 }
 
-impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
-    fn visit_item(&mut self, it: &ast::Item) {
+impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
+    fn visit_item(&mut self, it: &'ast ast::Item) {
         self.with_item_id_pushed(it.id, |v| visit::walk_item(v, it));
     }
 
-    fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
+    fn visit_enum_def(&mut self, enum_definition: &'ast ast::EnumDef,
+                      generics: &'ast ast::Generics) {
+        self.populate_enum_discriminants(enum_definition);
+        visit::walk_enum_def(self, enum_definition, generics);
+    }
+
+    fn visit_variant(&mut self, variant: &'ast ast::Variant,
+                     _: &'ast ast::Generics) {
+        let variant_id = variant.node.id;
+        let maybe_expr;
+        if let Some(get_expr) = self.discriminant_map.borrow().get(&variant_id) {
+            // This is necessary because we need to let the `discriminant_map`
+            // borrow fall out of scope, so that we can reborrow farther down.
+            maybe_expr = (*get_expr).clone();
+        } else {
+            self.sess.span_bug(variant.span,
+                               "`check_static_recursion` attempted to visit \
+                                variant with unknown discriminant")
+        }
+        // If `maybe_expr` is `None`, that's because no discriminant is
+        // specified that affects this variant. Thus, no risk of recursion.
+        if let Some(expr) = maybe_expr {
+            self.with_item_id_pushed(expr.id, |v| visit::walk_expr(v, expr));
+        }
+    }
+
+    fn visit_trait_item(&mut self, ti: &'ast ast::TraitItem) {
         self.with_item_id_pushed(ti.id, |v| visit::walk_trait_item(v, ti));
     }
 
-    fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
+    fn visit_impl_item(&mut self, ii: &'ast ast::ImplItem) {
         self.with_item_id_pushed(ii.id, |v| visit::walk_impl_item(v, ii));
     }
 
-    fn visit_expr(&mut self, e: &ast::Expr) {
+    fn visit_expr(&mut self, e: &'ast ast::Expr) {
         match e.node {
             ast::ExprPath(..) => {
                 match self.def_map.borrow().get(&e.id).map(|d| d.base_def) {
                     Some(DefStatic(def_id, _)) |
                     Some(DefAssociatedConst(def_id, _)) |
-                    Some(DefConst(def_id)) if
-                            ast_util::is_local(def_id) => {
+                    Some(DefConst(def_id))
+                           if ast_util::is_local(def_id) => {
                         match self.ast_map.get(def_id.node) {
                           ast_map::NodeItem(item) =>
                             self.visit_item(item),
@@ -141,11 +230,28 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
                             self.visit_impl_item(item),
                           ast_map::NodeForeignItem(_) => {},
                           _ => {
-                            span_err!(self.sess, e.span, E0266,
-                              "expected item, found {}",
-                                      self.ast_map.node_to_string(def_id.node));
-                            return;
-                          },
+                              self.sess.span_bug(
+                                  e.span,
+                                  &format!("expected item, found {}",
+                                           self.ast_map.node_to_string(def_id.node)));
+                          }
+                        }
+                    }
+                    // For variants, we only want to check expressions that
+                    // affect the specific variant used, but we need to check
+                    // the whole enum definition to see what expression that
+                    // might be (if any).
+                    Some(DefVariant(enum_id, variant_id, false))
+                           if ast_util::is_local(enum_id) => {
+                        if let ast::ItemEnum(ref enum_def, ref generics) =
+                               self.ast_map.expect_item(enum_id.local_id()).node {
+                            self.populate_enum_discriminants(enum_def);
+                            let variant = self.ast_map.expect_variant(variant_id.local_id());
+                            self.visit_variant(variant, generics);
+                        } else {
+                            self.sess.span_bug(e.span,
+                                "`check_static_recursion` found \
+                                 non-enum in DefVariant");
                         }
                     }
                     _ => ()
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 162bf6ed9a9..77575cd6b24 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -76,12 +76,14 @@ pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
 }
 
 // Memory reporting
+#[cfg(unix)]
 fn get_resident() -> Option<usize> {
-    if cfg!(unix) {
-        get_proc_self_statm_field(1)
-    } else {
-        None
-    }
+    get_proc_self_statm_field(1)
+}
+
+#[cfg(windows)]
+fn get_resident() -> Option<usize> {
+    get_working_set_size()
 }
 
 // Like std::macros::try!, but for Option<>.
@@ -89,6 +91,39 @@ macro_rules! option_try(
     ($e:expr) => (match $e { Some(e) => e, None => return None })
 );
 
+#[cfg(windows)]
+fn get_working_set_size() -> Option<usize> {
+    use libc::{BOOL, DWORD, HANDLE, SIZE_T, GetCurrentProcess};
+    use std::mem;
+    #[repr(C)] #[allow(non_snake_case)]
+    struct PROCESS_MEMORY_COUNTERS {
+        cb: DWORD,
+        PageFaultCount: DWORD,
+        PeakWorkingSetSize: SIZE_T,
+        WorkingSetSize: SIZE_T,
+        QuotaPeakPagedPoolUsage: SIZE_T,
+        QuotaPagedPoolUsage: SIZE_T,
+        QuotaPeakNonPagedPoolUsage: SIZE_T,
+        QuotaNonPagedPoolUsage: SIZE_T,
+        PagefileUsage: SIZE_T,
+        PeakPagefileUsage: SIZE_T,
+    }
+    type PPROCESS_MEMORY_COUNTERS = *mut PROCESS_MEMORY_COUNTERS;
+    #[link(name = "psapi")]
+    extern "system" {
+        fn GetProcessMemoryInfo(Process: HANDLE,
+                                ppsmemCounters: PPROCESS_MEMORY_COUNTERS,
+                                cb: DWORD) -> BOOL;
+    }
+    let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { mem::zeroed() };
+    pmc.cb = mem::size_of_val(&pmc) as DWORD;
+    match unsafe { GetProcessMemoryInfo(GetCurrentProcess(), &mut pmc, pmc.cb) } {
+        0 => None,
+        _ => Some(pmc.WorkingSetSize as usize),
+    }
+}
+
+#[cfg_attr(windows, allow(dead_code))]
 fn get_proc_self_statm_field(field: usize) -> Option<usize> {
     use std::fs::File;
     use std::io::Read;
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index ae6136a049a..9541076df82 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -804,8 +804,8 @@ fn write_out_deps(sess: &Session,
         match *output_type {
             config::OutputTypeExe => {
                 for output in sess.crate_types.borrow().iter() {
-                    let p = link::filename_for_input(sess, *output,
-                                                     id, &file);
+                    let p = link::filename_for_input(sess, *output, id,
+                                                     outputs);
                     out_filenames.push(p);
                 }
             }
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 36438ccc784..7ccada1079f 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -452,10 +452,8 @@ impl RustcDefaultCalls {
                     let metadata = driver::collect_crate_metadata(sess, attrs);
                     *sess.crate_metadata.borrow_mut() = metadata;
                     for &style in &crate_types {
-                        let fname = link::filename_for_input(sess,
-                                                             style,
-                                                             &id,
-                                                             &t_outputs.with_extension(""));
+                        let fname = link::filename_for_input(sess, style, &id,
+                                                             &t_outputs);
                         println!("{}", fname.file_name().unwrap()
                                             .to_string_lossy());
                     }
@@ -481,17 +479,6 @@ pub fn commit_date_str() -> Option<&'static str> {
     option_env!("CFG_VER_DATE")
 }
 
-/// Returns a stage string, such as "stage0".
-pub fn stage_str() -> Option<&'static str> {
-    if cfg!(stage0) {
-        Some("stage0")
-    } else if cfg!(stage1) {
-        Some("stage1")
-    } else {
-        None
-    }
-}
-
 /// Prints version information
 pub fn version(binary: &str, matches: &getopts::Matches) {
     let verbose = matches.opt_present("verbose");
@@ -504,9 +491,6 @@ pub fn version(binary: &str, matches: &getopts::Matches) {
         println!("commit-date: {}", unw(commit_date_str()));
         println!("host: {}", config::host_triple());
         println!("release: {}", unw(release_str()));
-        if let Some(stage) = stage_str() {
-            println!("stage: {}", stage);
-        }
     }
 }
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 5d10b0d9a57..0ec3979ccfb 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1844,11 +1844,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         visit::walk_ty_param_bounds_helper(this, bounds);
 
                         for trait_item in trait_items {
-                            // Create a new rib for the trait_item-specific type
-                            // parameters.
-                            //
-                            // FIXME #4951: Do we need a node ID here?
-
                             match trait_item.node {
                                 ast::ConstTraitItem(_, ref default) => {
                                     // Only impose the restrictions of
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index e0495226d90..21bc61593c9 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -417,11 +417,10 @@ pub fn link_binary(sess: &Session,
 
     // Remove the temporary object file and metadata if we aren't saving temps
     if !sess.opts.cg.save_temps {
-        let obj_filename = outputs.temp_path(OutputTypeObject);
-        if !sess.opts.output_types.contains(&OutputTypeObject) {
-            remove(sess, &obj_filename);
+        for obj in object_filenames(sess, outputs) {
+            remove(sess, &obj);
         }
-        remove(sess, &obj_filename.with_extension("metadata.o"));
+        remove(sess, &outputs.with_extension("metadata.o"));
     }
 
     out_filenames
@@ -465,26 +464,25 @@ fn is_writeable(p: &Path) -> bool {
 
 pub fn filename_for_input(sess: &Session,
                           crate_type: config::CrateType,
-                          name: &str,
-                          out_filename: &Path) -> PathBuf {
-    let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
+                          crate_name: &str,
+                          outputs: &OutputFilenames) -> PathBuf {
+    let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename);
     match crate_type {
         config::CrateTypeRlib => {
-            out_filename.with_file_name(&format!("lib{}.rlib", libname))
+            outputs.out_directory.join(&format!("lib{}.rlib", libname))
         }
         config::CrateTypeDylib => {
             let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
                                     &sess.target.target.options.dll_suffix);
-            out_filename.with_file_name(&format!("{}{}{}",
-                                                  prefix,
-                                                 libname,
-                                                 suffix))
+            outputs.out_directory.join(&format!("{}{}{}", prefix, libname,
+                                                suffix))
         }
         config::CrateTypeStaticlib => {
-            out_filename.with_file_name(&format!("lib{}.a", libname))
+            outputs.out_directory.join(&format!("lib{}.a", libname))
         }
         config::CrateTypeExecutable => {
             let suffix = &sess.target.target.options.exe_suffix;
+            let out_filename = outputs.path(OutputTypeExe);
             if suffix.is_empty() {
                 out_filename.to_path_buf()
             } else {
@@ -499,50 +497,47 @@ fn link_binary_output(sess: &Session,
                       crate_type: config::CrateType,
                       outputs: &OutputFilenames,
                       crate_name: &str) -> PathBuf {
-    let obj_filename = outputs.temp_path(OutputTypeObject);
+    let objects = object_filenames(sess, outputs);
     let out_filename = match outputs.single_output_file {
         Some(ref file) => file.clone(),
-        None => {
-            let out_filename = outputs.path(OutputTypeExe);
-            filename_for_input(sess, crate_type, crate_name, &out_filename)
-        }
+        None => filename_for_input(sess, crate_type, crate_name, outputs),
     };
 
-    // Make sure the output and obj_filename are both writeable.
-    // Mac, FreeBSD, and Windows system linkers check this already --
-    // however, the Linux linker will happily overwrite a read-only file.
-    // We should be consistent.
-    let obj_is_writeable = is_writeable(&obj_filename);
-    let out_is_writeable = is_writeable(&out_filename);
-    if !out_is_writeable {
-        sess.fatal(&format!("output file {} is not writeable -- check its \
-                            permissions.",
-                           out_filename.display()));
-    }
-    else if !obj_is_writeable {
-        sess.fatal(&format!("object file {} is not writeable -- check its \
-                            permissions.",
-                           obj_filename.display()));
+    // Make sure files are writeable.  Mac, FreeBSD, and Windows system linkers
+    // check this already -- however, the Linux linker will happily overwrite a
+    // read-only file.  We should be consistent.
+    for file in objects.iter().chain(Some(&out_filename)) {
+        if !is_writeable(file) {
+            sess.fatal(&format!("output file {} is not writeable -- check its \
+                                permissions", file.display()));
+        }
     }
 
     match crate_type {
         config::CrateTypeRlib => {
-            link_rlib(sess, Some(trans), &obj_filename, &out_filename).build();
+            link_rlib(sess, Some(trans), &objects, &out_filename).build();
         }
         config::CrateTypeStaticlib => {
-            link_staticlib(sess, &obj_filename, &out_filename);
+            link_staticlib(sess, &objects, &out_filename);
         }
         config::CrateTypeExecutable => {
-            link_natively(sess, trans, false, &obj_filename, &out_filename);
+            link_natively(sess, trans, false, &objects, &out_filename, outputs);
         }
         config::CrateTypeDylib => {
-            link_natively(sess, trans, true, &obj_filename, &out_filename);
+            link_natively(sess, trans, true, &objects, &out_filename, outputs);
         }
     }
 
     out_filename
 }
 
+fn object_filenames(sess: &Session, outputs: &OutputFilenames) -> Vec<PathBuf> {
+    (0..sess.opts.cg.codegen_units).map(|i| {
+        let ext = format!("{}.o", i);
+        outputs.temp_path(OutputTypeObject).with_extension(&ext)
+    }).collect()
+}
+
 fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
     let mut search = Vec::new();
     sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
@@ -552,6 +547,19 @@ fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
     return search;
 }
 
+fn archive_config<'a>(sess: &'a Session,
+                      output: &Path) -> ArchiveConfig<'a> {
+    ArchiveConfig {
+        handler: &sess.diagnostic().handler,
+        dst: output.to_path_buf(),
+        lib_search_paths: archive_search_paths(sess),
+        slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
+        slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
+        ar_prog: get_ar_prog(sess),
+        command_path: command_path(sess),
+    }
+}
+
 // Create an 'rlib'
 //
 // An rlib in its current incarnation is essentially a renamed .a file. The
@@ -560,21 +568,13 @@ fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
 // native libraries and inserting all of the contents into this archive.
 fn link_rlib<'a>(sess: &'a Session,
                  trans: Option<&CrateTranslation>, // None == no metadata/bytecode
-                 obj_filename: &Path,
+                 objects: &[PathBuf],
                  out_filename: &Path) -> ArchiveBuilder<'a> {
-    info!("preparing rlib from {:?} to {:?}", obj_filename, out_filename);
-    let handler = &sess.diagnostic().handler;
-    let config = ArchiveConfig {
-        handler: handler,
-        dst: out_filename.to_path_buf(),
-        lib_search_paths: archive_search_paths(sess),
-        slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
-        slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
-        ar_prog: get_ar_prog(sess),
-        command_path: command_path(sess),
-    };
-    let mut ab = ArchiveBuilder::create(config);
-    ab.add_file(obj_filename).unwrap();
+    info!("preparing rlib from {:?} to {:?}", objects, out_filename);
+    let mut ab = ArchiveBuilder::create(archive_config(sess, out_filename));
+    for obj in objects {
+        ab.add_file(obj).unwrap();
+    }
 
     for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
         match kind {
@@ -600,7 +600,7 @@ fn link_rlib<'a>(sess: &'a Session,
     // this is as follows:
     //
     // * When performing LTO, this archive will be modified to remove
-    //   obj_filename from above. The reason for this is described below.
+    //   objects from above. The reason for this is described below.
     //
     // * When the system linker looks at an archive, it will attempt to
     //   determine the architecture of the archive in order to see whether its
@@ -639,15 +639,14 @@ fn link_rlib<'a>(sess: &'a Session,
             // For LTO purposes, the bytecode of this library is also inserted
             // into the archive.  If codegen_units > 1, we insert each of the
             // bitcode files.
-            for i in 0..sess.opts.cg.codegen_units {
+            for obj in objects {
                 // Note that we make sure that the bytecode filename in the
                 // archive is never exactly 16 bytes long by adding a 16 byte
                 // extension to it. This is to work around a bug in LLDB that
                 // would cause it to crash if the name of a file in an archive
                 // was exactly 16 bytes.
-                let bc_filename = obj_filename.with_extension(&format!("{}.bc", i));
-                let bc_deflated_filename = obj_filename.with_extension(
-                    &format!("{}.bytecode.deflate", i));
+                let bc_filename = obj.with_extension("bc");
+                let bc_deflated_filename = obj.with_extension("bytecode.deflate");
 
                 let mut bc_data = Vec::new();
                 match fs::File::open(&bc_filename).and_then(|mut f| {
@@ -750,8 +749,8 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write,
 // There's no need to include metadata in a static archive, so ensure to not
 // link in the metadata object file (and also don't prepare the archive with a
 // metadata file).
-fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
-    let ab = link_rlib(sess, None, obj_filename, out_filename);
+fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path) {
+    let ab = link_rlib(sess, None, objects, out_filename);
     let mut ab = match sess.target.target.options.is_like_osx {
         true => ab.build().extend(),
         false => ab,
@@ -806,8 +805,9 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
 // This will invoke the system linker/cc to create the resulting file. This
 // links to all upstream files as well.
 fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
-                 obj_filename: &Path, out_filename: &Path) {
-    info!("preparing dylib? ({}) from {:?} to {:?}", dylib, obj_filename,
+                 objects: &[PathBuf], out_filename: &Path,
+                 outputs: &OutputFilenames) {
+    info!("preparing dylib? ({}) from {:?} to {:?}", dylib, objects,
           out_filename);
     let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
 
@@ -828,7 +828,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
             Box::new(GnuLinker { cmd: &mut cmd, sess: &sess }) as Box<Linker>
         };
         link_args(&mut *linker, sess, dylib, tmpdir.path(),
-                  trans, obj_filename, out_filename);
+                  trans, objects, out_filename, outputs);
         if !sess.target.target.options.no_compiler_rt {
             linker.link_staticlib("compiler-rt");
         }
@@ -884,8 +884,9 @@ fn link_args(cmd: &mut Linker,
              dylib: bool,
              tmpdir: &Path,
              trans: &CrateTranslation,
-             obj_filename: &Path,
-             out_filename: &Path) {
+             objects: &[PathBuf],
+             out_filename: &Path,
+             outputs: &OutputFilenames) {
 
     // The default library location, we need this to find the runtime.
     // The location of crates will be determined as needed.
@@ -895,7 +896,9 @@ fn link_args(cmd: &mut Linker,
     let t = &sess.target.target;
 
     cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
-    cmd.add_object(obj_filename);
+    for obj in objects {
+        cmd.add_object(obj);
+    }
     cmd.output_filename(out_filename);
 
     // Stack growth requires statically linking a __morestack function. Note
@@ -922,7 +925,7 @@ fn link_args(cmd: &mut Linker,
     // executable. This metadata is in a separate object file from the main
     // object file, so we link that in here.
     if dylib {
-        cmd.add_object(&obj_filename.with_extension("metadata.o"));
+        cmd.add_object(&outputs.with_extension("metadata.o"));
     }
 
     // Try to strip as much out of the generated object by removing unused
@@ -1127,7 +1130,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
                 add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
             }
             cstore::RequireStatic => {
-                add_static_crate(cmd, sess, tmpdir, &src.rlib.unwrap().0)
+                add_static_crate(cmd, sess, tmpdir, dylib, &src.rlib.unwrap().0)
             }
         }
 
@@ -1143,71 +1146,80 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
     }
 
     // Adds the static "rlib" versions of all crates to the command line.
+    // There's a bit of magic which happens here specifically related to LTO and
+    // dynamic libraries. Specifically:
+    //
+    // * For LTO, we remove upstream object files.
+    // * For dylibs we remove metadata and bytecode from upstream rlibs
+    //
+    // When performing LTO, all of the bytecode from the upstream libraries has
+    // already been included in our object file output. As a result we need to
+    // remove the object files in the upstream libraries so the linker doesn't
+    // try to include them twice (or whine about duplicate symbols). We must
+    // continue to include the rest of the rlib, however, as it may contain
+    // static native libraries which must be linked in.
+    //
+    // When making a dynamic library, linkers by default don't include any
+    // object files in an archive if they're not necessary to resolve the link.
+    // We basically want to convert the archive (rlib) to a dylib, though, so we
+    // *do* want everything included in the output, regardless of whether the
+    // linker thinks it's needed or not. As a result we must use the
+    // --whole-archive option (or the platform equivalent). When using this
+    // option the linker will fail if there are non-objects in the archive (such
+    // as our own metadata and/or bytecode). All in all, for rlibs to be
+    // entirely included in dylibs, we need to remove all non-object files.
+    //
+    // Note, however, that if we're not doing LTO or we're not producing a dylib
+    // (aka we're making an executable), we can just pass the rlib blindly to
+    // the linker (fast) because it's fine if it's not actually included as
+    // we're at the end of the dependency chain.
     fn add_static_crate(cmd: &mut Linker, sess: &Session, tmpdir: &Path,
-                        cratepath: &Path) {
-        // When performing LTO on an executable output, all of the
-        // bytecode from the upstream libraries has already been
-        // included in our object file output. We need to modify all of
-        // the upstream archives to remove their corresponding object
-        // file to make sure we don't pull the same code in twice.
-        //
-        // We must continue to link to the upstream archives to be sure
-        // to pull in native static dependencies. As the final caveat,
-        // on Linux it is apparently illegal to link to a blank archive,
-        // so if an archive no longer has any object files in it after
-        // we remove `lib.o`, then don't link against it at all.
-        //
-        // If we're not doing LTO, then our job is simply to just link
-        // against the archive.
-        if sess.lto() {
-            let name = cratepath.file_name().unwrap().to_str().unwrap();
-            let name = &name[3..name.len() - 5]; // chop off lib/.rlib
-            time(sess.time_passes(),
-                 &format!("altering {}.rlib", name),
-                 (), |()| {
-                let dst = tmpdir.join(cratepath.file_name().unwrap());
-                match fs::copy(&cratepath, &dst) {
-                    Ok(..) => {}
-                    Err(e) => {
-                        sess.fatal(&format!("failed to copy {} to {}: {}",
-                                            cratepath.display(),
-                                            dst.display(), e));
-                    }
+                        dylib: bool, cratepath: &Path) {
+        if !sess.lto() && !dylib {
+            cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
+            return
+        }
+
+        let dst = tmpdir.join(cratepath.file_name().unwrap());
+        let name = cratepath.file_name().unwrap().to_str().unwrap();
+        let name = &name[3..name.len() - 5]; // chop off lib/.rlib
+
+        time(sess.time_passes(), &format!("altering {}.rlib", name), (), |()| {
+            let err = (|| {
+                io::copy(&mut try!(fs::File::open(&cratepath)),
+                         &mut try!(fs::File::create(&dst)))
+            })();
+            if let Err(e) = err {
+                sess.fatal(&format!("failed to copy {} to {}: {}",
+                                    cratepath.display(), dst.display(), e));
+            }
+
+            let mut archive = Archive::open(archive_config(sess, &dst));
+            archive.remove_file(METADATA_FILENAME);
+
+            let mut any_objects = false;
+            for f in archive.files() {
+                if f.ends_with("bytecode.deflate") {
+                    archive.remove_file(&f);
+                    continue
                 }
-                // Fix up permissions of the copy, as fs::copy() preserves
-                // permissions, but the original file may have been installed
-                // by a package manager and may be read-only.
-                match fs::metadata(&dst).and_then(|m| {
-                    let mut perms = m.permissions();
-                    perms.set_readonly(false);
-                    fs::set_permissions(&dst, perms)
-                }) {
-                    Ok(..) => {}
-                    Err(e) => {
-                        sess.fatal(&format!("failed to chmod {} when preparing \
-                                             for LTO: {}", dst.display(), e));
+                let canonical = f.replace("-", "_");
+                let canonical_name = name.replace("-", "_");
+                if sess.lto() && canonical.starts_with(&canonical_name) &&
+                   canonical.ends_with(".o") {
+                    let num = &f[name.len()..f.len() - 2];
+                    if num.len() > 0 && num[1..].parse::<u32>().is_ok() {
+                        archive.remove_file(&f);
+                        continue
                     }
                 }
-                let handler = &sess.diagnostic().handler;
-                let config = ArchiveConfig {
-                    handler: handler,
-                    dst: dst.clone(),
-                    lib_search_paths: archive_search_paths(sess),
-                    slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
-                    slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
-                    ar_prog: get_ar_prog(sess),
-                    command_path: command_path(sess),
-                };
-                let mut archive = Archive::open(config);
-                archive.remove_file(&format!("{}.o", name));
-                let files = archive.files();
-                if files.iter().any(|s| s.ends_with(".o")) {
-                    cmd.link_rlib(&dst);
-                }
-            });
-        } else {
-            cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
-        }
+                any_objects = true;
+            }
+
+            if any_objects {
+                cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
+            }
+        });
     }
 
     // Same thing as above, but for dynamic crates instead of static crates.
diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs
index 7253334d699..518a6c24840 100644
--- a/src/librustc_trans/back/linker.rs
+++ b/src/librustc_trans/back/linker.rs
@@ -30,6 +30,7 @@ pub trait Linker {
     fn link_framework(&mut self, framework: &str);
     fn link_staticlib(&mut self, lib: &str);
     fn link_rlib(&mut self, lib: &Path);
+    fn link_whole_rlib(&mut self, lib: &Path);
     fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]);
     fn include_path(&mut self, path: &Path);
     fn framework_path(&mut self, path: &Path);
@@ -96,6 +97,17 @@ impl<'a> Linker for GnuLinker<'a> {
         }
     }
 
+    fn link_whole_rlib(&mut self, lib: &Path) {
+        if self.sess.target.target.options.is_like_osx {
+            let mut v = OsString::from("-Wl,-force_load,");
+            v.push(lib);
+            self.cmd.arg(&v);
+        } else {
+            self.cmd.arg("-Wl,--whole-archive").arg(lib)
+                    .arg("-Wl,--no-whole-archive");
+        }
+    }
+
     fn gc_sections(&mut self, is_dylib: bool) {
         // The dead_strip option to the linker specifies that functions and data
         // unreachable by the entry point will be removed. This is quite useful
@@ -250,6 +262,10 @@ impl<'a> Linker for MsvcLinker<'a> {
         // not supported?
         self.link_staticlib(lib);
     }
+    fn link_whole_rlib(&mut self, path: &Path) {
+        // not supported?
+        self.link_rlib(path);
+    }
     fn optimize(&mut self) {
         // Needs more investigation of `/OPT` arguments
     }
diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs
index e13a5e97f75..dfeb866c5b3 100644
--- a/src/librustc_trans/back/lto.rs
+++ b/src/librustc_trans/back/lto.rs
@@ -56,33 +56,14 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
         };
 
         let archive = ArchiveRO::open(&path).expect("wanted an rlib");
-        let file = path.file_name().unwrap().to_str().unwrap();
-        let file = &file[3..file.len() - 5]; // chop off lib/.rlib
-        debug!("reading {}", file);
-        for i in 0.. {
-            let filename = format!("{}.{}.bytecode.deflate", file, i);
-            let msg = format!("check for {}", filename);
-            let bc_encoded = time(sess.time_passes(), &msg, (), |_| {
-                archive.iter().find(|section| {
-                    section.name() == Some(&filename[..])
-                })
-            });
-            let bc_encoded = match bc_encoded {
-                Some(data) => data,
-                None => {
-                    if i == 0 {
-                        // No bitcode was found at all.
-                        sess.fatal(&format!("missing compressed bytecode in {}",
-                                           path.display()));
-                    }
-                    // No more bitcode files to read.
-                    break
-                }
-            };
-            let bc_encoded = bc_encoded.data();
+        let bytecodes = archive.iter().filter_map(|child| {
+            child.name().map(|name| (name, child))
+        }).filter(|&(name, _)| name.ends_with("bytecode.deflate"));
+        for (name, data) in bytecodes {
+            let bc_encoded = data.data();
 
             let bc_decoded = if is_versioned_bytecode_format(bc_encoded) {
-                time(sess.time_passes(), &format!("decode {}.{}.bc", file, i), (), |_| {
+                time(sess.time_passes(), &format!("decode {}", name), (), |_| {
                     // Read the version
                     let version = extract_bytecode_format_version(bc_encoded);
 
@@ -106,7 +87,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                     }
                 })
             } else {
-                time(sess.time_passes(), &format!("decode {}.{}.bc", file, i), (), |_| {
+                time(sess.time_passes(), &format!("decode {}", name), (), |_| {
                 // the object must be in the old, pre-versioning format, so simply
                 // inflate everything and let LLVM decide if it can make sense of it
                     match flate::inflate_bytes(bc_encoded) {
@@ -120,10 +101,8 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
             };
 
             let ptr = bc_decoded.as_ptr();
-            debug!("linking {}, part {}", name, i);
-            time(sess.time_passes(),
-                 &format!("ll link {}.{}", name, i),
-                 (),
+            debug!("linking {}", name);
+            time(sess.time_passes(), &format!("ll link {}", name), (),
                  |()| unsafe {
                 if !llvm::LLVMRustLinkInExternalBitcode(llmod,
                                                         ptr as *const libc::c_char,
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 90ddba4e09c..0a9db8a651e 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -27,7 +27,6 @@ use std::ffi::{CStr, CString};
 use std::fs;
 use std::mem;
 use std::path::Path;
-use std::process::Stdio;
 use std::ptr;
 use std::str;
 use std::sync::{Arc, Mutex};
@@ -619,6 +618,8 @@ pub fn run_passes(sess: &Session,
     let needs_crate_bitcode =
             sess.crate_types.borrow().contains(&config::CrateTypeRlib) &&
             sess.opts.output_types.contains(&config::OutputTypeExe);
+    let needs_crate_object =
+            sess.opts.output_types.contains(&config::OutputTypeExe);
     if needs_crate_bitcode {
         modules_config.emit_bc = true;
     }
@@ -696,7 +697,8 @@ pub fn run_passes(sess: &Session,
         if sess.opts.cg.codegen_units == 1 {
             // 1) Only one codegen unit.  In this case it's no difficulty
             //    to copy `foo.0.x` to `foo.x`.
-            copy_gracefully(&crate_output.with_extension(ext), &crate_output.path(output_type));
+            copy_gracefully(&crate_output.with_extension(ext),
+                            &crate_output.path(output_type));
             if !sess.opts.cg.save_temps && !keep_numbered {
                 // The user just wants `foo.x`, not `foo.0.x`.
                 remove(sess, &crate_output.with_extension(ext));
@@ -715,76 +717,11 @@ pub fn run_passes(sess: &Session,
         }
     };
 
-    let link_obj = |output_path: &Path| {
-        // Running `ld -r` on a single input is kind of pointless.
-        if sess.opts.cg.codegen_units == 1 {
-            copy_gracefully(&crate_output.with_extension("0.o"), output_path);
-            // Leave the .0.o file around, to mimic the behavior of the normal
-            // code path.
-            return;
-        }
-
-        // Some builds of MinGW GCC will pass --force-exe-suffix to ld, which
-        // will automatically add a .exe extension if the extension is not
-        // already .exe or .dll.  To ensure consistent behavior on Windows, we
-        // add the .exe suffix explicitly and then rename the output file to
-        // the desired path.  This will give the correct behavior whether or
-        // not GCC adds --force-exe-suffix.
-        let windows_output_path =
-            if sess.target.target.options.is_like_windows {
-                Some(output_path.with_extension("o.exe"))
-            } else {
-                None
-            };
-
-        let (pname, mut cmd) = get_linker(sess);
-
-        cmd.args(&sess.target.target.options.pre_link_args);
-        cmd.arg("-nostdlib");
-
-        for index in 0..trans.modules.len() {
-            cmd.arg(&crate_output.with_extension(&format!("{}.o", index)));
-        }
-
-        cmd.arg("-r").arg("-o")
-           .arg(windows_output_path.as_ref().map(|s| &**s).unwrap_or(output_path));
-
-        cmd.args(&sess.target.target.options.post_link_args);
-
-        if sess.opts.debugging_opts.print_link_args {
-            println!("{:?}", &cmd);
-        }
-
-        cmd.stdin(Stdio::null());
-        match cmd.status() {
-            Ok(status) => {
-                if !status.success() {
-                    sess.err(&format!("linking of {} with `{:?}` failed",
-                                     output_path.display(), cmd));
-                    sess.abort_if_errors();
-                }
-            },
-            Err(e) => {
-                sess.err(&format!("could not exec the linker `{}`: {}",
-                                 pname, e));
-                sess.abort_if_errors();
-            },
-        }
-
-        match windows_output_path {
-            Some(ref windows_path) => {
-                fs::rename(windows_path, output_path).unwrap();
-            },
-            None => {
-                // The file is already named according to `output_path`.
-            }
-        }
-    };
-
     // Flag to indicate whether the user explicitly requested bitcode.
     // Otherwise, we produced it only as a temporary output, and will need
     // to get rid of it.
     let mut user_wants_bitcode = false;
+    let mut user_wants_objects = false;
     for output_type in output_types {
         match *output_type {
             config::OutputTypeBitcode => {
@@ -801,17 +738,10 @@ pub fn run_passes(sess: &Session,
                 copy_if_one_unit("0.s", config::OutputTypeAssembly, false);
             }
             config::OutputTypeObject => {
-                link_obj(&crate_output.path(config::OutputTypeObject));
-            }
-            config::OutputTypeExe => {
-                // If config::OutputTypeObject is already in the list, then
-                // `crate.o` will be handled by the config::OutputTypeObject case.
-                // Otherwise, we need to create the temporary object so we
-                // can run the linker.
-                if !sess.opts.output_types.contains(&config::OutputTypeObject) {
-                    link_obj(&crate_output.temp_path(config::OutputTypeObject));
-                }
+                user_wants_objects = true;
+                copy_if_one_unit("0.o", config::OutputTypeObject, true);
             }
+            config::OutputTypeExe |
             config::OutputTypeDepInfo => {}
         }
     }
@@ -848,15 +778,18 @@ pub fn run_passes(sess: &Session,
         let keep_numbered_bitcode = needs_crate_bitcode ||
                 (user_wants_bitcode && sess.opts.cg.codegen_units > 1);
 
+        let keep_numbered_objects = needs_crate_object ||
+                (user_wants_objects && sess.opts.cg.codegen_units > 1);
+
         for i in 0..trans.modules.len() {
-            if modules_config.emit_obj {
+            if modules_config.emit_obj && !keep_numbered_objects {
                 let ext = format!("{}.o", i);
-                remove(sess, &crate_output.with_extension(&ext[..]));
+                remove(sess, &crate_output.with_extension(&ext));
             }
 
             if modules_config.emit_bc && !keep_numbered_bitcode {
                 let ext = format!("{}.bc", i);
-                remove(sess, &crate_output.with_extension(&ext[..]));
+                remove(sess, &crate_output.with_extension(&ext));
             }
         }
 
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index e2f35983eb4..5027be5fb62 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -1550,6 +1550,31 @@ impl Foo for Bar {
 ```
 "##,
 
+E0191: r##"
+Trait objects need to have all associated types specified. Erroneous code
+example:
+
+```
+trait Trait {
+    type Bar;
+}
+
+type Foo = Trait; // error: the value of the associated type `Bar` (from
+                  //        the trait `Trait`) must be specified
+```
+
+Please verify you specified all associated types of the trait and that you
+used the right trait. Example:
+
+```
+trait Trait {
+    type Bar;
+}
+
+type Foo = Trait<Bar=i32>; // ok!
+```
+"##,
+
 E0192: r##"
 Negative impls are only allowed for traits with default impls. For more
 information see the [opt-in builtin traits RFC](https://github.com/rust-lang/
@@ -1831,6 +1856,47 @@ extern "rust-intrinsic" {
 ```
 "##,
 
+E0220: r##"
+You used an associated type which isn't defined in the trait.
+Erroneous code example:
+
+```
+trait Trait {
+    type Bar;
+}
+
+type Foo = Trait<F=i32>; // error: associated type `F` not found for
+                         //        `Trait`
+```
+
+Please verify you used the right trait or you didn't misspell the
+associated type name. Example:
+
+```
+trait Trait {
+    type Bar;
+}
+
+type Foo = Trait<Bar=i32>; // ok!
+```
+"##,
+
+E0232: r##"
+The attribute must have a value. Erroneous code example:
+
+```
+#[rustc_on_unimplemented] // error: this attribute must have a value
+trait Bar {}
+```
+
+Please supply the missing value of the attribute. Example:
+
+```
+#[rustc_on_unimplemented = "foo"] // ok!
+trait Bar {}
+```
+"##,
+
 E0243: r##"
 This error indicates that not enough type parameters were found in a type or
 trait.
@@ -2074,7 +2140,6 @@ register_diagnostics! {
     E0188, // can not cast a immutable reference to a mutable pointer
     E0189, // deprecated: can only cast a boxed pointer to a boxed object
     E0190, // deprecated: can only cast a &-pointer to an &-object
-    E0191, // value of the associated type must be specified
     E0193, // cannot bound type where clause bounds may only be attached to types
            // involving type parameters
     E0194,
@@ -2092,7 +2157,6 @@ register_diagnostics! {
     E0217, // ambiguous associated type, defined in multiple supertraits
     E0218, // no associated type defined
     E0219, // associated type defined in higher-ranked supertrait
-    E0220, // associated type not found for type parameter
     E0221, // ambiguous associated type in bounds
     //E0222, // Error code E0045 (variadic function must have C calling
              // convention) duplicate
@@ -2105,7 +2169,6 @@ register_diagnostics! {
     E0229, // associated type bindings are not allowed here
     E0230, // there is no type parameter on trait
     E0231, // only named substitution parameters are allowed
-    E0232, // this attribute must have a value
     E0233,
     E0234,
     E0235, // structure constructor specifies a structure of type but
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 1d0152e2751..98d8bc6bdaf 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -19,9 +19,8 @@ use error;
 use fmt;
 use io::{self, DEFAULT_BUF_SIZE, Error, ErrorKind, SeekFrom};
 use ptr;
-use iter;
 
-/// Wraps a `Read` and buffers input from it
+/// Wraps a `Read` and buffers input from it.
 ///
 /// It can be excessively inefficient to work directly with a `Read` instance.
 /// For example, every call to `read` on `TcpStream` results in a system call.
@@ -54,20 +53,18 @@ pub struct BufReader<R> {
 }
 
 impl<R: Read> BufReader<R> {
-    /// Creates a new `BufReader` with a default buffer capacity
+    /// Creates a new `BufReader` with a default buffer capacity.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: R) -> BufReader<R> {
         BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
-    /// Creates a new `BufReader` with the specified buffer capacity
+    /// Creates a new `BufReader` with the specified buffer capacity.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
-        let mut buf = Vec::with_capacity(cap);
-        buf.extend(iter::repeat(0).take(cap));
         BufReader {
             inner: inner,
-            buf: buf,
+            buf: vec![0; cap],
             pos: 0,
             cap: 0,
         }
@@ -183,7 +180,7 @@ impl<R: Seek> Seek for BufReader<R> {
     }
 }
 
-/// Wraps a Writer and buffers output to it
+/// Wraps a Writer and buffers output to it.
 ///
 /// It can be excessively inefficient to work directly with a `Write`. For
 /// example, every call to `write` on `TcpStream` results in a system call. A
@@ -205,13 +202,13 @@ pub struct BufWriter<W: Write> {
 pub struct IntoInnerError<W>(W, Error);
 
 impl<W: Write> BufWriter<W> {
-    /// Creates a new `BufWriter` with a default buffer capacity
+    /// Creates a new `BufWriter` with a default buffer capacity.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: W) -> BufWriter<W> {
         BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
-    /// Creates a new `BufWriter` with the specified buffer capacity
+    /// Creates a new `BufWriter` with the specified buffer capacity.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(cap: usize, inner: W) -> BufWriter<W> {
         BufWriter {
@@ -253,11 +250,11 @@ impl<W: Write> BufWriter<W> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
 
-    /// Gets a mutable reference to the underlying write.
+    /// Gets a mutable reference to the underlying writer.
     ///
     /// # Warning
     ///
-    /// It is inadvisable to directly read from the underlying writer.
+    /// It is inadvisable to directly write to the underlying writer.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
 
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 9021f32fad0..50c44299dc7 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -16,7 +16,7 @@ use cmp;
 use rustc_unicode::str as core_str;
 use error as std_error;
 use fmt;
-use iter::{self, Iterator, Extend};
+use iter::{Iterator};
 use marker::Sized;
 use ops::{Drop, FnOnce};
 use option::Option::{self, Some, None};
@@ -106,7 +106,7 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize>
             if new_write_size < DEFAULT_BUF_SIZE {
                 new_write_size *= 2;
             }
-            buf.extend(iter::repeat(0).take(new_write_size));
+            buf.resize(len + new_write_size, 0);
         }
 
         match r.read(&mut buf[len..]) {
@@ -984,6 +984,14 @@ mod tests {
         let mut v = Vec::new();
         assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
         assert_eq!(v, b"1");
+
+        let cap = 1024 * 1024;
+        let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>();
+        let mut v = Vec::new();
+        let (a, b) = data.split_at(data.len() / 2);
+        assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len());
+        assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len());
+        assert_eq!(v, data);
     }
 
     #[test]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 73e45619774..caf3f497e10 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -146,6 +146,7 @@
 #![feature(unique)]
 #![feature(unsafe_no_drop_flag, filling_drop)]
 #![feature(vec_push_all)]
+#![feature(vec_resize)]
 #![feature(wrapping)]
 #![feature(zero_one)]
 #![cfg_attr(windows, feature(str_utf16))]
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 710928a00c1..649052d123c 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -90,6 +90,11 @@ pub trait Visitor<'v> : Sized {
         walk_struct_def(self, s)
     }
     fn visit_struct_field(&mut self, s: &'v StructField) { walk_struct_field(self, s) }
+    fn visit_enum_def(&mut self, enum_definition: &'v EnumDef,
+                      generics: &'v Generics) {
+        walk_enum_def(self, enum_definition, generics)
+    }
+
     fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics) { walk_variant(self, v, g) }
 
     /// Visits an optional reference to a lifetime. The `span` is the span of some surrounding
@@ -268,7 +273,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
         }
         ItemEnum(ref enum_definition, ref type_parameters) => {
             visitor.visit_generics(type_parameters);
-            walk_enum_def(visitor, enum_definition, type_parameters)
+            visitor.visit_enum_def(enum_definition, type_parameters)
         }
         ItemDefaultImpl(_, ref trait_ref) => {
             visitor.visit_trait_ref(trait_ref)
diff --git a/src/test/auxiliary/issue-14344-1.rs b/src/test/auxiliary/issue-14344-1.rs
new file mode 100644
index 00000000000..78c03bac33f
--- /dev/null
+++ b/src/test/auxiliary/issue-14344-1.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+pub fn foo() {}
diff --git a/src/test/auxiliary/issue-14344-2.rs b/src/test/auxiliary/issue-14344-2.rs
new file mode 100644
index 00000000000..9df35e50adb
--- /dev/null
+++ b/src/test/auxiliary/issue-14344-2.rs
@@ -0,0 +1,13 @@
+// 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.
+
+extern crate issue_14344_1;
+
+pub fn bar() {}
diff --git a/src/test/auxiliary/issue-25185-1.rs b/src/test/auxiliary/issue-25185-1.rs
new file mode 100644
index 00000000000..b9da39cbbcb
--- /dev/null
+++ b/src/test/auxiliary/issue-25185-1.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.
+
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_u32(u: u32) -> u32;
+}
diff --git a/src/test/auxiliary/issue-25185-2.rs b/src/test/auxiliary/issue-25185-2.rs
new file mode 100644
index 00000000000..00b5277d6c0
--- /dev/null
+++ b/src/test/auxiliary/issue-25185-2.rs
@@ -0,0 +1,13 @@
+// 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.
+
+extern crate issue_25185_1;
+
+pub use issue_25185_1::rust_dbg_extern_identity_u32;
diff --git a/src/test/compile-fail/issue-23302.rs b/src/test/compile-fail/issue-23302.rs
new file mode 100644
index 00000000000..7ac8cf45edb
--- /dev/null
+++ b/src/test/compile-fail/issue-23302.rs
@@ -0,0 +1,24 @@
+// 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.
+
+// Check that an enum with recursion in the discriminant throws
+// the appropriate error (rather than, say, blowing the stack).
+enum X {
+    A = X::A as isize, //~ ERROR E0265
+}
+
+// Since `Y::B` here defaults to `Y::A+1`, this is also a
+// recursive definition.
+enum Y {
+    A = Y::B as isize, //~ ERROR E0265
+    B,
+}
+
+fn main() { }
diff --git a/src/test/run-make/execution-engine/Makefile b/src/test/run-make/execution-engine/Makefile
index 387905f45d8..ef646c5bf5d 100644
--- a/src/test/run-make/execution-engine/Makefile
+++ b/src/test/run-make/execution-engine/Makefile
@@ -1,8 +1,14 @@
 -include ../tools.mk
 
+# FIXME: ignore freebsd
 # This is a basic test of LLVM ExecutionEngine functionality using compiled
 # Rust code built using the `rustc` crate.
 
+ifneq ($(shell uname),FreeBSD)
 all:
 	$(RUSTC) test.rs
 	$(call RUN,test $(RUSTC))
+else
+all:
+
+endif
diff --git a/src/test/run-make/extern-fn-reachable/Makefile b/src/test/run-make/extern-fn-reachable/Makefile
index 56748b1eb9b..79a9a3c640f 100644
--- a/src/test/run-make/extern-fn-reachable/Makefile
+++ b/src/test/run-make/extern-fn-reachable/Makefile
@@ -4,6 +4,6 @@
 TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
 
 all:
-	$(RUSTC) dylib.rs -o $(TMPDIR)/libdylib.so
-	$(RUSTC) main.rs
+	$(RUSTC) dylib.rs -o $(TMPDIR)/libdylib.so -C prefer-dynamic
+	$(RUSTC) main.rs -C prefer-dynamic
 	$(call RUN,main)
diff --git a/src/test/run-make/extra-filename-with-temp-outputs/Makefile b/src/test/run-make/extra-filename-with-temp-outputs/Makefile
index 28c22a173cc..d33c18a6f3c 100644
--- a/src/test/run-make/extra-filename-with-temp-outputs/Makefile
+++ b/src/test/run-make/extra-filename-with-temp-outputs/Makefile
@@ -2,5 +2,5 @@
 
 all:
 	$(RUSTC) -C extra-filename=bar foo.rs -C save-temps
-	rm $(TMPDIR)/foobar.o
+	rm $(TMPDIR)/foobar.0.o
 	rm $(TMPDIR)/$(call BIN,foobar)
diff --git a/src/test/run-pass/issue-14344.rs b/src/test/run-pass/issue-14344.rs
new file mode 100644
index 00000000000..06b8f44ed26
--- /dev/null
+++ b/src/test/run-pass/issue-14344.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:issue-14344-1.rs
+// aux-build:issue-14344-2.rs
+
+extern crate issue_14344_1;
+extern crate issue_14344_2;
+
+fn main() {
+    issue_14344_1::foo();
+    issue_14344_2::bar();
+}
diff --git a/src/test/run-pass/issue-25185.rs b/src/test/run-pass/issue-25185.rs
new file mode 100644
index 00000000000..d8d2d5078c5
--- /dev/null
+++ b/src/test/run-pass/issue-25185.rs
@@ -0,0 +1,21 @@
+// 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.
+
+// aux-build:issue-25185-1.rs
+// aux-build:issue-25185-2.rs
+
+extern crate issue_25185_2;
+
+fn main() {
+    let x = unsafe {
+        issue_25185_2::rust_dbg_extern_identity_u32(1)
+    };
+    assert_eq!(x, 1);
+}