about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rwxr-xr-xconfigure12
-rw-r--r--mk/main.mk1
-rw-r--r--mk/tests.mk1
-rw-r--r--src/bootstrap/check.rs4
-rw-r--r--src/bootstrap/compile.rs4
-rw-r--r--src/doc/reference.md3
-rw-r--r--src/libcore/macros.rs33
-rw-r--r--src/libcore/ops.rs12
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs22
-rw-r--r--src/librustc_errors/emitter.rs15
-rw-r--r--src/librustc_errors/lib.rs8
-rw-r--r--src/librustc_typeck/astconv.rs7
-rw-r--r--src/librustc_typeck/check/_match.rs14
-rw-r--r--src/librustc_typeck/check/closure.rs2
-rw-r--r--src/libsyntax/attr.rs5
-rw-r--r--src/test/compile-fail/E0528.rs4
-rw-r--r--src/test/compile-fail/E0529.rs4
-rw-r--r--src/test/compile-fail/E0558.rs5
-rw-r--r--src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs24
-rw-r--r--src/test/compile-fail/regions-escape-loop-via-vec.rs4
-rw-r--r--src/test/run-pass/issue-36023.rs2
-rw-r--r--src/test/run-pass/issue-36139-normalize-closure-sig.rs28
-rw-r--r--src/test/ui/lifetimes/borrowck-let-suggestion.rs (renamed from src/test/compile-fail/borrowck/borrowck-let-suggestion.rs)5
-rw-r--r--src/test/ui/lifetimes/borrowck-let-suggestion.stderr14
-rw-r--r--src/test/ui/span/issue-11925.stderr4
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header.rs22
-rw-r--r--src/tools/compiletest/src/main.rs2
29 files changed, 211 insertions, 57 deletions
diff --git a/.travis.yml b/.travis.yml
index 0abd858d822..c5d8a94f39b 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 44fb3d368d2..bcc1faea3b5 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 5a849af9856..6130b581387 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 201e4cae51d..c135aa9b8fb 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 3d8b1438125..2b9d717cbd4 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 155848901cd..302ac68460c 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 ec2d3e2822e..cc5d9c3685a 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/macros.rs b/src/libcore/macros.rs
index c916ad930ff..f29a49dd5fe 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 2bb0c3c04e0..85a52da332d 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -282,6 +282,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 +355,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> {
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 07faeee10f1..67152ed04ec 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 ed133d21b8a..dcdbe2a8525 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 c99bc470448..d82d7dbe70f 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 7f655ad3d14..6c9cc5f5e13 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 225468cb9f4..f8a2e82edc2 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 516dd9c6422..8980cb90760 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/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 703f3f7adf9..81ee96459fd 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -438,8 +438,9 @@ pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<Inte
             } else {
                 struct_span_err!(diag, attr.span, E0558,
                                  "export_name attribute has invalid format")
-                                .help("use #[export_name=\"*\"]")
-                                .emit();
+                    .span_label(attr.span,
+                                &format!("did you mean #[export_name=\"*\"]?"))
+                    .emit();
                 None
             }
         } else {
diff --git a/src/test/compile-fail/E0528.rs b/src/test/compile-fail/E0528.rs
index 27187bb5aba..e912650f112 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 488fe7c7763..18d3e68816a 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/E0558.rs b/src/test/compile-fail/E0558.rs
index 4ab0506a9c0..0c2ca698491 100644
--- a/src/test/compile-fail/E0558.rs
+++ b/src/test/compile-fail/E0558.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[export_name] //~ ERROR E0558
+#[export_name]
+//~^ ERROR E0558
+//~| NOTE did you mean #[export_name="*"]?
+
 pub fn something() {}
 
 fn main() {}
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 6c9f67b2b33..95c74348e78 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 8c026df7d97..f5ea7a2108e 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 f6c03b384f2..53a8a403b64 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 00000000000..adde0ed3066
--- /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
index ef8f44c1df7..eeafaab44c6 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 00000000000..91600340019
--- /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 d379cfc3d68..3fedb2884bc 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 6090cb4f527..5d522736089 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 af33d76be1b..899a366a4bb 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 90641b5c476..4afeb361331 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!("{}/{}",