about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap/install.rs7
-rw-r--r--src/doc/not_found.md2
-rw-r--r--src/librustc/hir/print.rs9
-rw-r--r--src/librustc/infer/error_reporting/different_lifetimes.rs55
-rw-r--r--src/librustc/infer/error_reporting/named_anon_conflict.rs16
-rw-r--r--src/librustc/infer/error_reporting/util.rs1
-rw-r--r--src/librustc/session/config.rs48
-rw-r--r--src/librustdoc/test.rs16
-rw-r--r--src/libstd/sync/rwlock.rs11
-rw-r--r--src/libstd/sys/unix/ext/fs.rs246
-rw-r--r--src/libstd/thread/mod.rs14
-rw-r--r--src/libsyntax/print/pprust.rs9
-rw-r--r--src/test/compile-fail/regions-infer-at-fn-not-param.rs2
-rw-r--r--src/test/pretty/cast-lt.pp24
-rw-r--r--src/test/pretty/cast-lt.rs22
-rw-r--r--src/test/rustdoc/playground-arg.rs2
-rw-r--r--src/test/rustdoc/playground.rs6
-rw-r--r--src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs30
-rw-r--r--src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr11
-rw-r--r--src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs (renamed from src/test/ui/lifetime-errors/ex3-both-anon-regions-earlybound-regions.rs)0
-rw-r--r--src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr11
-rw-r--r--src/test/ui/lifetime-errors/ex3-both-anon-regions-earlybound-regions.stderr11
22 files changed, 479 insertions, 74 deletions
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 5ca9cb5e521..c150459bee5 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -186,8 +186,11 @@ install!((self, builder, _config),
         install_cargo(builder, self.stage, self.target);
     };
     Rls, "rls", _config.extended, only_hosts: true, {
-        builder.ensure(dist::Rls { stage: self.stage, target: self.target });
-        install_rls(builder, self.stage, self.target);
+        if builder.ensure(dist::Rls { stage: self.stage, target: self.target }).is_some() {
+            install_rls(builder, self.stage, self.target);
+        } else {
+            println!("skipping Install RLS stage{} ({})", self.stage, self.target);
+        }
     };
     Analysis, "analysis", _config.extended, only_hosts: false, {
         builder.ensure(dist::Analysis {
diff --git a/src/doc/not_found.md b/src/doc/not_found.md
index 5d632ebc68f..ebe7c59313f 100644
--- a/src/doc/not_found.md
+++ b/src/doc/not_found.md
@@ -22,7 +22,7 @@ Some things that might be helpful to you though:
 # Reference
 
 * [The Rust official site](https://www.rust-lang.org)
-* [The Rust reference](https://doc.rust-lang.org/reference.html)
+* [The Rust reference](https://doc.rust-lang.org/reference/index.html)
 
 # Docs
 
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 7b4881f5486..7d0f26ba34d 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1254,6 +1254,15 @@ impl<'a> State<'a> {
             Fixity::None => (prec + 1, prec + 1),
         };
 
+        let left_prec = match (&lhs.node, op.node) {
+            // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
+            // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
+            // of `(x as i32) < ...`. We need to convince it _not_ to do that.
+            (&hir::ExprCast { .. }, hir::BinOp_::BiLt) |
+            (&hir::ExprCast { .. }, hir::BinOp_::BiShl) => parser::PREC_FORCE_PAREN,
+            _ => left_prec,
+        };
+
         self.print_expr_maybe_paren(lhs, left_prec)?;
         self.s.space()?;
         self.word_space(op.node.as_str())?;
diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs
index ee30db26255..d7e0877d95c 100644
--- a/src/librustc/infer/error_reporting/different_lifetimes.rs
+++ b/src/librustc/infer/error_reporting/different_lifetimes.rs
@@ -21,25 +21,42 @@ use hir::intravisit::{self, Visitor, NestedVisitorMap};
 use infer::error_reporting::util::AnonymousArgInfo;
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-    // This method prints the error message for lifetime errors when both the concerned regions
-    // are anonymous.
-    // Consider a case where we have
-    // fn foo(x: &mut Vec<&u8>, y: &u8)
-    //    { x.push(y); }.
-    // The example gives
-    // fn foo(x: &mut Vec<&u8>, y: &u8) {
-    //                    ---      --- these references are declared with different lifetimes...
-    //            x.push(y);
-    //            ^ ...but data from `y` flows into `x` here
-    // It has been extended for the case of structs too.
-    // Consider the example
-    // struct Ref<'a> { x: &'a u32 }
-    // fn foo(mut x: Vec<Ref>, y: Ref) {
-    //                   ---      --- these structs are declared with different lifetimes...
-    //               x.push(y);
-    //               ^ ...but data from `y` flows into `x` here
-    // }
-    // It will later be extended to trait objects.
+    /// Print the error message for lifetime errors when both the concerned regions are anonymous.
+    ///
+    /// Consider a case where we have
+    ///
+    /// ```no_run
+    /// fn foo(x: &mut Vec<&u8>, y: &u8) {
+    ///     x.push(y);
+    /// }
+    /// ```
+    ///
+    /// The example gives
+    ///
+    /// ```text
+    /// fn foo(x: &mut Vec<&u8>, y: &u8) {
+    ///                    ---      --- these references are declared with different lifetimes...
+    ///     x.push(y);
+    ///     ^ ...but data from `y` flows into `x` here
+    /// ```
+    ///
+    /// It has been extended for the case of structs too.
+    ///
+    /// Consider the example
+    ///
+    /// ```no_run
+    /// struct Ref<'a> { x: &'a u32 }
+    /// ```
+    ///
+    /// ```text
+    /// fn foo(mut x: Vec<Ref>, y: Ref) {
+    ///                   ---      --- these structs are declared with different lifetimes...
+    ///     x.push(y);
+    ///     ^ ...but data from `y` flows into `x` here
+    /// }
+    /// ````
+    ///
+    /// It will later be extended to trait objects.
     pub fn try_report_anon_anon_conflict(&self, error: &RegionResolutionError<'tcx>) -> bool {
         let (span, sub, sup) = match *error {
             ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
diff --git a/src/librustc/infer/error_reporting/named_anon_conflict.rs b/src/librustc/infer/error_reporting/named_anon_conflict.rs
index 80fb4ce8e03..6d3b9507840 100644
--- a/src/librustc/infer/error_reporting/named_anon_conflict.rs
+++ b/src/librustc/infer/error_reporting/named_anon_conflict.rs
@@ -16,18 +16,15 @@ use infer::region_inference::RegionResolutionError;
 use ty;
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-    // This method generates the error message for the case when
-    // the function arguments consist of a named region and an anonymous
-    // region and corresponds to `ConcreteFailure(..)`
+    /// When given a `ConcreteFailure` for a function with arguments containing a named region and
+    /// an anonymous region, emit an descriptive diagnostic error.
     pub fn try_report_named_anon_conflict(&self, error: &RegionResolutionError<'tcx>) -> bool {
         let (span, sub, sup) = match *error {
             ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
             _ => return false, // inapplicable
         };
 
-        debug!("try_report_named_anon_conflict(sub={:?}, sup={:?})",
-               sub,
-               sup);
+        debug!("try_report_named_anon_conflict(sub={:?}, sup={:?})", sub, sup);
 
         // Determine whether the sub and sup consist of one named region ('a)
         // and one anonymous (elided) region. If so, find the parameter arg
@@ -53,10 +50,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             };
 
         debug!("try_report_named_anon_conflict: named = {:?}", named);
-        debug!("try_report_named_anon_conflict: anon_arg_info = {:?}",
-               anon_arg_info);
-        debug!("try_report_named_anon_conflict: region_info = {:?}",
-               region_info);
+        debug!("try_report_named_anon_conflict: anon_arg_info = {:?}", anon_arg_info);
+        debug!("try_report_named_anon_conflict: region_info = {:?}", region_info);
 
         let (arg, new_ty, br, is_first, scope_def_id, is_impl_item) = (anon_arg_info.arg,
                                                                        anon_arg_info.arg_ty,
@@ -101,6 +96,5 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 .span_label(span, format!("lifetime `{}` required", named))
                 .emit();
         return true;
-
     }
 }
diff --git a/src/librustc/infer/error_reporting/util.rs b/src/librustc/infer/error_reporting/util.rs
index 47db3f1b792..6bcd98a7a68 100644
--- a/src/librustc/infer/error_reporting/util.rs
+++ b/src/librustc/infer/error_reporting/util.rs
@@ -221,6 +221,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     _ => false,
                 }
             }
+            ty::ReEarlyBound(_) => true,
             _ => false,
         }
     }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 9f50afde145..4ed2bce5ab1 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -138,6 +138,34 @@ impl OutputType {
         }
     }
 
+    fn from_shorthand(shorthand: &str) -> Option<Self> {
+        Some(match shorthand {
+             "asm" => OutputType::Assembly,
+             "llvm-ir" => OutputType::LlvmAssembly,
+             "mir" => OutputType::Mir,
+             "llvm-bc" => OutputType::Bitcode,
+             "obj" => OutputType::Object,
+             "metadata" => OutputType::Metadata,
+             "link" => OutputType::Exe,
+             "dep-info" => OutputType::DepInfo,
+            _ => return None,
+        })
+    }
+
+    fn shorthands_display() -> String {
+        format!(
+            "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
+            OutputType::Bitcode.shorthand(),
+            OutputType::Assembly.shorthand(),
+            OutputType::LlvmAssembly.shorthand(),
+            OutputType::Mir.shorthand(),
+            OutputType::Object.shorthand(),
+            OutputType::Metadata.shorthand(),
+            OutputType::Exe.shorthand(),
+            OutputType::DepInfo.shorthand(),
+        )
+    }
+
     pub fn extension(&self) -> &'static str {
         match *self {
             OutputType::Bitcode => "bc",
@@ -1488,19 +1516,13 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
         for list in matches.opt_strs("emit") {
             for output_type in list.split(',') {
                 let mut parts = output_type.splitn(2, '=');
-                let output_type = match parts.next().unwrap() {
-                    "asm" => OutputType::Assembly,
-                    "llvm-ir" => OutputType::LlvmAssembly,
-                    "mir" => OutputType::Mir,
-                    "llvm-bc" => OutputType::Bitcode,
-                    "obj" => OutputType::Object,
-                    "metadata" => OutputType::Metadata,
-                    "link" => OutputType::Exe,
-                    "dep-info" => OutputType::DepInfo,
-                    part => {
-                        early_error(error_format, &format!("unknown emission type: `{}`",
-                                                    part))
-                    }
+                let shorthand = parts.next().unwrap();
+                let output_type = match OutputType::from_shorthand(shorthand) {
+                    Some(output_type) => output_type,
+                    None => early_error(error_format, &format!(
+                        "unknown emission type: `{}` - expected one of: {}",
+                        shorthand, OutputType::shorthands_display(),
+                    )),
                 };
                 let path = parts.next().map(PathBuf::from);
                 output_types.insert(output_type, path);
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 9316805b932..9bbd16355be 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -337,15 +337,23 @@ pub fn make_test(s: &str,
 
     let mut prog = String::new();
 
-    // First push any outer attributes from the example, assuming they
-    // are intended to be crate attributes.
-    prog.push_str(&crate_attrs);
+    if opts.attrs.is_empty() {
+        // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some
+        // lints that are commonly triggered in doctests. The crate-level test attributes are
+        // commonly used to make tests fail in case they trigger warnings, so having this there in
+        // that case may cause some tests to pass when they shouldn't have.
+        prog.push_str("#![allow(unused)]\n");
+    }
 
-    // Next, any attributes for other aspects such as lints.
+    // Next, any attributes that came from the crate root via #![doc(test(attr(...)))].
     for attr in &opts.attrs {
         prog.push_str(&format!("#![{}]\n", attr));
     }
 
+    // Now push any outer attributes from the example, assuming they
+    // are intended to be crate attributes.
+    prog.push_str(&crate_attrs);
+
     // Don't inject `extern crate std` because it's already injected by the
     // compiler.
     if !s.contains("extern crate") && !opts.no_crate_inject && cratename != Some("std") {
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 5555f364e6e..d59a0b65a69 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -10,7 +10,6 @@
 
 use cell::UnsafeCell;
 use fmt;
-use marker;
 use mem;
 use ops::{Deref, DerefMut};
 use ptr;
@@ -102,7 +101,10 @@ pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
+impl<'a, T: ?Sized> !Send for RwLockReadGuard<'a, T> {}
+
+#[stable(feature = "rwlock_guard_sync", since = "1.23.0")]
+unsafe impl<'a, T: ?Sized + Sync> Sync for RwLockReadGuard<'a, T> {}
 
 /// RAII structure used to release the exclusive write access of a lock when
 /// dropped.
@@ -121,7 +123,10 @@ pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: ?Sized> !marker::Send for RwLockWriteGuard<'a, T> {}
+impl<'a, T: ?Sized> !Send for RwLockWriteGuard<'a, T> {}
+
+#[stable(feature = "rwlock_guard_sync", since = "1.23.0")]
+unsafe impl<'a, T: ?Sized + Sync> Sync for RwLockWriteGuard<'a, T> {}
 
 impl<T> RwLock<T> {
     /// Creates a new instance of an `RwLock<T>` which is unlocked.
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index 3e631ad40ac..d23cae40cfa 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -215,36 +215,282 @@ impl OpenOptionsExt for OpenOptions {
 // casts and rely on manual lowering to `stat` if the raw type is desired.
 #[stable(feature = "metadata_ext", since = "1.1.0")]
 pub trait MetadataExt {
+    /// Returns the ID of the device containing the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let dev_id = meta.dev();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn dev(&self) -> u64;
+    /// Returns the inode number.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let inode = meta.ino();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ino(&self) -> u64;
+    /// Returns the rights applied to this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let mode = meta.mode();
+    /// let user_has_write_access      = mode & 0o200;
+    /// let user_has_read_write_access = mode & 0o600;
+    /// let group_has_read_access      = mode & 0o040;
+    /// let others_have_exec_access    = mode & 0o001;
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mode(&self) -> u32;
+    /// Returns the number of hard links pointing to this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let nb_hard_links = meta.nlink();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn nlink(&self) -> u64;
+    /// Returns the user ID of the owner of this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let user_id = meta.uid();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn uid(&self) -> u32;
+    /// Returns the group ID of the owner of this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let group_id = meta.gid();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn gid(&self) -> u32;
+    /// Returns the device ID of this file (if it is a special one).
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let device_id = meta.rdev();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn rdev(&self) -> u64;
+    /// Returns the total size of this file in bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let file_size = meta.size();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn size(&self) -> u64;
+    /// Returns the time of the last access to the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let last_access_time = meta.atime();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn atime(&self) -> i64;
+    /// Returns the time of the last access to the file in nanoseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let nano_last_access_time = meta.atime_nsec();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn atime_nsec(&self) -> i64;
+    /// Returns the time of the last modification of the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let last_modification_time = meta.mtime();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mtime(&self) -> i64;
+    /// Returns the time of the last modification of the file in nanoseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let nano_last_modification_time = meta.mtime_nsec();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mtime_nsec(&self) -> i64;
+    /// Returns the time of the last status change of the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let last_status_change_time = meta.ctime();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ctime(&self) -> i64;
+    /// Returns the time of the last status change of the file in nanoseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let nano_last_status_change_time = meta.ctime_nsec();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ctime_nsec(&self) -> i64;
+    /// Returns the blocksize for filesystem I/O.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let blocksize = meta.blksize();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn blksize(&self) -> u64;
+    /// Returns the number of blocks allocated to the file, in 512-byte units.
+    ///
+    /// Please note that this may be smaller than `st_size / 512` when the file has holes.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let blocks = meta.blocks();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn blocks(&self) -> u64;
 }
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 28a33c7ec14..ee49bf796b8 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -25,11 +25,15 @@
 //!
 //! Fatal logic errors in Rust cause *thread panic*, during which
 //! a thread will unwind the stack, running destructors and freeing
-//! owned resources. Thread panic is unrecoverable from within
-//! the panicking thread (i.e. there is no 'try/catch' in Rust), but
-//! the panic may optionally be detected from a different thread. If
-//! the main thread panics, the application will exit with a non-zero
-//! exit code.
+//! owned resources. While not meant as a 'try/catch' mechanism, panics
+//! in Rust can nonetheless be caught (unless compiling with `panic=abort`) with
+//! [`catch_unwind`](../../std/panic/fn.catch_unwind.html) and recovered
+//! from, or alternatively be resumed with
+//! [`resume_unwind`](../../std/panic/fn.resume_unwind.html). If the panic
+//! is not caught the thread will exit, but the panic may optionally be
+//! detected from a different thread with [`join`]. If the main thread panics
+//! without the panic being caught, the application will exit with a
+//! non-zero exit code.
 //!
 //! When the main thread of a Rust program terminates, the entire program shuts
 //! down, even if other threads are still running. However, this module provides
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 227db93cf65..5cb8e8694cf 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1987,6 +1987,15 @@ impl<'a> State<'a> {
             Fixity::None => (prec + 1, prec + 1),
         };
 
+        let left_prec = match (&lhs.node, op.node) {
+            // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
+            // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
+            // of `(x as i32) < ...`. We need to convince it _not_ to do that.
+            (&ast::ExprKind::Cast { .. }, ast::BinOpKind::Lt) |
+            (&ast::ExprKind::Cast { .. }, ast::BinOpKind::Shl) => parser::PREC_FORCE_PAREN,
+            _ => left_prec,
+        };
+
         self.print_expr_maybe_paren(lhs, left_prec)?;
         self.s.space()?;
         self.word_space(op.node.to_string())?;
diff --git a/src/test/compile-fail/regions-infer-at-fn-not-param.rs b/src/test/compile-fail/regions-infer-at-fn-not-param.rs
index 0c250e38258..ec73bf90b6e 100644
--- a/src/test/compile-fail/regions-infer-at-fn-not-param.rs
+++ b/src/test/compile-fail/regions-infer-at-fn-not-param.rs
@@ -21,7 +21,7 @@ struct not_parameterized2 {
 }
 
 fn take1<'a>(p: parameterized1) -> parameterized1<'a> { p }
-//~^ ERROR mismatched types
+//~^ ERROR explicit lifetime required in the type of `p`
 
 fn take3(p: not_parameterized1) -> not_parameterized1 { p }
 fn take4(p: not_parameterized2) -> not_parameterized2 { p }
diff --git a/src/test/pretty/cast-lt.pp b/src/test/pretty/cast-lt.pp
new file mode 100644
index 00000000000..b21158abfe5
--- /dev/null
+++ b/src/test/pretty/cast-lt.pp
@@ -0,0 +1,24 @@
+#![feature(prelude_import)]
+#![no_std]
+#[prelude_import]
+use std::prelude::v1::*;
+#[macro_use]
+extern crate std as std;
+// Copyright 2017 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.
+
+// pretty-compare-only
+// pretty-mode:expanded
+// pp-exact:cast-lt.pp
+
+macro_rules! negative(( $ e : expr ) => { $ e < 0 });
+
+fn main() { (1 as i32) < 0; }
+
diff --git a/src/test/pretty/cast-lt.rs b/src/test/pretty/cast-lt.rs
new file mode 100644
index 00000000000..87b5274545f
--- /dev/null
+++ b/src/test/pretty/cast-lt.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+// pretty-compare-only
+// pretty-mode:expanded
+// pp-exact:cast-lt.pp
+
+macro_rules! negative {
+      ($e:expr) => { $e < 0 }
+}
+
+fn main() {
+      negative!(1 as i32);
+}
+
diff --git a/src/test/rustdoc/playground-arg.rs b/src/test/rustdoc/playground-arg.rs
index f0d55ef6e9f..478477dea61 100644
--- a/src/test/rustdoc/playground-arg.rs
+++ b/src/test/rustdoc/playground-arg.rs
@@ -21,4 +21,4 @@
 pub fn dummy() {}
 
 // ensure that `extern crate foo;` was inserted into code snips automatically:
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=extern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D"]' "Run"
diff --git a/src/test/rustdoc/playground.rs b/src/test/rustdoc/playground.rs
index 9eb8dec51a7..8e193efaf85 100644
--- a/src/test/rustdoc/playground.rs
+++ b/src/test/rustdoc/playground.rs
@@ -34,6 +34,6 @@
 //! }
 //! ```
 
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=fn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A"]' "Run"
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=fn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run"
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A&version=nightly"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A&version=nightly"]' "Run"
diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs
new file mode 100644
index 00000000000..55752f753ef
--- /dev/null
+++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs
@@ -0,0 +1,30 @@
+// Copyright 2017 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.
+
+#[derive(Clone)]
+enum Foo<'a> {
+    Bar(&'a str),
+}
+
+impl<'a> Foo<'a> {
+    fn bar(&self, other: Foo) -> Foo<'a> {
+        match *self {
+            Foo::Bar(s) => {
+                if s == "test" {
+                    other
+                } else {
+                    self.clone()
+                }
+            }
+        }
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr
new file mode 100644
index 00000000000..d1660a620b6
--- /dev/null
+++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `other`
+  --> $DIR/ex1-return-one-existing-name-early-bound-in-struct.rs:21:21
+   |
+17 |     fn bar(&self, other: Foo) -> Foo<'a> {
+   |                   ----- consider changing the type of `other` to `Foo<'a>`
+...
+21 |                     other
+   |                     ^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-earlybound-regions.rs b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs
index 5d182008209..5d182008209 100644
--- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-earlybound-regions.rs
+++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs
diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr
new file mode 100644
index 00000000000..980f14a51d9
--- /dev/null
+++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `y`
+  --> $DIR/ex2a-push-one-existing-name-early-bound.rs:17:12
+   |
+13 | fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T)
+   |                                       - consider changing the type of `y` to `&'a T`
+...
+17 |     x.push(y);
+   |            ^ lifetime `'a` required
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-earlybound-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-earlybound-regions.stderr
deleted file mode 100644
index 58f2cb94cec..00000000000
--- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-earlybound-regions.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0623]: lifetime mismatch
-  --> $DIR/ex3-both-anon-regions-earlybound-regions.rs:17:12
-   |
-13 | fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T)
-   |                               -----      -- these two types are declared with different lifetimes...
-...
-17 |     x.push(y);
-   |            ^ ...but data from `y` flows into `x` here
-
-error: aborting due to previous error
-