diff --git a/.travis.yml b/.travis.yml
index 0abd858d8228b..c5d8a94f39b05 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,9 +15,9 @@ before_install:
 script:
   - docker run -v `pwd`:/build rust
     sh -c "
-      ./configure --llvm-root=/usr/lib/llvm-3.7 &&
+      ./configure --enable-rustbuild --llvm-root=/usr/lib/llvm-3.7 &&
       make tidy &&
-      make check-notidy -j4
+      make check -j4
     "
 
 # Real testing happens on http://buildbot.rust-lang.org/
diff --git a/configure b/configure
index 44fb3d368d2c7..bcc1faea3b5d8 100755
--- a/configure
+++ b/configure
@@ -360,6 +360,13 @@ abs_path() {
     (unset CDPATH && cd "$_path" > /dev/null && pwd)
 }
 
+HELP=0
+for arg; do
+    case "$arg" in
+        --help) HELP=1;;
+    esac
+done
+
 msg "looking for configure programs"
 need_cmd cmp
 need_cmd mkdir
@@ -566,11 +573,8 @@ esac
 
 
 OPTIONS=""
-HELP=0
-if [ "$1" = "--help" ]
+if [ "$HELP" -eq 1 ]
 then
-    HELP=1
-    shift
     echo
     echo "Usage: $CFG_SELF [options]"
     echo
diff --git a/mk/main.mk b/mk/main.mk
index 5a849af9856f1..6130b58138751 100644
--- a/mk/main.mk
+++ b/mk/main.mk
@@ -348,6 +348,7 @@ LLVM_AS_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-as$$(X_$(1))
 LLC_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llc$$(X_$(1))
 
 LLVM_ALL_COMPONENTS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --components)
+LLVM_VERSION_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --version)
 
 endef
 
diff --git a/mk/tests.mk b/mk/tests.mk
index 201e4cae51d6d..c135aa9b8fb95 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -649,6 +649,7 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) = \
 	--lldb-python $$(CFG_LLDB_PYTHON) \
         --gdb-version="$(CFG_GDB_VERSION)" \
         --lldb-version="$(CFG_LLDB_VERSION)" \
+        --llvm-version="$$(LLVM_VERSION_$(3))" \
         --android-cross-path=$(CFG_ARM_LINUX_ANDROIDEABI_NDK) \
         --adb-path=$(CFG_ADB) \
         --adb-test-dir=$(CFG_ADB_TEST_DIR) \
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 3d8b1438125e6..2b9d717cbd48d 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -148,6 +148,9 @@ pub fn compiletest(build: &Build,
     if let Some(ref dir) = build.lldb_python_dir {
         cmd.arg("--lldb-python-dir").arg(dir);
     }
+    let llvm_config = build.llvm_config(target);
+    let llvm_version = output(Command::new(&llvm_config).arg("--version"));
+    cmd.arg("--llvm-version").arg(llvm_version);
 
     cmd.args(&build.flags.args);
 
@@ -158,7 +161,6 @@ pub fn compiletest(build: &Build,
     // Only pass correct values for these flags for the `run-make` suite as it
     // requires that a C++ compiler was configured which isn't always the case.
     if suite == "run-make" {
-        let llvm_config = build.llvm_config(target);
         let llvm_components = output(Command::new(&llvm_config).arg("--components"));
         let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags"));
         cmd.arg("--cc").arg(build.cc(target))
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 155848901cdb4..302ac68460c69 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -203,6 +203,10 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
         cargo.env("LLVM_RUSTLLVM", "1");
     }
     cargo.env("LLVM_CONFIG", build.llvm_config(target));
+    let target_config = build.config.target_config.get(target);
+    if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
+        cargo.env("CFG_LLVM_ROOT", s);
+    }
     if build.config.llvm_static_stdcpp {
         cargo.env("LLVM_STATIC_STDCPP",
                   compiler_file(build.cxx(target), "libstdc++.a"));
diff --git a/src/doc/reference.md b/src/doc/reference.md
index ec2d3e2822e20..cc5d9c3685aba 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -2071,6 +2071,9 @@ macro scope.
    trait of the same name. `{Self}` will be replaced with the type that is supposed
    to implement the trait but doesn't. To use this, the `on_unimplemented` feature gate
    must be enabled.
+- `must_use` - on structs and enums, will warn if a value of this type isn't used or
+   assigned to a variable. You may also include an optional message by using
+   `#[must_use = "message"]` which will be given alongside the warning.
 
 ### Conditional compilation
 
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 8271b85b01a3b..761f1cac8392b 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -222,15 +222,20 @@ extern "rust-intrinsic" {
     ///   trait objects, because they can't be read out onto the stack and
     ///   dropped normally.
     ///
-    /// * It is friendlier to the optimizer to do this over `ptr::read` when
-    ///   dropping manually allocated memory (e.g. when writing Box/Rc/Vec),
-    ///   as the compiler doesn't need to prove that it's sound to elide the
-    ///   copy.
+    /// * It is friendlier to the optimizer to do this over [`ptr::read`] when
+    ///   dropping manually allocated memory (e.g. when writing
+    ///   [`Box`]/[`Rc`]/[`Vec`]), as the compiler doesn't need to prove that
+    ///   it's sound to elide the copy.
     ///
     /// # Undefined Behavior
     ///
-    /// This has all the same safety problems as `ptr::read` with respect to
+    /// This has all the same safety problems as [`ptr::read`] with respect to
     /// invalid pointers, types, and double drops.
+    ///
+    /// [`ptr::read`]: fn.read.html
+    /// [`Box`]: ../boxed/struct.Box.html
+    /// [`Rc`]: ../rc/struct.Rc.html
+    /// [`Vec`]: ../vec/struct.Vec.html
     #[stable(feature = "drop_in_place", since = "1.8.0")]
     pub fn drop_in_place<T: ?Sized>(to_drop: *mut T);
 
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index c916ad930ff10..f29a49dd5fe1a 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -189,10 +189,19 @@ macro_rules! debug_assert_eq {
     ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
 }
 
-/// Helper macro for unwrapping `Result` values while returning early with an
-/// error if the value of the expression is `Err`. Can only be used in
-/// functions that return `Result` because of the early return of `Err` that
-/// it provides.
+/// Helper macro for reducing boilerplate code for matching `Result` together
+/// with converting downstream errors.
+///
+/// `try!` matches the given `Result`. In case of the `Ok` variant, the
+/// expression has the value of the wrapped value.
+///
+/// In case of the `Err` variant, it retrieves the inner error. `try!` then
+/// performs conversion using `From`. This provides automatic conversion
+/// between specialized errors and more general ones. The resulting
+/// error is then immediately returned.
+///
+/// Because of the early return, `try!` can only be used in functions that
+/// return `Result`.
 ///
 /// # Examples
 ///
@@ -201,18 +210,28 @@ macro_rules! debug_assert_eq {
 /// use std::fs::File;
 /// use std::io::prelude::*;
 ///
-/// fn write_to_file_using_try() -> Result<(), io::Error> {
+/// enum MyError {
+///     FileWriteError
+/// }
+///
+/// impl From<io::Error> for MyError {
+///     fn from(e: io::Error) -> MyError {
+///         MyError::FileWriteError
+///     }
+/// }
+///
+/// fn write_to_file_using_try() -> Result<(), MyError> {
 ///     let mut file = try!(File::create("my_best_friends.txt"));
 ///     try!(file.write_all(b"This is a list of my best friends."));
 ///     println!("I wrote to the file");
 ///     Ok(())
 /// }
 /// // This is equivalent to:
-/// fn write_to_file_using_match() -> Result<(), io::Error> {
+/// fn write_to_file_using_match() -> Result<(), MyError> {
 ///     let mut file = try!(File::create("my_best_friends.txt"));
 ///     match file.write_all(b"This is a list of my best friends.") {
 ///         Ok(v) => v,
-///         Err(e) => return Err(e),
+///         Err(e) => return Err(From::from(e)),
 ///     }
 ///     println!("I wrote to the file");
 ///     Ok(())
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 2bb0c3c04e02c..369c00f521418 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -140,6 +140,26 @@
 //!
 //! // `consume_and_return_x` can no longer be invoked at this point
 //! ```
+//!
+//! This example shows the behavior of the various `Range*` structs.
+//!
+//! ```rust
+//! #![feature(inclusive_range_syntax)]
+//! fn main() {
+//!     let arr = [0, 1, 2, 3, 4];
+//!
+//!     assert_eq!(arr[ .. ], [0,1,2,3,4]); // RangeFull
+//!     assert_eq!(arr[ ..3], [0,1,2    ]); // RangeTo
+//!     assert_eq!(arr[1.. ], [  1,2,3,4]); // RangeFrom
+//!     assert_eq!(arr[1..3], [  1,2    ]); // Range
+//!
+//!     assert_eq!(arr[ ...3], [0,1,2,3 ]); // RangeToIncusive
+//!     assert_eq!(arr[1...3], [  1,2,3 ]); // RangeInclusive
+//! }
+//! ```
+//!
+//! Note: whitespace alignment is not idiomatic Rust. An exception is made in
+//! this case to facilitate comparison.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -282,6 +302,12 @@ macro_rules! forward_ref_binop {
 ///                Point { x: 3, y: 3 });
 /// }
 /// ```
+///
+/// Note that `RHS = Self` by default, but this is not mandatory. For example,
+/// [std::time::SystemTime] implements `Add<Duration>`, which permits
+/// operations of the form `SystemTime = SystemTime + Duration`.
+///
+/// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html
 #[lang = "add"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Add<RHS=Self> {
@@ -349,6 +375,12 @@ add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 ///                Point { x: 1, y: 0 });
 /// }
 /// ```
+///
+/// Note that `RHS = Self` by default, but this is not mandatory. For example,
+/// [std::time::SystemTime] implements `Sub<Duration>`, which permits
+/// operations of the form `SystemTime = SystemTime - Duration`.
+///
+/// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html
 #[lang = "sub"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Sub<RHS=Self> {
@@ -1986,11 +2018,12 @@ pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
 ///
 /// ```
 /// let arr = [0, 1, 2, 3];
-/// assert_eq!(arr[ .. ], [0,1,2,3]);  // RangeFull
-/// assert_eq!(arr[ ..3], [0,1,2  ]);
-/// assert_eq!(arr[1.. ], [  1,2,3]);
-/// assert_eq!(arr[1..3], [  1,2  ]);
+/// assert_eq!(arr[ .. ], [0, 1, 2, 3]);
 /// ```
+///
+/// See the [module examples] for the behavior of other range structs.
+///
+/// [module examples]: ../#Examples
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeFull;
@@ -2015,12 +2048,13 @@ impl fmt::Debug for RangeFull {
 ///     assert_eq!(3+4+5, (3..6).sum());
 ///
 ///     let arr = [0, 1, 2, 3];
-///     assert_eq!(arr[ .. ], [0,1,2,3]);
-///     assert_eq!(arr[ ..3], [0,1,2  ]);
-///     assert_eq!(arr[1.. ], [  1,2,3]);
-///     assert_eq!(arr[1..3], [  1,2  ]);  // Range
+///     assert_eq!(arr[1..3], [1, 2]);
 /// }
 /// ```
+///
+/// See the [module examples] for the behavior of other range structs.
+///
+/// [module examples]: ../#Examples
 #[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Range<Idx> {
@@ -2078,12 +2112,13 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
 ///     assert_eq!(2+3+4, (2..).take(3).sum());
 ///
 ///     let arr = [0, 1, 2, 3];
-///     assert_eq!(arr[ .. ], [0,1,2,3]);
-///     assert_eq!(arr[ ..3], [0,1,2  ]);
-///     assert_eq!(arr[1.. ], [  1,2,3]);  // RangeFrom
-///     assert_eq!(arr[1..3], [  1,2  ]);
+///     assert_eq!(arr[1.. ], [1, 2, 3]);
 /// }
 /// ```
+///
+/// See the [module examples] for the behavior of other range structs.
+///
+/// [module examples]: ../#Examples
 #[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeFrom<Idx> {
@@ -2145,11 +2180,12 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
 ///
 /// ```
 /// let arr = [0, 1, 2, 3];
-/// assert_eq!(arr[ .. ], [0,1,2,3]);
-/// assert_eq!(arr[ ..3], [0,1,2  ]);  // RangeTo
-/// assert_eq!(arr[1.. ], [  1,2,3]);
-/// assert_eq!(arr[1..3], [  1,2  ]);
+/// assert_eq!(arr[ ..3], [0, 1, 2]);
 /// ```
+///
+/// See the [module examples] for the behavior of other range structs.
+///
+/// [module examples]: ../#Examples
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeTo<Idx> {
@@ -2196,10 +2232,13 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
 ///     assert_eq!(3+4+5, (3...5).sum());
 ///
 ///     let arr = [0, 1, 2, 3];
-///     assert_eq!(arr[ ...2], [0,1,2  ]);
-///     assert_eq!(arr[1...2], [  1,2  ]);  // RangeInclusive
+///     assert_eq!(arr[1...2], [1, 2]);
 /// }
 /// ```
+///
+/// See the [module examples] for the behavior of other range structs.
+///
+/// [module examples]: ../#Examples
 #[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 pub enum RangeInclusive<Idx> {
@@ -2297,11 +2336,13 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
 /// array elements up to and including the index indicated by `end`.
 ///
 /// ```
-/// #![feature(inclusive_range_syntax)]
 /// let arr = [0, 1, 2, 3];
-/// assert_eq!(arr[ ...2], [0,1,2  ]);  // RangeToInclusive
-/// assert_eq!(arr[1...2], [  1,2  ]);
+/// assert_eq!(arr[ ...2], [0, 1, 2]);
 /// ```
+///
+/// See the [module examples] for the behavior of other range structs.
+///
+/// [module examples]: ../#Examples
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 pub struct RangeToInclusive<Idx> {
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 8c8925251e5cf..1a6be5d202c9d 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -111,11 +111,15 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
 /// # Safety
 ///
 /// Beyond accepting a raw pointer, this is unsafe because it semantically
-/// moves the value out of `src` without preventing further usage of `src`.
-/// If `T` is not `Copy`, then care must be taken to ensure that the value at
-/// `src` is not used before the data is overwritten again (e.g. with `write`,
-/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
-/// because it will attempt to drop the value previously at `*src`.
+/// moves the value out of `src` without preventing further usage of `src`. If
+/// `T` is not [`Copy`], then care must be taken to ensure that the value at
+/// `src` is not used before the data is overwritten again (e.g. with
+/// [`write`]). Note that `*src = foo`
+/// counts as a use because it will attempt to drop the value previously at
+/// `*src`.
+///
+/// [`Copy`]: ../marker/trait.Copy.html
+/// [`write`]: fn.write.html
 ///
 /// # Examples
 ///
@@ -190,11 +194,15 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
 /// # Safety
 ///
 /// Beyond accepting a raw pointer, this is unsafe because it semantically
-/// moves the value out of `src` without preventing further usage of `src`.
-/// If `T` is not `Copy`, then care must be taken to ensure that the value at
-/// `src` is not used before the data is overwritten again (e.g. with `write`,
-/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
-/// because it will attempt to drop the value previously at `*src`.
+/// moves the value out of `src` without preventing further usage of `src`. If
+/// `T` is not [`Copy`], then care must be taken to ensure that the value at
+/// `src` is not used before the data is overwritten again (e.g. with
+/// [`write`]). Note that `*src = foo`
+/// counts as a use because it will attempt to drop the value previously at
+/// `*src`.
+///
+/// [`Copy`]: ../marker/trait.Copy.html
+/// [`write`]: fn.write.html
 ///
 /// # Examples
 ///
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 07faeee10f1c4..67152ed04ec1d 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -1028,6 +1028,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
             }
 
             err_out_of_scope(super_scope, sub_scope, cause) => {
+                let (value_kind, value_msg) = match err.cmt.cat {
+                    mc::Categorization::Rvalue(_) =>
+                        ("temporary value", "temporary value created here"),
+                    _ =>
+                        ("borrowed value", "does not live long enough")
+                };
                 match cause {
                     euv::ClosureCapture(s) => {
                         // The primary span starts out as the closure creation point.
@@ -1038,13 +1044,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                             Some(primary) => {
                                 db.span = MultiSpan::from_span(s);
                                 db.span_label(primary, &format!("capture occurs here"));
-                                db.span_label(s, &format!("does not live long enough"));
+                                db.span_label(s, &value_msg);
                             }
                             None => ()
                         }
                     }
                     _ => {
-                        db.span_label(error_span, &format!("does not live long enough"));
+                        db.span_label(error_span, &value_msg);
                     }
                 }
 
@@ -1053,14 +1059,15 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
 
                 match (sub_span, super_span) {
                     (Some(s1), Some(s2)) if s1 == s2 => {
-                        db.span_label(s1, &"borrowed value dropped before borrower");
+                        db.span_label(s1, &format!("{} dropped before borrower", value_kind));
                         db.note("values in a scope are dropped in the opposite order \
                                 they are created");
                     }
                     _ => {
                         match sub_span {
                             Some(s) => {
-                                db.span_label(s, &"borrowed value must be valid until here");
+                                db.span_label(s, &format!("{} needs to live until here",
+                                                          value_kind));
                             }
                             None => {
                                 self.tcx.note_and_explain_region(
@@ -1072,7 +1079,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                         }
                         match super_span {
                             Some(s) => {
-                                db.span_label(s, &"borrowed value only valid until here");
+                                db.span_label(s, &format!("{} only lives until here", value_kind));
                             }
                             None => {
                                 self.tcx.note_and_explain_region(
@@ -1085,9 +1092,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     }
                 }
 
-                if let Some(span) = statement_scope_span(self.tcx, super_scope) {
-                    db.span_help(span,
-                                 "consider using a `let` binding to increase its lifetime");
+                if let Some(_) = statement_scope_span(self.tcx, super_scope) {
+                    db.note("consider using a `let` binding to increase its lifetime");
                 }
             }
 
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index ed133d21b8a0f..dcdbe2a85259b 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -883,7 +883,11 @@ impl Destination {
             Style::FileNameStyle | Style::LineAndColumn => {}
             Style::LineNumber => {
                 try!(self.start_attr(term::Attr::Bold));
-                try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE)));
+                if cfg!(windows) {
+                    try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_CYAN)));
+                } else {
+                    try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE)));
+                }
             }
             Style::ErrorCode => {
                 try!(self.start_attr(term::Attr::Bold));
@@ -896,6 +900,9 @@ impl Destination {
             }
             Style::OldSchoolNoteText | Style::HeaderMsg => {
                 try!(self.start_attr(term::Attr::Bold));
+                if cfg!(windows) {
+                    try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_WHITE)));
+                }
             }
             Style::UnderlinePrimary | Style::LabelPrimary => {
                 try!(self.start_attr(term::Attr::Bold));
@@ -904,7 +911,11 @@ impl Destination {
             Style::UnderlineSecondary |
             Style::LabelSecondary => {
                 try!(self.start_attr(term::Attr::Bold));
-                try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE)));
+                if cfg!(windows) {
+                    try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_CYAN)));
+                } else {
+                    try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE)));
+                }
             }
             Style::NoStyle => {}
             Style::Level(l) => {
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index c99bc47044853..d82d7dbe70f92 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -732,7 +732,13 @@ impl Level {
     pub fn color(self) -> term::color::Color {
         match self {
             Bug | Fatal | PhaseFatal | Error => term::color::BRIGHT_RED,
-            Warning => term::color::YELLOW,
+            Warning => {
+                if cfg!(windows) {
+                    term::color::BRIGHT_YELLOW
+                } else {
+                    term::color::YELLOW
+                }
+            },
             Note => term::color::BRIGHT_GREEN,
             Help => term::color::BRIGHT_CYAN,
             Cancelled => unreachable!(),
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 7f655ad3d149e..6c9cc5f5e132a 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1878,11 +1878,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
             hir::DefaultReturn(..) => self.tcx().mk_nil(),
         };
 
+        let input_tys = self_ty.into_iter().chain(arg_tys).collect();
+
+        debug!("ty_of_method_or_bare_fn: input_tys={:?}", input_tys);
+        debug!("ty_of_method_or_bare_fn: output_ty={:?}", output_ty);
+
         (self.tcx().mk_bare_fn(ty::BareFnTy {
             unsafety: unsafety,
             abi: abi,
             sig: ty::Binder(ty::FnSig {
-                inputs: self_ty.into_iter().chain(arg_tys).collect(),
+                inputs: input_tys,
                 output: output_ty,
                 variadic: decl.variadic
             }),
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 225468cb9f40c..f8a2e82edc2a6 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -248,9 +248,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         } else if let Some(rest) = size.checked_sub(min_len) {
                             (inner_ty, tcx.mk_array(inner_ty, rest))
                         } else {
-                            span_err!(tcx.sess, pat.span, E0528,
-                                      "pattern requires at least {} elements but array has {}",
-                                      min_len, size);
+                            struct_span_err!(tcx.sess, pat.span, E0528,
+                                    "pattern requires at least {} elements but array has {}",
+                                    min_len, size)
+                                .span_label(pat.span,
+                                    &format!("pattern cannot match array of {} elements", size))
+                                .emit();
                             (inner_ty, tcx.types.err)
                         }
                     }
@@ -270,7 +273,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                     _ => {}
                                 }
                             }
-                            err.emit();
+
+                            err.span_label( pat.span,
+                                &format!("pattern cannot match with input type `{}`", expected_ty)
+                            ).emit();
                         }
                         (tcx.types.err, tcx.types.err)
                     }
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 516dd9c64221c..8980cb9076027 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -74,6 +74,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         let fn_sig = self.tcx.liberate_late_bound_regions(
             self.tcx.region_maps.call_site_extent(expr.id, body.id), &fn_ty.sig);
+        let fn_sig =
+            (**self).normalize_associated_types_in(body.span, body.id, &fn_sig);
 
         check_fn(self, hir::Unsafety::Normal, expr.id, &fn_sig, decl, expr.id, &body);
 
diff --git a/src/test/compile-fail/E0528.rs b/src/test/compile-fail/E0528.rs
index 27187bb5aba08..e912650f11292 100644
--- a/src/test/compile-fail/E0528.rs
+++ b/src/test/compile-fail/E0528.rs
@@ -13,7 +13,9 @@
 fn main() {
     let r = &[1, 2];
     match r {
-        &[a, b, c, rest..] => { //~ ERROR E0528
+        &[a, b, c, rest..] => {
+        //~^ ERROR E0528
+        //~| NOTE pattern cannot match array of 2 elements
         }
     }
 }
diff --git a/src/test/compile-fail/E0529.rs b/src/test/compile-fail/E0529.rs
index 488fe7c7763ae..18d3e68816aad 100644
--- a/src/test/compile-fail/E0529.rs
+++ b/src/test/compile-fail/E0529.rs
@@ -13,7 +13,9 @@
 fn main() {
     let r: f32 = 1.0;
     match r {
-        [a, b] => { //~ ERROR E0529
+        [a, b] => {
+        //~^ ERROR E0529
+        //~| NOTE pattern cannot match with input type `f32`
         }
     }
 }
diff --git a/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs b/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs
index 6c9f67b2b33d4..95c74348e788b 100644
--- a/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs
+++ b/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs
@@ -25,9 +25,9 @@ fn f() {
 
     v3.push(&'x');           // statement 6
     //~^ ERROR borrowed value does not live long enough
-    //~| NOTE does not live long enough
-    //~| NOTE borrowed value only valid until here
-    //~| HELP consider using a `let` binding to increase its lifetime
+    //~| NOTE temporary value created here
+    //~| NOTE temporary value only lives until here
+    //~| NOTE consider using a `let` binding to increase its lifetime
 
     {
 
@@ -35,26 +35,26 @@ fn f() {
 
         v4.push(&'y');
         //~^ ERROR borrowed value does not live long enough
-        //~| NOTE does not live long enough
-        //~| NOTE borrowed value only valid until here
-        //~| HELP consider using a `let` binding to increase its lifetime
+        //~| NOTE temporary value created here
+        //~| NOTE temporary value only lives until here
+        //~| NOTE consider using a `let` binding to increase its lifetime
 
     }                       // (statement 7)
-    //~^ NOTE borrowed value must be valid until here
+    //~^ NOTE temporary value needs to live until here
 
     let mut v5 = Vec::new(); // statement 8
 
     v5.push(&'z');
     //~^ ERROR borrowed value does not live long enough
-    //~| NOTE does not live long enough
-    //~| NOTE borrowed value only valid until here
-    //~| HELP consider using a `let` binding to increase its lifetime
+    //~| NOTE temporary value created here
+    //~| NOTE temporary value only lives until here
+    //~| NOTE consider using a `let` binding to increase its lifetime
 
     v1.push(&old[0]);
 }
 //~^ NOTE borrowed value dropped before borrower
-//~| NOTE borrowed value must be valid until here
-//~| NOTE borrowed value must be valid until here
+//~| NOTE temporary value needs to live until here
+//~| NOTE temporary value needs to live until here
 
 fn main() {
     f();
diff --git a/src/test/compile-fail/regions-escape-loop-via-vec.rs b/src/test/compile-fail/regions-escape-loop-via-vec.rs
index 8c026df7d9754..f5ea7a2108e79 100644
--- a/src/test/compile-fail/regions-escape-loop-via-vec.rs
+++ b/src/test/compile-fail/regions-escape-loop-via-vec.rs
@@ -24,8 +24,8 @@ fn broken() {
         x += 1; //~ ERROR cannot assign
         //~^ NOTE assignment to borrowed `x` occurs here
     }
-    //~^ NOTE borrowed value only valid until here
+    //~^ NOTE borrowed value only lives until here
 }
-//~^ NOTE borrowed value must be valid until here
+//~^ NOTE borrowed value needs to live until here
 
 fn main() { }
diff --git a/src/test/run-pass/issue-36023.rs b/src/test/run-pass/issue-36023.rs
index f6c03b384f23d..53a8a403b6410 100644
--- a/src/test/run-pass/issue-36023.rs
+++ b/src/test/run-pass/issue-36023.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// min-llvm-version 3.9
+
 use std::ops::Deref;
 
 fn main() {
diff --git a/src/test/run-pass/issue-36139-normalize-closure-sig.rs b/src/test/run-pass/issue-36139-normalize-closure-sig.rs
new file mode 100644
index 0000000000000..adde0ed306674
--- /dev/null
+++ b/src/test/run-pass/issue-36139-normalize-closure-sig.rs
@@ -0,0 +1,28 @@
+// Copyright 2016 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.
+
+// Previously the closure's argument would be inferred to
+// <S as ITrait<'a>>::Item, causing an error in MIR type
+// checking
+
+trait ITrait<'a> {type Item;}
+
+struct S {}
+
+impl<'a> ITrait<'a> for S { type Item = &'a mut usize; }
+
+fn m<T, I, F>(_: F)
+    where I: for<'a> ITrait<'a>,
+          F: for<'a> FnMut(<I as ITrait<'a>>::Item) { }
+
+
+fn main() {
+    m::<usize,S,_>(|x| { *x += 1; });
+}
diff --git a/src/test/compile-fail/borrowck/borrowck-let-suggestion.rs b/src/test/ui/lifetimes/borrowck-let-suggestion.rs
similarity index 66%
rename from src/test/compile-fail/borrowck/borrowck-let-suggestion.rs
rename to src/test/ui/lifetimes/borrowck-let-suggestion.rs
index ef8f44c1df789..eeafaab44c620 100644
--- a/src/test/compile-fail/borrowck/borrowck-let-suggestion.rs
+++ b/src/test/ui/lifetimes/borrowck-let-suggestion.rs
@@ -10,12 +10,7 @@
 
 fn f() {
     let x = [1].iter();
-    //~^ ERROR borrowed value does not live long enough
-    //~| NOTE does not live long enough
-    //~| NOTE borrowed value only valid until here
-    //~| HELP consider using a `let` binding to increase its lifetime
 }
-//~^ borrowed value must be valid until here
 
 fn main() {
     f();
diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
new file mode 100644
index 0000000000000..91600340019c3
--- /dev/null
+++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
@@ -0,0 +1,14 @@
+error: borrowed value does not live long enough
+  --> $DIR/borrowck-let-suggestion.rs:12:13
+   |
+12 |     let x = [1].iter();
+   |             ^^^       - temporary value only lives until here
+   |             |
+   |             temporary value created here
+13 | }
+   | - temporary value needs to live until here
+   |
+   = note: consider using a `let` binding to increase its lifetime
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/span/issue-11925.stderr b/src/test/ui/span/issue-11925.stderr
index d379cfc3d68a7..3fedb2884bc58 100644
--- a/src/test/ui/span/issue-11925.stderr
+++ b/src/test/ui/span/issue-11925.stderr
@@ -5,10 +5,10 @@ error: `x` does not live long enough
    |                                    ^
    |                                    |
    |                                    does not live long enough
-   |                                    borrowed value only valid until here
+   |                                    borrowed value only lives until here
 ...
 23 | }
-   | - borrowed value must be valid until here
+   | - borrowed value needs to live until here
 
 error: aborting due to previous error
 
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 6090cb4f52725..5d522736089ea 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -152,6 +152,9 @@ pub struct Config {
     // Version of LLDB
     pub lldb_version: Option<String>,
 
+    // Version of LLVM
+    pub llvm_version: Option<String>,
+
     // Path to the android tools
     pub android_cross_path: PathBuf,
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index af33d76be1b0d..899a366a4bb74 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -44,7 +44,9 @@ impl EarlyProps {
                 (config.mode == common::Pretty && parse_name_directive(ln, "ignore-pretty")) ||
                 (config.target != config.host &&
                  parse_name_directive(ln, "ignore-cross-compile")) ||
-                ignore_gdb(config, ln) || ignore_lldb(config, ln);
+                ignore_gdb(config, ln) ||
+                ignore_lldb(config, ln) ||
+                ignore_llvm(config, ln);
 
             props.should_fail = props.should_fail || parse_name_directive(ln, "should-fail");
         });
@@ -115,6 +117,24 @@ impl EarlyProps {
                 false
             }
         }
+
+        fn ignore_llvm(config: &Config, line: &str) -> bool {
+            if let Some(ref actual_version) = config.llvm_version {
+                if line.contains("min-llvm-version") {
+                    let min_version = line.trim()
+                        .split(' ')
+                        .last()
+                        .expect("Malformed llvm version directive");
+                    // Ignore if actual version is smaller the minimum required
+                    // version
+                    &actual_version[..] < min_version
+                } else {
+                    false
+                }
+            } else {
+                false
+            }
+        }
     }
 }
 
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 90641b5c476d7..4afeb3613319b 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -99,6 +99,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
           optopt("", "host", "the host to build for", "HOST"),
           optopt("", "gdb-version", "the version of GDB used", "VERSION STRING"),
           optopt("", "lldb-version", "the version of LLDB used", "VERSION STRING"),
+          optopt("", "llvm-version", "the version of LLVM used", "VERSION STRING"),
           optopt("", "android-cross-path", "Android NDK standalone path", "PATH"),
           optopt("", "adb-path", "path to the android debugger", "PATH"),
           optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"),
@@ -170,6 +171,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
         host: opt_str2(matches.opt_str("host")),
         gdb_version: extract_gdb_version(matches.opt_str("gdb-version")),
         lldb_version: extract_lldb_version(matches.opt_str("lldb-version")),
+        llvm_version: matches.opt_str("llvm-version"),
         android_cross_path: opt_path(matches, "android-cross-path"),
         adb_path: opt_str2(matches.opt_str("adb-path")),
         adb_test_dir: format!("{}/{}",