about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-07-12 17:04:14 +0000
committerbors <bors@rust-lang.org>2017-07-12 17:04:14 +0000
commitf85579d4a2c342654f9b158fafd565eb159fdb59 (patch)
treee0ab8d41914e967769ee6422ad434d85c9fbcc31
parentb2b19ec92e233b7f91617e4cc2130e70d6e7a5fd (diff)
parent388fce9dab429e2cc90588727ae07a4c878bd7b3 (diff)
downloadrust-f85579d4a2c342654f9b158fafd565eb159fdb59.tar.gz
rust-f85579d4a2c342654f9b158fafd565eb159fdb59.zip
Auto merge of #43181 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 8 pull requests

- Successful merges: #42670, #42826, #43000, #43011, #43098, #43100, #43136, #43137
- Failed merges:
-rw-r--r--src/liballoc/boxed.rs4
-rw-r--r--src/libcore/cell.rs4
-rw-r--r--src/libcore/char.rs6
-rw-r--r--src/libcore/fmt/mod.rs9
-rw-r--r--src/libcore/hash/mod.rs7
-rw-r--r--src/libcore/macros.rs2
-rw-r--r--src/libcore/tuple.rs14
-rw-r--r--src/libproc_macro/lib.rs2
-rw-r--r--src/librustc/infer/error_reporting/mod.rs5
-rw-r--r--src/librustc/traits/error_reporting.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/libstd/error.rs2
-rw-r--r--src/libstd/io/buffered.rs6
-rw-r--r--src/libstd/macros.rs5
-rw-r--r--src/libstd/sync/mutex.rs2
-rw-r--r--src/libstd/sync/rwlock.rs4
-rw-r--r--src/libstd/sys/redox/ext/fs.rs15
-rw-r--r--src/libstd/sys/redox/fs.rs4
-rw-r--r--src/libstd_unicode/char.rs2
-rw-r--r--src/test/run-make/type-mismatch-same-crate-name/Makefile19
-rw-r--r--src/test/run-make/type-mismatch-same-crate-name/crateA.rs26
-rw-r--r--src/test/run-make/type-mismatch-same-crate-name/crateB.rs14
-rw-r--r--src/test/run-make/type-mismatch-same-crate-name/crateC.rs35
-rw-r--r--src/test/run-pass/unsized-tuple-impls.rs29
-rw-r--r--src/test/ui/on-unimplemented/bad-annotation.rs (renamed from src/test/compile-fail/on-unimplemented/bad-annotation.rs)0
-rw-r--r--src/test/ui/on-unimplemented/bad-annotation.stderr22
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.rs (renamed from src/test/compile-fail/on-unimplemented/multiple-impls.rs)0
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.stderr53
-rw-r--r--src/test/ui/on-unimplemented/on-impl.rs (renamed from src/test/compile-fail/on-unimplemented/on-impl.rs)0
-rw-r--r--src/test/ui/on-unimplemented/on-impl.stderr19
-rw-r--r--src/test/ui/on-unimplemented/on-trait.rs (renamed from src/test/compile-fail/on-unimplemented/on-trait.rs)9
-rw-r--r--src/test/ui/on-unimplemented/on-trait.stderr20
-rw-r--r--src/test/ui/on-unimplemented/slice-index.rs (renamed from src/test/compile-fail/on-unimplemented/slice-index.rs)0
-rw-r--r--src/test/ui/on-unimplemented/slice-index.stderr20
34 files changed, 338 insertions, 29 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 76cf10f0d55..94f5f4042e1 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -726,14 +726,14 @@ impl<T: Clone> Clone for Box<[T]> {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
+#[stable(feature = "box_borrow", since = "1.1.0")]
 impl<T: ?Sized> borrow::Borrow<T> for Box<T> {
     fn borrow(&self) -> &T {
         &**self
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
+#[stable(feature = "box_borrow", since = "1.1.0")]
 impl<T: ?Sized> borrow::BorrowMut<T> for Box<T> {
     fn borrow_mut(&mut self) -> &mut T {
         &mut **self
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 1eebf67ad04..35744f3f16b 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -942,7 +942,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Ref<'b, U>> for Ref<'b, T> {}
 
-#[stable(feature = "std_guard_impls", since = "1.20")]
+#[stable(feature = "std_guard_impls", since = "1.20.0")]
 impl<'a, T: ?Sized + fmt::Display> fmt::Display for Ref<'a, T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.value.fmt(f)
@@ -1041,7 +1041,7 @@ impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, T> {}
 
-#[stable(feature = "std_guard_impls", since = "1.20")]
+#[stable(feature = "std_guard_impls", since = "1.20.0")]
 impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.value.fmt(f)
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 44f5fdbf431..bb4cb0ac3b2 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -210,7 +210,7 @@ impl From<u8> for char {
 
 
 /// An error which can be returned when parsing a char.
-#[stable(feature = "char_from_str", since = "1.19.0")]
+#[stable(feature = "char_from_str", since = "1.20.0")]
 #[derive(Clone, Debug)]
 pub struct ParseCharError {
     kind: CharErrorKind,
@@ -237,7 +237,7 @@ enum CharErrorKind {
     TooManyChars,
 }
 
-#[stable(feature = "char_from_str", since = "1.19.0")]
+#[stable(feature = "char_from_str", since = "1.20.0")]
 impl fmt::Display for ParseCharError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.__description().fmt(f)
@@ -245,7 +245,7 @@ impl fmt::Display for ParseCharError {
 }
 
 
-#[stable(feature = "char_from_str", since = "1.19.0")]
+#[stable(feature = "char_from_str", since = "1.20.0")]
 impl FromStr for char {
     type Err = ParseCharError;
 
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index bcc6d53c81d..750e86114c4 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1627,13 +1627,13 @@ macro_rules! tuple {
     () => ();
     ( $($name:ident,)+ ) => (
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl<$($name:Debug),*> Debug for ($($name,)*) {
+        impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized {
             #[allow(non_snake_case, unused_assignments, deprecated)]
             fn fmt(&self, f: &mut Formatter) -> Result {
                 let mut builder = f.debug_tuple("");
                 let ($(ref $name,)*) = *self;
                 $(
-                    builder.field($name);
+                    builder.field(&$name);
                 )*
 
                 builder.finish()
@@ -1643,6 +1643,11 @@ macro_rules! tuple {
     )
 }
 
+macro_rules! last_type {
+    ($a:ident,) => { $a };
+    ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
+}
+
 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 3b304f4c479..2000ba91460 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -559,7 +559,7 @@ mod impls {
 
         ( $($name:ident)+) => (
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($name: Hash),*> Hash for ($($name,)*) {
+            impl<$($name: Hash),*> Hash for ($($name,)*) where last_type!($($name,)+): ?Sized {
                 #[allow(non_snake_case)]
                 fn hash<S: Hasher>(&self, state: &mut S) {
                     let ($(ref $name,)*) = *self;
@@ -569,6 +569,11 @@ mod impls {
         );
     }
 
+    macro_rules! last_type {
+        ($a:ident,) => { $a };
+        ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
+    }
+
     impl_hash_tuple! {}
     impl_hash_tuple! { A }
     impl_hash_tuple! { A B }
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 70820dce5f9..ae74016ad74 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -462,7 +462,7 @@ macro_rules! writeln {
 ///
 /// # Panics
 ///
-/// This will always panic.
+/// This will always [panic!](macro.panic.html)
 ///
 /// # Examples
 ///
diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs
index 55d55079ddc..47e9c7c9038 100644
--- a/src/libcore/tuple.rs
+++ b/src/libcore/tuple.rs
@@ -29,7 +29,7 @@ macro_rules! tuple_impls {
             }
 
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
+            impl<$($T:PartialEq),+> PartialEq for ($($T,)+) where last_type!($($T,)+): ?Sized {
                 #[inline]
                 fn eq(&self, other: &($($T,)+)) -> bool {
                     $(self.$idx == other.$idx)&&+
@@ -41,10 +41,11 @@ macro_rules! tuple_impls {
             }
 
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T:Eq),+> Eq for ($($T,)+) {}
+            impl<$($T:Eq),+> Eq for ($($T,)+) where last_type!($($T,)+): ?Sized {}
 
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
+            impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+)
+                    where last_type!($($T,)+): ?Sized {
                 #[inline]
                 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
                     lexical_partial_cmp!($(self.$idx, other.$idx),+)
@@ -68,7 +69,7 @@ macro_rules! tuple_impls {
             }
 
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T:Ord),+> Ord for ($($T,)+) {
+            impl<$($T:Ord),+> Ord for ($($T,)+) where last_type!($($T,)+): ?Sized {
                 #[inline]
                 fn cmp(&self, other: &($($T,)+)) -> Ordering {
                     lexical_cmp!($(self.$idx, other.$idx),+)
@@ -118,6 +119,11 @@ macro_rules! lexical_cmp {
     ($a:expr, $b:expr) => { ($a).cmp(&$b) };
 }
 
+macro_rules! last_type {
+    ($a:ident,) => { $a };
+    ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
+}
+
 tuple_impls! {
     Tuple1 {
         (0) -> A
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index 06f9634d706..357e2ab853c 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -303,7 +303,7 @@ impl Literal {
         Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), None))
     }
 
-    int_literals!(u8, i8, u16, i16, u32, i32, u64, i64);
+    int_literals!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);
     fn typed_integer(n: i128, kind: &'static str) -> Literal {
         Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())),
                                Some(Symbol::intern(kind))))
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 278ec03c753..95722a93bed 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -347,9 +347,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
                 let exp_path = self.tcx.item_path_str(did1);
                 let found_path = self.tcx.item_path_str(did2);
+                let exp_abs_path = self.tcx.absolute_item_path_str(did1);
+                let found_abs_path = self.tcx.absolute_item_path_str(did2);
                 // We compare strings because DefPath can be different
                 // for imported and non-imported crates
-                if exp_path == found_path {
+                if exp_path == found_path
+                || exp_abs_path == found_abs_path {
                     let crate_name = self.tcx.sess.cstore.crate_name(did1.krate);
                     err.span_note(sp, &format!("Perhaps two different versions \
                                                 of crate `{}` are being used?",
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 0bf0e21baaf..c02d1394f6b 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -330,6 +330,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             .filter(|a| a.check_name("rustc_on_unimplemented"))
             .next()
         {
+            let name = self.tcx.item_name(def_id).as_str();
             let err_sp = item.span.substitute_dummy(span);
             let trait_str = self.tcx.item_path_str(trait_ref.def_id);
             if let Some(istring) = item.value_str() {
@@ -347,6 +348,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                         Piece::NextArgument(a) => match a.position {
                             Position::ArgumentNamed(s) => match generic_map.get(s) {
                                 Some(val) => Some(val),
+                                None if s == name => {
+                                    Some(&trait_str)
+                                }
                                 None => {
                                     span_err!(self.tcx.sess, err_sp, E0272,
                                               "the #[rustc_on_unimplemented] attribute on trait \
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 6e2c36c86a3..cdbe5e14e90 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1167,6 +1167,7 @@ fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }) {
         if let Some(istring) = attr.value_str() {
             let istring = istring.as_str();
+            let name = tcx.item_name(def_id).as_str();
             let parser = Parser::new(&istring);
             let types = &generics.types;
             for token in parser {
@@ -1175,13 +1176,14 @@ fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     Piece::NextArgument(a) => match a.position {
                         // `{Self}` is allowed
                         Position::ArgumentNamed(s) if s == "Self" => (),
+                        // `{ThisTraitsName}` is allowed
+                        Position::ArgumentNamed(s) if s == name => (),
                         // So is `{A}` if A is a type parameter
                         Position::ArgumentNamed(s) => match types.iter().find(|t| {
                             t.name == s
                         }) {
                             Some(_) => (),
                             None => {
-                                let name = tcx.item_name(def_id);
                                 span_err!(tcx.sess, attr.span, E0230,
                                                  "there is no type parameter \
                                                           {} on trait {}",
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index d77f817659c..d1c2bfb96b3 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -340,7 +340,7 @@ impl Error for char::CharTryFromError {
     }
 }
 
-#[stable(feature = "char_from_str", since = "1.19.0")]
+#[stable(feature = "char_from_str", since = "1.20.0")]
 impl Error for char::ParseCharError {
     fn description(&self) -> &str {
         self.__description()
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 296ee78aadb..1b832453523 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -276,7 +276,10 @@ impl<R: Seek> Seek for BufReader<R> {
 /// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying
 /// writer in large, infrequent batches.
 ///
-/// The buffer will be written out when the writer is dropped.
+/// When the `BufWriter` is dropped, the contents of its buffer will be written
+/// out. However, any errors that happen in the process of flushing the buffer
+/// when the writer is dropped will be ignored. Code that wishes to handle such
+/// errors must manually call [`flush`] before the writer is dropped.
 ///
 /// # Examples
 ///
@@ -316,6 +319,7 @@ impl<R: Seek> Seek for BufReader<R> {
 /// [`Write`]: ../../std/io/trait.Write.html
 /// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write
 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+/// [`flush`]: #method.flush
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufWriter<W: Write> {
     inner: Option<W>,
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 6eb9faacf7f..6ad22820a7d 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -24,6 +24,11 @@
 /// The multi-argument form of this macro panics with a string and has the
 /// `format!` syntax for building a string.
 ///
+/// # Current implementation
+///
+/// If the main thread panics it will terminate all your threads and end your
+/// program with code `101`.
+///
 /// # Examples
 ///
 /// ```should_panic
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index fc6c7de9ef0..62d8de18f4b 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -440,7 +440,7 @@ impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
     }
 }
 
-#[stable(feature = "std_guard_impls", since = "1.20")]
+#[stable(feature = "std_guard_impls", since = "1.20.0")]
 impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         (**self).fmt(f)
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 944801e8a3b..5c5231f4e84 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -370,7 +370,7 @@ impl<'a, T: fmt::Debug> fmt::Debug for RwLockReadGuard<'a, T> {
     }
 }
 
-#[stable(feature = "std_guard_impls", since = "1.20")]
+#[stable(feature = "std_guard_impls", since = "1.20.0")]
 impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'a, T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         (**self).fmt(f)
@@ -386,7 +386,7 @@ impl<'a, T: fmt::Debug> fmt::Debug for RwLockWriteGuard<'a, T> {
     }
 }
 
-#[stable(feature = "std_guard_impls", since = "1.20")]
+#[stable(feature = "std_guard_impls", since = "1.20.0")]
 impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'a, T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         (**self).fmt(f)
diff --git a/src/libstd/sys/redox/ext/fs.rs b/src/libstd/sys/redox/ext/fs.rs
index 4437cf43920..9a0d1e06da3 100644
--- a/src/libstd/sys/redox/ext/fs.rs
+++ b/src/libstd/sys/redox/ext/fs.rs
@@ -177,6 +177,8 @@ pub trait MetadataExt {
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mode(&self) -> u32;
     #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn nlink(&self) -> u64;
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn uid(&self) -> u32;
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn gid(&self) -> u32;
@@ -194,6 +196,10 @@ pub trait MetadataExt {
     fn ctime(&self) -> i64;
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ctime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn blksize(&self) -> u64;
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn blocks(&self) -> u64;
 }
 
 #[stable(feature = "metadata_ext", since = "1.1.0")]
@@ -207,6 +213,9 @@ impl MetadataExt for fs::Metadata {
     fn mode(&self) -> u32 {
         self.as_inner().as_inner().st_mode as u32
     }
+    fn nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
     fn uid(&self) -> u32 {
         self.as_inner().as_inner().st_uid as u32
     }
@@ -234,6 +243,12 @@ impl MetadataExt for fs::Metadata {
     fn ctime_nsec(&self) -> i64 {
         self.as_inner().as_inner().st_ctime_nsec as i64
     }
+    fn blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+    fn blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
 }
 
 /// Add special Redox types (block/char device, fifo and socket)
diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs
index 4dcaec6edb8..87e50c40148 100644
--- a/src/libstd/sys/redox/fs.rs
+++ b/src/libstd/sys/redox/fs.rs
@@ -119,10 +119,10 @@ impl FilePermissions {
 impl FileType {
     pub fn is_dir(&self) -> bool { self.is(syscall::MODE_DIR) }
     pub fn is_file(&self) -> bool { self.is(syscall::MODE_FILE) }
-    pub fn is_symlink(&self) -> bool { false /*FIXME: Implement symlink mode*/ }
+    pub fn is_symlink(&self) -> bool { self.is(syscall::MODE_SYMLINK) }
 
     pub fn is(&self, mode: u16) -> bool {
-        self.mode & (syscall::MODE_DIR | syscall::MODE_FILE) == mode
+        self.mode & syscall::MODE_TYPE == mode
     }
 }
 
diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs
index d4d8993efb3..d6836418b4b 100644
--- a/src/libstd_unicode/char.rs
+++ b/src/libstd_unicode/char.rs
@@ -38,7 +38,7 @@ use tables::{conversions, derived_property, general_category, property};
 pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::char::{EscapeDebug, EscapeDefault, EscapeUnicode};
-#[stable(feature = "char_from_str", since = "1.19.0")]
+#[stable(feature = "char_from_str", since = "1.20.0")]
 pub use core::char::ParseCharError;
 
 // unstable reexports
diff --git a/src/test/run-make/type-mismatch-same-crate-name/Makefile b/src/test/run-make/type-mismatch-same-crate-name/Makefile
new file mode 100644
index 00000000000..1044d73fd1a
--- /dev/null
+++ b/src/test/run-make/type-mismatch-same-crate-name/Makefile
@@ -0,0 +1,19 @@
+-include ../tools.mk
+
+all:
+	# compile two different versions of crateA
+	$(RUSTC) --crate-type=rlib crateA.rs -C metadata=-1 -C extra-filename=-1
+	$(RUSTC) --crate-type=rlib crateA.rs -C metadata=-2 -C extra-filename=-2
+	# make crateB depend on version 1 of crateA
+	$(RUSTC) --crate-type=rlib crateB.rs --extern crateA=$(TMPDIR)/libcrateA-1.rlib
+	# make crateC depend on version 2 of crateA
+	$(RUSTC) crateC.rs --extern crateA=$(TMPDIR)/libcrateA-2.rlib 2>&1 | \
+		tr -d '\r\n' | grep \
+	"mismatched types.*\
+	crateB::try_foo(foo2);.*\
+	expected struct \`crateA::foo::Foo\`, found struct \`crateA::Foo\`.*\
+	different versions of crate \`crateA\`.*\
+	mismatched types.*\
+	crateB::try_bar(bar2);.*\
+	expected trait \`crateA::bar::Bar\`, found trait \`crateA::Bar\`.*\
+	different versions of crate \`crateA\`"
diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateA.rs b/src/test/run-make/type-mismatch-same-crate-name/crateA.rs
new file mode 100644
index 00000000000..e40266bb4cd
--- /dev/null
+++ b/src/test/run-make/type-mismatch-same-crate-name/crateA.rs
@@ -0,0 +1,26 @@
+// 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.
+
+mod foo {
+    pub struct Foo;
+}
+
+mod bar {
+    pub trait Bar{}
+
+    pub fn bar() -> Box<Bar> {
+        unimplemented!()
+    }
+}
+
+// This makes the publicly accessible path
+// differ from the internal one.
+pub use foo::Foo;
+pub use bar::{Bar, bar};
diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateB.rs b/src/test/run-make/type-mismatch-same-crate-name/crateB.rs
new file mode 100644
index 00000000000..da4ea1c9387
--- /dev/null
+++ b/src/test/run-make/type-mismatch-same-crate-name/crateB.rs
@@ -0,0 +1,14 @@
+// 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.
+
+extern crate crateA;
+
+pub fn try_foo(x: crateA::Foo){}
+pub fn try_bar(x: Box<crateA::Bar>){}
diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateC.rs b/src/test/run-make/type-mismatch-same-crate-name/crateC.rs
new file mode 100644
index 00000000000..da869d2145f
--- /dev/null
+++ b/src/test/run-make/type-mismatch-same-crate-name/crateC.rs
@@ -0,0 +1,35 @@
+// 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.
+
+// This tests the extra note reported when a type error deals with
+// seemingly identical types.
+// The main use case of this error is when there are two crates
+// (generally different versions of the same crate) with the same name
+// causing a type mismatch.
+
+// The test is nearly the same as the one in
+// compile-fail/type-mismatch-same-crate-name.rs
+// but deals with the case where one of the crates
+// is only introduced as an indirect dependency.
+// and the type is accessed via a reexport.
+// This is similar to how the error can be introduced
+// when using cargo's automatic dependency resolution.
+
+extern crate crateA;
+
+fn main() {
+    let foo2 = crateA::Foo;
+    let bar2 = crateA::bar();
+    {
+        extern crate crateB;
+        crateB::try_foo(foo2);
+        crateB::try_bar(bar2);
+    }
+}
diff --git a/src/test/run-pass/unsized-tuple-impls.rs b/src/test/run-pass/unsized-tuple-impls.rs
new file mode 100644
index 00000000000..591b19f89e8
--- /dev/null
+++ b/src/test/run-pass/unsized-tuple-impls.rs
@@ -0,0 +1,29 @@
+// 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.
+
+#![feature(unsized_tuple_coercion)]
+
+use std::collections::HashSet;
+
+fn main() {
+    let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]);
+    let y : &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]);
+    let mut a = [y, x];
+    a.sort();
+    assert_eq!(a, [x, y]);
+
+    assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]");
+
+    let mut h = HashSet::new();
+    h.insert(x);
+    h.insert(y);
+    assert!(h.contains(x));
+    assert!(h.contains(y));
+}
diff --git a/src/test/compile-fail/on-unimplemented/bad-annotation.rs b/src/test/ui/on-unimplemented/bad-annotation.rs
index 8580749084d..8580749084d 100644
--- a/src/test/compile-fail/on-unimplemented/bad-annotation.rs
+++ b/src/test/ui/on-unimplemented/bad-annotation.rs
diff --git a/src/test/ui/on-unimplemented/bad-annotation.stderr b/src/test/ui/on-unimplemented/bad-annotation.stderr
new file mode 100644
index 00000000000..8599477e8ed
--- /dev/null
+++ b/src/test/ui/on-unimplemented/bad-annotation.stderr
@@ -0,0 +1,22 @@
+error[E0232]: this attribute must have a value
+  --> $DIR/bad-annotation.rs:26:1
+   |
+26 | #[rustc_on_unimplemented] //~ ERROR this attribute must have a value
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ attribute requires a value
+   |
+   = note: eg `#[rustc_on_unimplemented = "foo"]`
+
+error[E0230]: there is no type parameter C on trait BadAnnotation2
+  --> $DIR/bad-annotation.rs:30:1
+   |
+30 | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0231]: only named substitution parameters are allowed
+  --> $DIR/bad-annotation.rs:35:1
+   |
+35 | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/compile-fail/on-unimplemented/multiple-impls.rs b/src/test/ui/on-unimplemented/multiple-impls.rs
index 15375936b89..15375936b89 100644
--- a/src/test/compile-fail/on-unimplemented/multiple-impls.rs
+++ b/src/test/ui/on-unimplemented/multiple-impls.rs
diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr
new file mode 100644
index 00000000000..a1fa8b720a8
--- /dev/null
+++ b/src/test/ui/on-unimplemented/multiple-impls.stderr
@@ -0,0 +1,53 @@
+error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
+  --> $DIR/multiple-impls.rs:43:5
+   |
+43 |     Index::index(&[] as &[i32], 2u32);
+   |     ^^^^^^^^^^^^ trait message
+   |
+   = help: the trait `Index<u32>` is not implemented for `[i32]`
+   = note: required by `Index::index`
+
+error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
+  --> $DIR/multiple-impls.rs:43:5
+   |
+43 |     Index::index(&[] as &[i32], 2u32);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait message
+   |
+   = help: the trait `Index<u32>` is not implemented for `[i32]`
+
+error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
+  --> $DIR/multiple-impls.rs:49:5
+   |
+49 |     Index::index(&[] as &[i32], Foo(2u32));
+   |     ^^^^^^^^^^^^ on impl for Foo
+   |
+   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
+   = note: required by `Index::index`
+
+error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
+  --> $DIR/multiple-impls.rs:49:5
+   |
+49 |     Index::index(&[] as &[i32], Foo(2u32));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo
+   |
+   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
+
+error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
+  --> $DIR/multiple-impls.rs:55:5
+   |
+55 |     Index::index(&[] as &[i32], Bar(2u32));
+   |     ^^^^^^^^^^^^ on impl for Bar
+   |
+   = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
+   = note: required by `Index::index`
+
+error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
+  --> $DIR/multiple-impls.rs:55:5
+   |
+55 |     Index::index(&[] as &[i32], Bar(2u32));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
+   |
+   = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/compile-fail/on-unimplemented/on-impl.rs b/src/test/ui/on-unimplemented/on-impl.rs
index 66d612baab4..66d612baab4 100644
--- a/src/test/compile-fail/on-unimplemented/on-impl.rs
+++ b/src/test/ui/on-unimplemented/on-impl.rs
diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr
new file mode 100644
index 00000000000..c8c06bf44fd
--- /dev/null
+++ b/src/test/ui/on-unimplemented/on-impl.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
+  --> $DIR/on-impl.rs:32:5
+   |
+32 |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
+   |     ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
+   |
+   = help: the trait `Index<u32>` is not implemented for `[i32]`
+   = note: required by `Index::index`
+
+error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
+  --> $DIR/on-impl.rs:32:5
+   |
+32 |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
+   |
+   = help: the trait `Index<u32>` is not implemented for `[i32]`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/compile-fail/on-unimplemented/on-trait.rs b/src/test/ui/on-unimplemented/on-trait.rs
index a8daef356a5..ed7ec9b1436 100644
--- a/src/test/compile-fail/on-unimplemented/on-trait.rs
+++ b/src/test/ui/on-unimplemented/on-trait.rs
@@ -11,9 +11,12 @@
 
 #![feature(on_unimplemented)]
 
-#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
-trait Foo<Bar, Baz, Quux>
-{}
+pub mod Bar {
+  #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"]
+  pub trait Foo<Bar, Baz, Quux> {}
+}
+
+use Bar::Foo;
 
 fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
     panic!()
diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr
new file mode 100644
index 00000000000..84986c1ecfd
--- /dev/null
+++ b/src/test/ui/on-unimplemented/on-trait.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `std::option::Option<std::vec::Vec<u8>>: MyFromIterator<&u8>` is not satisfied
+  --> $DIR/on-trait.rs:37:30
+   |
+37 |     let y: Option<Vec<u8>> = collect(x.iter()); // this should give approximately the same error for x.iter().collect()
+   |                              ^^^^^^^ a collection of type `std::option::Option<std::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
+   |
+   = help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option<std::vec::Vec<u8>>`
+   = note: required by `collect`
+
+error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not satisfied
+  --> $DIR/on-trait.rs:42:21
+   |
+42 |     let x: String = foobar(); //~ ERROR
+   |                     ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo`
+   |
+   = help: the trait `Bar::Foo<u8, _, u32>` is not implemented for `std::string::String`
+   = note: required by `foobar`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/compile-fail/on-unimplemented/slice-index.rs b/src/test/ui/on-unimplemented/slice-index.rs
index 5d30c2e982e..5d30c2e982e 100644
--- a/src/test/compile-fail/on-unimplemented/slice-index.rs
+++ b/src/test/ui/on-unimplemented/slice-index.rs
diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr
new file mode 100644
index 00000000000..68789f77f75
--- /dev/null
+++ b/src/test/ui/on-unimplemented/slice-index.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `i32: std::slice::SliceIndex<[i32]>` is not satisfied
+  --> $DIR/slice-index.rs:21:5
+   |
+21 |     x[1i32]; //~ ERROR E0277
+   |     ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
+   |
+   = help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32`
+   = note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[i32]`
+
+error[E0277]: the trait bound `std::ops::RangeTo<i32>: std::slice::SliceIndex<[i32]>` is not satisfied
+  --> $DIR/slice-index.rs:24:5
+   |
+24 |     x[..1i32]; //~ ERROR E0277
+   |     ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
+   |
+   = help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `std::ops::RangeTo<i32>`
+   = note: required because of the requirements on the impl of `std::ops::Index<std::ops::RangeTo<i32>>` for `[i32]`
+
+error: aborting due to 2 previous errors
+