about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-02-07 17:51:52 +0000
committerbors <bors@rust-lang.org>2018-02-07 17:51:52 +0000
commit29c8276cee4a0eab7e0634ff25c6b47bd9f87c6c (patch)
treeaabb7278f081c3c90cea9e0337779739805408a9
parentfee39ba8bd98f5b93c60de51336830fa7f0b9d97 (diff)
parent732c83007c9069c6dd33a5dc98e62337dca014bd (diff)
downloadrust-29c8276cee4a0eab7e0634ff25c6b47bd9f87c6c.tar.gz
rust-29c8276cee4a0eab7e0634ff25c6b47bd9f87c6c.zip
Auto merge of #48053 - Manishearth:rollup, r=Manishearth
Rollup of 10 pull requests

- Successful merges: #47613, #47631, #47810, #47883, #47922, #47944, #48014, #48018, #48020, #48028
- Failed merges:
-rw-r--r--src/libcore/fmt/mod.rs17
-rw-r--r--src/libcore/iter/iterator.rs9
-rw-r--r--src/libcore/iter/mod.rs3
-rw-r--r--src/libcore/iter/range.rs3
-rw-r--r--src/libcore/iter/sources.rs3
-rw-r--r--src/libcore/iter/traits.rs6
-rw-r--r--src/libcore/ops/arith.rs40
-rw-r--r--src/libcore/ops/bit.rs30
-rw-r--r--src/libcore/ptr.rs87
-rw-r--r--src/libcore/tests/iter.rs43
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/liveness.rs63
-rw-r--r--src/librustc/session/config.rs45
-rw-r--r--src/librustc/session/mod.rs7
-rw-r--r--src/librustc/traits/error_reporting.rs34
-rw-r--r--src/librustc/traits/on_unimplemented.rs37
-rw-r--r--src/librustc/util/nodemap.rs4
-rw-r--r--src/librustc_binaryen/BinaryenWrapper.cpp34
-rw-r--r--src/librustc_binaryen/lib.rs22
-rw-r--r--src/librustc_mir/transform/promote_consts.rs19
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs45
-rw-r--r--src/librustc_trans/back/write.rs18
-rw-r--r--src/librustc_typeck/check/method/probe.rs18
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/collect.rs36
-rw-r--r--src/librustc_typeck/diagnostics.rs49
-rw-r--r--src/librustdoc/html/static/main.js26
-rw-r--r--src/librustdoc/html/static/rustdoc.css31
-rw-r--r--src/librustdoc/html/static/themes/dark.css2
-rw-r--r--src/libstd/panic.rs2
-rw-r--r--src/libsyntax/parse/parser.rs31
-rw-r--r--src/test/codegen/repeat-trusted-len.rs23
-rw-r--r--src/test/compile-fail/const-eval-overflow-4b.rs2
-rw-r--r--src/test/compile-fail/dst-bad-assign-3.rs2
-rw-r--r--src/test/compile-fail/epoch-raw-pointer-method-2015.rs23
-rw-r--r--src/test/compile-fail/epoch-raw-pointer-method-2018.rs22
-rw-r--r--src/test/compile-fail/private-in-public-warn.rs2
-rw-r--r--src/test/compile-fail/rustc-args-required-const.rs36
-rw-r--r--src/test/compile-fail/ufcs-qpath-self-mismatch.rs2
-rw-r--r--src/test/ui/impl-trait/equality.rs2
-rw-r--r--src/test/ui/impl-trait/equality.stderr2
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs34
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr40
-rw-r--r--src/test/ui/mismatched_types/binops.rs8
-rw-r--r--src/test/ui/mismatched_types/binops.stderr16
-rw-r--r--src/test/ui/on-unimplemented/auxiliary/no_debug.rs14
-rw-r--r--src/test/ui/on-unimplemented/no-debug.rs27
-rw-r--r--src/test/ui/on-unimplemented/no-debug.stderr38
-rw-r--r--src/test/ui/param-bounds-ignored.rs33
-rw-r--r--src/test/ui/param-bounds-ignored.stderr18
-rw-r--r--src/test/ui/span/issue-24690.stderr3
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.rs27
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.stderr15
-rw-r--r--src/test/ui/span/multiline-span-simple.rs2
-rw-r--r--src/test/ui/span/multiline-span-simple.stderr4
-rw-r--r--src/test/ui/suggestions/for-c-in-str.stderr2
56 files changed, 983 insertions, 181 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 6c8a1c3062b..8ad5a9861a0 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -530,9 +530,12 @@ impl<'a> Display for Arguments<'a> {
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \
-                            defined in your crate, add `#[derive(Debug)]` or \
-                            manually implement it"]
+#[rustc_on_unimplemented(
+    on(crate_local, label="`{Self}` cannot be formatted using `:?`; \
+                            add `#[derive(Debug)]` or manually implement `{Debug}`"),
+    message="`{Self}` doesn't implement `{Debug}`",
+    label="`{Self}` cannot be formatted using `:?` because it doesn't implement `{Debug}`",
+)]
 #[lang = "debug_trait"]
 pub trait Debug {
     /// Formats the value using the given formatter.
@@ -593,9 +596,11 @@ pub trait Debug {
 ///
 /// println!("The origin is: {}", origin);
 /// ```
-#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \
-                            formatter; try using `:?` instead if you are using \
-                            a format string"]
+#[rustc_on_unimplemented(
+    message="`{Self}` doesn't implement `{Display}`",
+    label="`{Self}` cannot be formatted with the default formatter; \
+           try using `:?` instead if you are using a format string",
+)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Display {
     /// Formats the value using the given formatter.
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 35cd7441c66..296fb8733ba 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -28,8 +28,13 @@ fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
 /// [module-level documentation]: index.html
 /// [impl]: index.html#implementing-iterator
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \
-                            `.iter()` or a similar method"]
+#[rustc_on_unimplemented(
+    on(
+        _Self="&str",
+        label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
+    ),
+    label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method"
+)]
 #[doc(spotlight)]
 pub trait Iterator {
     /// The type of the elements being iterated over.
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 7314fac282b..bf8367d85fd 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -2322,6 +2322,9 @@ impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
 #[unstable(feature = "fused", issue = "35602")]
 impl<I> FusedIterator for Take<I> where I: FusedIterator {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
+
 /// An iterator to maintain state while iterating another iterator.
 ///
 /// This `struct` is created by the [`scan`] method on [`Iterator`]. See its
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index 3b034efcce1..5b4dc9b2c9a 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -325,6 +325,9 @@ impl<A: Step> Iterator for ops::RangeFrom<A> {
 #[unstable(feature = "fused", issue = "35602")]
 impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: Step> TrustedLen for ops::RangeFrom<A> {}
+
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<A: Step> Iterator for ops::RangeInclusive<A> {
     type Item = A;
diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs
index b405f35d5e4..b05a893e661 100644
--- a/src/libcore/iter/sources.rs
+++ b/src/libcore/iter/sources.rs
@@ -44,6 +44,9 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
 #[unstable(feature = "fused", issue = "35602")]
 impl<A: Clone> FusedIterator for Repeat<A> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
+
 /// Creates a new iterator that endlessly repeats a single element.
 ///
 /// The `repeat()` function repeats a single value over and over and over and
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 11e668d228c..be4889f2487 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -970,9 +970,11 @@ impl<'a, I: FusedIterator + ?Sized> FusedIterator for &'a mut I {}
 /// The iterator reports a size hint where it is either exact
 /// (lower bound is equal to upper bound), or the upper bound is [`None`].
 /// The upper bound must only be [`None`] if the actual iterator length is
-/// larger than [`usize::MAX`].
+/// larger than [`usize::MAX`]. In that case, the lower bound must be
+/// [`usize::MAX`], resulting in a [`.size_hint`] of `(usize::MAX, None)`.
 ///
-/// The iterator must produce exactly the number of elements it reported.
+/// The iterator must produce exactly the number of elements it reported
+/// or diverge before reaching the end.
 ///
 /// # Safety
 ///
diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs
index 8b3d662a6db..d0d0c09869e 100644
--- a/src/libcore/ops/arith.rs
+++ b/src/libcore/ops/arith.rs
@@ -75,7 +75,18 @@
 /// ```
 #[lang = "add"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} + {RHS}`"]
+#[rustc_on_unimplemented(
+    on(
+        all(_Self="{integer}", RHS="{float}"),
+        message="cannot add a float to an integer",
+    ),
+    on(
+        all(_Self="{float}", RHS="{integer}"),
+        message="cannot add an integer to a float",
+    ),
+    message="cannot add `{RHS}` to `{Self}`",
+    label="no implementation for `{Self} + {RHS}`",
+)]
 pub trait Add<RHS=Self> {
     /// The resulting type after applying the `+` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -170,7 +181,8 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 #[lang = "sub"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} - {RHS}`"]
+#[rustc_on_unimplemented(message="cannot substract `{RHS}` from `{Self}`",
+                         label="no implementation for `{Self} - {RHS}`")]
 pub trait Sub<RHS=Self> {
     /// The resulting type after applying the `-` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -287,7 +299,8 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 #[lang = "mul"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} * {RHS}`"]
+#[rustc_on_unimplemented(message="cannot multiply `{RHS}` to `{Self}`",
+                         label="no implementation for `{Self} * {RHS}`")]
 pub trait Mul<RHS=Self> {
     /// The resulting type after applying the `*` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -408,7 +421,8 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 #[lang = "div"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} / {RHS}`"]
+#[rustc_on_unimplemented(message="cannot divide `{Self}` by `{RHS}`",
+                         label="no implementation for `{Self} / {RHS}`")]
 pub trait Div<RHS=Self> {
     /// The resulting type after applying the `/` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -490,7 +504,8 @@ div_impl_float! { f32 f64 }
 /// ```
 #[lang = "rem"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} % {RHS}`"]
+#[rustc_on_unimplemented(message="cannot mod `{Self}` by `{RHS}`",
+                         label="no implementation for `{Self} % {RHS}`")]
 pub trait Rem<RHS=Self> {
     /// The resulting type after applying the `%` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -647,7 +662,8 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 #[lang = "add_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} += {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot add-assign `{Rhs}` to `{Self}`",
+                         label="no implementation for `{Self} += {Rhs}`")]
 pub trait AddAssign<Rhs=Self> {
     /// Performs the `+=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -700,7 +716,8 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 #[lang = "sub_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} -= {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot substract-assign `{Rhs}` from `{Self}`",
+                         label="no implementation for `{Self} -= {Rhs}`")]
 pub trait SubAssign<Rhs=Self> {
     /// Performs the `-=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -744,7 +761,8 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 #[lang = "mul_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} *= {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot multiply-assign `{Rhs}` to `{Self}`",
+                         label="no implementation for `{Self} *= {Rhs}`")]
 pub trait MulAssign<Rhs=Self> {
     /// Performs the `*=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -788,7 +806,8 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 #[lang = "div_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} /= {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot divide-assign `{Self}` by `{Rhs}`",
+                         label="no implementation for `{Self} /= {Rhs}`")]
 pub trait DivAssign<Rhs=Self> {
     /// Performs the `/=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -835,7 +854,8 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 #[lang = "rem_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} %= {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot mod-assign `{Self}` by `{Rhs}``",
+                         label="no implementation for `{Self} %= {Rhs}`")]
 pub trait RemAssign<Rhs=Self> {
     /// Performs the `%=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs
index 7ac5fc4debf..a0ecd6cf75c 100644
--- a/src/libcore/ops/bit.rs
+++ b/src/libcore/ops/bit.rs
@@ -120,7 +120,8 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 /// ```
 #[lang = "bitand"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} & {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} & {RHS}`",
+                         label="no implementation for `{Self} & {RHS}`")]
 pub trait BitAnd<RHS=Self> {
     /// The resulting type after applying the `&` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -201,7 +202,8 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 /// ```
 #[lang = "bitor"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} | {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} | {RHS}`",
+                         label="no implementation for `{Self} | {RHS}`")]
 pub trait BitOr<RHS=Self> {
     /// The resulting type after applying the `|` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -285,7 +287,8 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 /// ```
 #[lang = "bitxor"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} ^ {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} ^ {RHS}`",
+                         label="no implementation for `{Self} ^ {RHS}`")]
 pub trait BitXor<RHS=Self> {
     /// The resulting type after applying the `^` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -365,7 +368,8 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 /// ```
 #[lang = "shl"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} << {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} << {RHS}`",
+                         label="no implementation for `{Self} << {RHS}`")]
 pub trait Shl<RHS> {
     /// The resulting type after applying the `<<` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -466,7 +470,8 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
 /// ```
 #[lang = "shr"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} >> {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} >> {RHS}`",
+                         label="no implementation for `{Self} >> {RHS}`")]
 pub trait Shr<RHS> {
     /// The resulting type after applying the `>>` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -579,7 +584,8 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
 /// ```
 #[lang = "bitand_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} &= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} &= {Rhs}`",
+                         label="no implementation for `{Self} &= {Rhs}`")]
 pub trait BitAndAssign<Rhs=Self> {
     /// Performs the `&=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -626,7 +632,8 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 /// ```
 #[lang = "bitor_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} |= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} |= {Rhs}`",
+                         label="no implementation for `{Self} |= {Rhs}`")]
 pub trait BitOrAssign<Rhs=Self> {
     /// Performs the `|=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -673,7 +680,8 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 /// ```
 #[lang = "bitxor_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} ^= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} ^= {Rhs}`",
+                         label="no implementation for `{Self} ^= {Rhs}`")]
 pub trait BitXorAssign<Rhs=Self> {
     /// Performs the `^=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -718,7 +726,8 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 /// ```
 #[lang = "shl_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} <<= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} <<= {Rhs}`",
+                         label="no implementation for `{Self} <<= {Rhs}`")]
 pub trait ShlAssign<Rhs> {
     /// Performs the `<<=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -784,7 +793,8 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
 /// ```
 #[lang = "shr_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} >>= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} >>= {Rhs}`",
+                         label="no implementation for `{Self} >>= {Rhs}`")]
 pub trait ShrAssign<Rhs=Self> {
     /// Performs the `>>=` operation.
     #[stable(feature = "op_assign_traits", since = "1.8.0")]
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index fab5832d905..3d84e910fe6 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -2461,7 +2461,7 @@ impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
 }
 
 /// Previous name of `NonNull`.
-#[rustc_deprecated(since = "1.24", reason = "renamed to `NonNull`")]
+#[rustc_deprecated(since = "1.25.0", reason = "renamed to `NonNull`")]
 #[unstable(feature = "shared", issue = "27730")]
 pub type Shared<T> = NonNull<T>;
 
@@ -2482,26 +2482,19 @@ pub type Shared<T> = NonNull<T>;
 /// Usually this won't be necessary; covariance is correct for most safe abstractions,
 /// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they
 /// provide a public API that follows the normal shared XOR mutable rules of Rust.
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
 pub struct NonNull<T: ?Sized> {
     pointer: NonZero<*const T>,
 }
 
-#[stable(feature = "nonnull", since = "1.24.0")]
-impl<T: ?Sized> fmt::Debug for NonNull<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Pointer::fmt(&self.as_ptr(), f)
-    }
-}
-
 /// `NonNull` pointers are not `Send` because the data they reference may be aliased.
 // NB: This impl is unnecessary, but should provide better error messages.
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> !Send for NonNull<T> { }
 
 /// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
 // NB: This impl is unnecessary, but should provide better error messages.
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> !Sync for NonNull<T> { }
 
 impl<T: Sized> NonNull<T> {
@@ -2509,7 +2502,7 @@ impl<T: Sized> NonNull<T> {
     ///
     /// This is useful for initializing types which lazily allocate, like
     /// `Vec::new` does.
-    #[stable(feature = "nonnull", since = "1.24.0")]
+    #[stable(feature = "nonnull", since = "1.25.0")]
     pub fn dangling() -> Self {
         unsafe {
             let ptr = mem::align_of::<T>() as *mut T;
@@ -2524,19 +2517,19 @@ impl<T: ?Sized> NonNull<T> {
     /// # Safety
     ///
     /// `ptr` must be non-null.
-    #[stable(feature = "nonnull", since = "1.24.0")]
+    #[stable(feature = "nonnull", since = "1.25.0")]
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
         NonNull { pointer: NonZero::new_unchecked(ptr) }
     }
 
     /// Creates a new `NonNull` if `ptr` is non-null.
-    #[stable(feature = "nonnull", since = "1.24.0")]
+    #[stable(feature = "nonnull", since = "1.25.0")]
     pub fn new(ptr: *mut T) -> Option<Self> {
         NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz })
     }
 
     /// Acquires the underlying `*mut` pointer.
-    #[stable(feature = "nonnull", since = "1.24.0")]
+    #[stable(feature = "nonnull", since = "1.25.0")]
     pub fn as_ptr(self) -> *mut T {
         self.pointer.get() as *mut T
     }
@@ -2546,7 +2539,7 @@ impl<T: ?Sized> NonNull<T> {
     /// The resulting lifetime is bound to self so this behaves "as if"
     /// it were actually an instance of T that is getting borrowed. If a longer
     /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
-    #[stable(feature = "nonnull", since = "1.24.0")]
+    #[stable(feature = "nonnull", since = "1.25.0")]
     pub unsafe fn as_ref(&self) -> &T {
         &*self.as_ptr()
     }
@@ -2556,47 +2549,93 @@ impl<T: ?Sized> NonNull<T> {
     /// The resulting lifetime is bound to self so this behaves "as if"
     /// it were actually an instance of T that is getting borrowed. If a longer
     /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
-    #[stable(feature = "nonnull", since = "1.24.0")]
+    #[stable(feature = "nonnull", since = "1.25.0")]
     pub unsafe fn as_mut(&mut self) -> &mut T {
         &mut *self.as_ptr()
     }
+
+    /// Cast to a pointer of another type
+    #[unstable(feature = "nonnull_cast", issue = "47653")]
+    pub fn cast<U>(self) -> NonNull<U> {
+        unsafe {
+            NonNull::new_unchecked(self.as_ptr() as *mut U)
+        }
+    }
 }
 
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> Clone for NonNull<T> {
     fn clone(&self) -> Self {
         *self
     }
 }
 
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> Copy for NonNull<T> { }
 
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
 
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> fmt::Debug for NonNull<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Pointer::fmt(&self.as_ptr(), f)
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> fmt::Pointer for NonNull<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Pointer::fmt(&self.as_ptr(), f)
     }
 }
 
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Eq for NonNull<T> {}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> PartialEq for NonNull<T> {
+    fn eq(&self, other: &Self) -> bool {
+        self.as_ptr() == other.as_ptr()
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Ord for NonNull<T> {
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.as_ptr().cmp(&other.as_ptr())
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> PartialOrd for NonNull<T> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        self.as_ptr().partial_cmp(&other.as_ptr())
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> hash::Hash for NonNull<T> {
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.as_ptr().hash(state)
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
     fn from(unique: Unique<T>) -> Self {
         NonNull { pointer: unique.pointer }
     }
 }
 
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
     fn from(reference: &'a mut T) -> Self {
         NonNull { pointer: NonZero::from(reference) }
     }
 }
 
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
     fn from(reference: &'a T) -> Self {
         NonNull { pointer: NonZero::from(reference) }
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index dc866d180bf..0373c8922b2 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1371,6 +1371,29 @@ fn test_range_from_nth() {
     assert_eq!(r, 16..);
     assert_eq!(r.nth(10), Some(26));
     assert_eq!(r, 27..);
+
+    assert_eq!((0..).size_hint(), (usize::MAX, None));
+}
+
+fn is_trusted_len<I: TrustedLen>(_: I) {}
+
+#[test]
+fn test_range_from_take() {
+    let mut it = (0..).take(3);
+    assert_eq!(it.next(), Some(0));
+    assert_eq!(it.next(), Some(1));
+    assert_eq!(it.next(), Some(2));
+    assert_eq!(it.next(), None);
+    is_trusted_len((0..).take(3));
+    assert_eq!((0..).take(3).size_hint(), (3, Some(3)));
+    assert_eq!((0..).take(0).size_hint(), (0, Some(0)));
+    assert_eq!((0..).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
+}
+
+#[test]
+fn test_range_from_take_collect() {
+    let v: Vec<_> = (0..).take(3).collect();
+    assert_eq!(v, vec![0, 1, 2]);
 }
 
 #[test]
@@ -1485,6 +1508,26 @@ fn test_repeat() {
     assert_eq!(it.next(), Some(42));
     assert_eq!(it.next(), Some(42));
     assert_eq!(it.next(), Some(42));
+    assert_eq!(repeat(42).size_hint(), (usize::MAX, None));
+}
+
+#[test]
+fn test_repeat_take() {
+    let mut it = repeat(42).take(3);
+    assert_eq!(it.next(), Some(42));
+    assert_eq!(it.next(), Some(42));
+    assert_eq!(it.next(), Some(42));
+    assert_eq!(it.next(), None);
+    is_trusted_len(repeat(42).take(3));
+    assert_eq!(repeat(42).take(3).size_hint(), (3, Some(3)));
+    assert_eq!(repeat(42).take(0).size_hint(), (0, Some(0)));
+    assert_eq!(repeat(42).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
+}
+
+#[test]
+fn test_repeat_take_collect() {
+    let v: Vec<_> = repeat(42).take(3).collect();
+    assert_eq!(v, vec![42, 42, 42]);
 }
 
 #[test]
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index db6863d6dad..a7a26195059 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -58,6 +58,7 @@
 #![feature(macro_vis_matcher)]
 #![feature(match_default_bindings)]
 #![feature(never_type)]
+#![feature(non_exhaustive)]
 #![feature(nonzero)]
 #![feature(quote)]
 #![feature(refcell_replace_swap)]
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 297586f140e..10497c95e27 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -109,7 +109,7 @@ use self::VarKind::*;
 use hir::def::*;
 use ty::{self, TyCtxt};
 use lint;
-use util::nodemap::NodeMap;
+use util::nodemap::{NodeMap, NodeSet};
 
 use std::{fmt, usize};
 use std::io::prelude::*;
@@ -244,7 +244,8 @@ struct CaptureInfo {
 #[derive(Copy, Clone, Debug)]
 struct LocalInfo {
     id: NodeId,
-    name: ast::Name
+    name: ast::Name,
+    is_shorthand: bool,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -333,6 +334,13 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
         }
     }
 
+    fn variable_is_shorthand(&self, var: Variable) -> bool {
+        match self.var_kinds[var.get()] {
+            Local(LocalInfo { is_shorthand, .. }) => is_shorthand,
+            Arg(..) | CleanExit => false
+        }
+    }
+
     fn set_captures(&mut self, node_id: NodeId, cs: Vec<CaptureInfo>) {
         self.capture_info_map.insert(node_id, Rc::new(cs));
     }
@@ -384,8 +392,9 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
         let name = path1.node;
         ir.add_live_node_for_node(p_id, VarDefNode(sp));
         ir.add_variable(Local(LocalInfo {
-          id: p_id,
-          name,
+            id: p_id,
+            name,
+            is_shorthand: false,
         }));
     });
     intravisit::walk_local(ir, local);
@@ -393,6 +402,22 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
 
 fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
     for pat in &arm.pats {
+        // for struct patterns, take note of which fields used shorthand (`x`
+        // rather than `x: x`)
+        //
+        // FIXME: according to the rust-lang-nursery/rustc-guide book and
+        // librustc/README.md, `NodeId`s are to be phased out in favor of
+        // `HirId`s; however, we need to match the signature of `each_binding`,
+        // which uses `NodeIds`.
+        let mut shorthand_field_ids = NodeSet();
+        if let hir::PatKind::Struct(_, ref fields, _) = pat.node {
+            for field in fields {
+                if field.node.is_shorthand {
+                    shorthand_field_ids.insert(field.node.pat.id);
+                }
+            }
+        }
+
         pat.each_binding(|bm, p_id, sp, path1| {
             debug!("adding local variable {} from match with bm {:?}",
                    p_id, bm);
@@ -400,7 +425,8 @@ fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
             ir.add_live_node_for_node(p_id, VarDefNode(sp));
             ir.add_variable(Local(LocalInfo {
                 id: p_id,
-                name,
+                name: name,
+                is_shorthand: shorthand_field_ids.contains(&p_id)
             }));
         })
     }
@@ -1483,17 +1509,26 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     self.assigned_on_exit(ln, var).is_some()
                 };
 
+                let suggest_underscore_msg = format!("consider using `_{}` instead",
+                                                     name);
                 if is_assigned {
-                    self.ir.tcx.lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp,
-                        &format!("variable `{}` is assigned to, but never used",
-                                 name),
-                        &format!("to avoid this warning, consider using `_{}` instead",
-                                 name));
+                    self.ir.tcx
+                        .lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp,
+                                        &format!("variable `{}` is assigned to, but never used",
+                                                 name),
+                                        &suggest_underscore_msg);
                 } else if name != "self" {
-                    self.ir.tcx.lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp,
-                        &format!("unused variable: `{}`", name),
-                        &format!("to avoid this warning, consider using `_{}` instead",
-                                 name));
+                    let msg = format!("unused variable: `{}`", name);
+                    let mut err = self.ir.tcx
+                        .struct_span_lint_node(lint::builtin::UNUSED_VARIABLES, id, sp, &msg);
+                    if self.ir.variable_is_shorthand(var) {
+                        err.span_suggestion(sp, "try ignoring the field",
+                                            format!("{}: _", name));
+                    } else {
+                        err.span_suggestion_short(sp, &suggest_underscore_msg,
+                                                  format!("_{}", name));
+                    }
+                    err.emit()
                 }
             }
             true
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index c56575f432d..8b9a08dda87 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -112,6 +112,31 @@ pub enum OutputType {
     DepInfo,
 }
 
+/// The epoch of the compiler (RFC 2052)
+#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq)]
+#[non_exhaustive]
+pub enum Epoch {
+    // epochs must be kept in order, newest to oldest
+
+    /// The 2015 epoch
+    Epoch2015,
+    /// The 2018 epoch
+    Epoch2018,
+
+    // when adding new epochs, be sure to update:
+    //
+    // - the list in the `parse_epoch` static
+    // - the match in the `parse_epoch` function
+    // - add a `rust_####()` function to the session
+    // - update the enum in Cargo's sources as well
+    //
+    // When -Zepoch becomes --epoch, there will
+    // also be a check for the epoch being nightly-only
+    // somewhere. That will need to be updated
+    // whenever we're stabilizing/introducing a new epoch
+    // as well as changing the default Cargo template.
+}
+
 impl_stable_hash_for!(enum self::OutputType {
     Bitcode,
     Assembly,
@@ -783,11 +808,13 @@ macro_rules! options {
             Some("`string` or `string=string`");
         pub const parse_lto: Option<&'static str> =
             Some("one of `thin`, `fat`, or omitted");
+        pub const parse_epoch: Option<&'static str> =
+            Some("one of: `2015`, `2018`");
     }
 
     #[allow(dead_code)]
     mod $mod_set {
-        use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto};
+        use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto, Epoch};
         use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel};
         use std::path::PathBuf;
 
@@ -991,6 +1018,15 @@ macro_rules! options {
             };
             true
         }
+
+        fn parse_epoch(slot: &mut Epoch, v: Option<&str>) -> bool {
+            match v {
+                Some("2015") => *slot = Epoch::Epoch2015,
+                Some("2018") => *slot = Epoch::Epoch2018,
+                _ => return false,
+            }
+            true
+        }
     }
 ) }
 
@@ -1278,6 +1314,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         `everybody_loops` (all function bodies replaced with `loop {}`),
         `hir` (the HIR), `hir,identified`, or
         `hir,typed` (HIR with types for each node)."),
+    epoch: Epoch = (Epoch::Epoch2015, parse_epoch, [TRACKED],
+        "The epoch to build Rust with. Newer epochs may include features
+         that require breaking changes. The default epoch is 2015 (the first
+         epoch). Crates compiled with different epochs can be linked together."),
 }
 
 pub fn default_lib_output() -> CrateType {
@@ -2069,7 +2109,7 @@ mod dep_tracking {
     use std::path::PathBuf;
     use std::collections::hash_map::DefaultHasher;
     use super::{Passes, CrateType, OptLevel, DebugInfoLevel, Lto,
-                OutputTypes, Externs, ErrorOutputType, Sanitizer};
+                OutputTypes, Externs, ErrorOutputType, Sanitizer, Epoch};
     use syntax::feature_gate::UnstableFeatures;
     use rustc_back::{PanicStrategy, RelroLevel};
 
@@ -2131,6 +2171,7 @@ mod dep_tracking {
     impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind);
     impl_dep_tracking_hash_via_hash!(Sanitizer);
     impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
+    impl_dep_tracking_hash_via_hash!(Epoch);
 
     impl_dep_tracking_hash_for_sortable_vec_of!(String);
     impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index f4a00a43d8d..9d7a9acc3d5 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -19,7 +19,7 @@ use lint;
 use middle::allocator::AllocatorKind;
 use middle::dependency_format;
 use session::search_paths::PathKind;
-use session::config::{BorrowckMode, DebugInfoLevel, OutputType};
+use session::config::{BorrowckMode, DebugInfoLevel, OutputType, Epoch};
 use ty::tls;
 use util::nodemap::{FxHashMap, FxHashSet};
 use util::common::{duration_to_secs_str, ErrorReported};
@@ -864,6 +864,11 @@ impl Session {
     pub fn teach(&self, code: &DiagnosticId) -> bool {
         self.opts.debugging_opts.teach && !self.parse_sess.span_diagnostic.code_emitted(code)
     }
+
+    /// Are we allowed to use features from the Rust 2018 epoch?
+    pub fn rust_2018(&self) -> bool {
+        self.opts.debugging_opts.epoch >= Epoch::Epoch2018
+    }
 }
 
 pub fn build_session(sopts: config::Options,
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 7b86791026b..d4bcf00be80 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -348,7 +348,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         if direct {
             // this is a "direct", user-specified, rather than derived,
             // obligation.
-            flags.push(("direct", None));
+            flags.push(("direct".to_string(), None));
         }
 
         if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code {
@@ -359,21 +359,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             // Currently I'm leaving it for what I need for `try`.
             if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
                 method = self.tcx.item_name(item);
-                flags.push(("from_method", None));
-                flags.push(("from_method", Some(&*method)));
+                flags.push(("from_method".to_string(), None));
+                flags.push(("from_method".to_string(), Some(method.to_string())));
             }
         }
 
         if let Some(k) = obligation.cause.span.compiler_desugaring_kind() {
             desugaring = k.as_symbol().as_str();
-            flags.push(("from_desugaring", None));
-            flags.push(("from_desugaring", Some(&*desugaring)));
+            flags.push(("from_desugaring".to_string(), None));
+            flags.push(("from_desugaring".to_string(), Some(desugaring.to_string())));
+        }
+        let generics = self.tcx.generics_of(def_id);
+        let self_ty = trait_ref.self_ty();
+        let self_ty_str = self_ty.to_string();
+        flags.push(("_Self".to_string(), Some(self_ty_str.clone())));
+
+        for param in generics.types.iter() {
+            let name = param.name.as_str().to_string();
+            let ty = trait_ref.substs.type_for_def(param);
+            let ty_str = ty.to_string();
+            flags.push((name.clone(),
+                        Some(ty_str.clone())));
+        }
+
+        if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) {
+            flags.push(("crate_local".to_string(), None));
         }
 
         if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
             self.tcx, trait_ref.def_id, def_id
         ) {
-            command.evaluate(self.tcx, trait_ref, &flags)
+            command.evaluate(self.tcx, trait_ref, &flags[..])
         } else {
             OnUnimplementedNote::empty()
         }
@@ -549,7 +565,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                 .map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t)))
                             .unwrap_or((String::new(), String::new()));
 
-                        let OnUnimplementedNote { message, label }
+                        let OnUnimplementedNote { message, label, note }
                             = self.on_unimplemented_note(trait_ref, obligation);
                         let have_alt_message = message.is_some() || label.is_some();
 
@@ -578,6 +594,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                                      trait_ref,
                                                      trait_ref.self_ty()));
                         }
+                        if let Some(ref s) = note {
+                            // If it has a custom "#[rustc_on_unimplemented]" note, let's display it
+                            err.note(s.as_str());
+                        }
 
                         self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
 
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index 757b078086d..8c2c1cfa454 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -29,16 +29,18 @@ pub struct OnUnimplementedDirective {
     pub subcommands: Vec<OnUnimplementedDirective>,
     pub message: Option<OnUnimplementedFormatString>,
     pub label: Option<OnUnimplementedFormatString>,
+    pub note: Option<OnUnimplementedFormatString>,
 }
 
 pub struct OnUnimplementedNote {
     pub message: Option<String>,
     pub label: Option<String>,
+    pub note: Option<String>,
 }
 
 impl OnUnimplementedNote {
     pub fn empty() -> Self {
-        OnUnimplementedNote { message: None, label: None }
+        OnUnimplementedNote { message: None, label: None, note: None }
     }
 }
 
@@ -89,6 +91,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
 
         let mut message = None;
         let mut label = None;
+        let mut note = None;
         let mut subcommands = vec![];
         for item in item_iter {
             if item.check_name("message") && message.is_none() {
@@ -103,8 +106,14 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
                         tcx, trait_def_id, label_.as_str(), span)?);
                     continue;
                 }
+            } else if item.check_name("note") && note.is_none() {
+                if let Some(note_) = item.value_str() {
+                    note = Some(OnUnimplementedFormatString::try_parse(
+                        tcx, trait_def_id, note_.as_str(), span)?);
+                    continue;
+                }
             } else if item.check_name("on") && is_root &&
-                message.is_none() && label.is_none()
+                message.is_none() && label.is_none() && note.is_none()
             {
                 if let Some(items) = item.meta_item_list() {
                     if let Ok(subcommand) =
@@ -128,7 +137,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
         if errored {
             Err(ErrorReported)
         } else {
-            Ok(OnUnimplementedDirective { condition, message, label, subcommands })
+            Ok(OnUnimplementedDirective { condition, message, label, subcommands, note })
         }
     }
 
@@ -154,7 +163,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
                 message: None,
                 subcommands: vec![],
                 label: Some(OnUnimplementedFormatString::try_parse(
-                    tcx, trait_def_id, value.as_str(), attr.span)?)
+                    tcx, trait_def_id, value.as_str(), attr.span)?),
+                note: None,
             }))
         } else {
             return Err(parse_error(tcx, attr.span,
@@ -169,20 +179,20 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
     pub fn evaluate(&self,
                     tcx: TyCtxt<'a, 'gcx, 'tcx>,
                     trait_ref: ty::TraitRef<'tcx>,
-                    options: &[(&str, Option<&str>)])
+                    options: &[(String, Option<String>)])
                     -> OnUnimplementedNote
     {
         let mut message = None;
         let mut label = None;
-        info!("evaluate({:?}, trait_ref={:?}, options={:?})",
-              self, trait_ref, options);
+        let mut note = None;
+        info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options);
 
         for command in self.subcommands.iter().chain(Some(self)).rev() {
             if let Some(ref condition) = command.condition {
                 if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
-                    options.contains(&(&c.name().as_str(),
-                                      match c.value_str().map(|s| s.as_str()) {
-                                          Some(ref s) => Some(s),
+                    options.contains(&(c.name().as_str().to_string(),
+                                      match c.value_str().map(|s| s.as_str().to_string()) {
+                                          Some(s) => Some(s),
                                           None => None
                                       }))
                 }) {
@@ -198,11 +208,16 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
             if let Some(ref label_) = command.label {
                 label = Some(label_.clone());
             }
+
+            if let Some(ref note_) = command.note {
+                note = Some(note_.clone());
+            }
         }
 
         OnUnimplementedNote {
             label: label.map(|l| l.format(tcx, trait_ref)),
-            message: message.map(|m| m.format(tcx, trait_ref))
+            message: message.map(|m| m.format(tcx, trait_ref)),
+            note: note.map(|n| n.format(tcx, trait_ref)),
         }
     }
 }
diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs
index 674f67d5cd2..f98a8f834df 100644
--- a/src/librustc/util/nodemap.rs
+++ b/src/librustc/util/nodemap.rs
@@ -13,7 +13,7 @@
 #![allow(non_snake_case)]
 
 use hir::def_id::DefId;
-use hir::ItemLocalId;
+use hir::{HirId, ItemLocalId};
 use syntax::ast;
 
 pub use rustc_data_structures::fx::FxHashMap;
@@ -21,10 +21,12 @@ pub use rustc_data_structures::fx::FxHashSet;
 
 pub type NodeMap<T> = FxHashMap<ast::NodeId, T>;
 pub type DefIdMap<T> = FxHashMap<DefId, T>;
+pub type HirIdMap<T> = FxHashMap<HirId, T>;
 pub type ItemLocalMap<T> = FxHashMap<ItemLocalId, T>;
 
 pub type NodeSet = FxHashSet<ast::NodeId>;
 pub type DefIdSet = FxHashSet<DefId>;
+pub type HirIdSet = FxHashSet<HirId>;
 pub type ItemLocalSet = FxHashSet<ItemLocalId>;
 
 pub fn NodeMap<T>() -> NodeMap<T> { FxHashMap() }
diff --git a/src/librustc_binaryen/BinaryenWrapper.cpp b/src/librustc_binaryen/BinaryenWrapper.cpp
index d1095a7819d..55f11665f6d 100644
--- a/src/librustc_binaryen/BinaryenWrapper.cpp
+++ b/src/librustc_binaryen/BinaryenWrapper.cpp
@@ -14,6 +14,7 @@
 
 #include <stdint.h>
 #include <string>
+#include <sstream>
 #include <stdlib.h>
 
 #include "s2wasm.h"
@@ -24,6 +25,7 @@ using namespace wasm;
 
 struct BinaryenRustModule {
   BufferWithRandomAccess buffer;
+  std::string sourceMapJSON;
 };
 
 struct BinaryenRustModuleOptions {
@@ -36,6 +38,7 @@ struct BinaryenRustModuleOptions {
   bool ignoreUnknownSymbols;
   bool debugInfo;
   std::string startFunction;
+  std::string sourceMapUrl;
 
   BinaryenRustModuleOptions() :
     globalBase(0),
@@ -46,7 +49,8 @@ struct BinaryenRustModuleOptions {
     importMemory(false),
     ignoreUnknownSymbols(false),
     debugInfo(false),
-    startFunction("")
+    startFunction(""),
+    sourceMapUrl("")
   {}
 
 };
@@ -74,6 +78,12 @@ BinaryenRustModuleOptionsSetStart(BinaryenRustModuleOptions *options,
 }
 
 extern "C" void
+BinaryenRustModuleOptionsSetSourceMapUrl(BinaryenRustModuleOptions *options,
+                                         char *sourceMapUrl) {
+  options->sourceMapUrl = sourceMapUrl;
+}
+
+extern "C" void
 BinaryenRustModuleOptionsSetStackAllocation(BinaryenRustModuleOptions *options,
                                             uint64_t stack) {
   options->stackAllocation = stack;
@@ -106,12 +116,20 @@ BinaryenRustModuleCreate(const BinaryenRustModuleOptions *options,
   {
     WasmBinaryWriter writer(&linker.getOutput().wasm, ret->buffer, options->debug);
     writer.setNamesSection(options->debugInfo);
-    // FIXME: support source maps?
-    // writer.setSourceMap(sourceMapStream.get(), sourceMapUrl);
+
+    std::unique_ptr<std::ostringstream> sourceMapStream = nullptr;
+    {
+      sourceMapStream = make_unique<std::ostringstream>();
+      writer.setSourceMap(sourceMapStream.get(), options->sourceMapUrl);
+    }
 
     // FIXME: support symbol maps?
     // writer.setSymbolMap(symbolMap);
     writer.write();
+
+    if (sourceMapStream) {
+      ret->sourceMapJSON = sourceMapStream->str();
+    }
   }
   return ret.release();
 }
@@ -126,6 +144,16 @@ BinaryenRustModuleLen(const BinaryenRustModule *M) {
   return M->buffer.size();
 }
 
+extern "C" const char*
+BinaryenRustModuleSourceMapPtr(const BinaryenRustModule *M) {
+  return M->sourceMapJSON.data();
+}
+
+extern "C" size_t
+BinaryenRustModuleSourceMapLen(const BinaryenRustModule *M) {
+  return M->sourceMapJSON.length();
+}
+
 extern "C" void
 BinaryenRustModuleFree(BinaryenRustModule *M) {
   delete M;
diff --git a/src/librustc_binaryen/lib.rs b/src/librustc_binaryen/lib.rs
index 6c7feb6a7a9..36174e11ba0 100644
--- a/src/librustc_binaryen/lib.rs
+++ b/src/librustc_binaryen/lib.rs
@@ -51,6 +51,15 @@ impl Module {
             slice::from_raw_parts(ptr, len)
         }
     }
+
+    /// Returns the data of the source map JSON.
+    pub fn source_map(&self) -> &[u8] {
+        unsafe {
+            let ptr = BinaryenRustModuleSourceMapPtr(self.ptr);
+            let len = BinaryenRustModuleSourceMapLen(self.ptr);
+            slice::from_raw_parts(ptr, len)
+        }
+    }
 }
 
 impl Drop for Module {
@@ -94,6 +103,15 @@ impl ModuleOptions {
         self
     }
 
+    /// Configures a `sourceMappingURL` custom section value for the module.
+    pub fn source_map_url(&mut self, url: &str) -> &mut Self {
+        let url = CString::new(url).unwrap();
+        unsafe {
+            BinaryenRustModuleOptionsSetSourceMapUrl(self.ptr, url.as_ptr());
+        }
+        self
+    }
+
     /// Configures how much stack is initially allocated for the module. 1MB is
     /// probably good enough for now.
     pub fn stack(&mut self, amt: u64) -> &mut Self {
@@ -130,6 +148,8 @@ extern {
         -> *mut BinaryenRustModule;
     fn BinaryenRustModulePtr(module: *const BinaryenRustModule) -> *const u8;
     fn BinaryenRustModuleLen(module: *const BinaryenRustModule) -> usize;
+    fn BinaryenRustModuleSourceMapPtr(module: *const BinaryenRustModule) -> *const u8;
+    fn BinaryenRustModuleSourceMapLen(module: *const BinaryenRustModule) -> usize;
     fn BinaryenRustModuleFree(module: *mut BinaryenRustModule);
 
     fn BinaryenRustModuleOptionsCreate()
@@ -138,6 +158,8 @@ extern {
                                              debuginfo: bool);
     fn BinaryenRustModuleOptionsSetStart(module: *mut BinaryenRustModuleOptions,
                                          start: *const libc::c_char);
+    fn BinaryenRustModuleOptionsSetSourceMapUrl(module: *mut BinaryenRustModuleOptions,
+                                                sourceMapUrl: *const libc::c_char);
     fn BinaryenRustModuleOptionsSetStackAllocation(
         module: *mut BinaryenRustModuleOptions,
         stack: u64,
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 1545040f2da..b732eeb624c 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -71,9 +71,12 @@ pub enum Candidate {
     /// Borrow of a constant temporary.
     Ref(Location),
 
-    /// Array of indices found in the third argument of
-    /// a call to one of the simd_shuffleN intrinsics.
-    ShuffleIndices(BasicBlock)
+    /// Currently applied to function calls where the callee has the unstable
+    /// `#[rustc_args_required_const]` attribute as well as the SIMD shuffle
+    /// intrinsic. The intrinsic requires the arguments are indeed constant and
+    /// the attribute currently provides the semantic requirement that arguments
+    /// must be constant.
+    Argument { bb: BasicBlock, index: usize },
 }
 
 struct TempCollector<'tcx> {
@@ -303,10 +306,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                     _ => bug!()
                 }
             }
-            Candidate::ShuffleIndices(bb) => {
+            Candidate::Argument { bb, index } => {
                 match self.source[bb].terminator_mut().kind {
                     TerminatorKind::Call { ref mut args, .. } => {
-                        Rvalue::Use(mem::replace(&mut args[2], new_operand))
+                        Rvalue::Use(mem::replace(&mut args[index], new_operand))
                     }
                     _ => bug!()
                 }
@@ -359,15 +362,15 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
                 }
                 (statement.source_info.span, dest.ty(mir, tcx).to_ty(tcx))
             }
-            Candidate::ShuffleIndices(bb) => {
+            Candidate::Argument { bb, index } => {
                 let terminator = mir[bb].terminator();
                 let ty = match terminator.kind {
                     TerminatorKind::Call { ref args, .. } => {
-                        args[2].ty(mir, tcx)
+                        args[index].ty(mir, tcx)
                     }
                     _ => {
                         span_bug!(terminator.source_info.span,
-                                  "expected simd_shuffleN call to promote");
+                                  "expected call argument to promote");
                     }
                 };
                 (terminator.source_info.span, ty)
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index da76adfd48f..297e0e491f6 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -17,6 +17,7 @@
 use rustc_data_structures::bitvec::BitVector;
 use rustc_data_structures::indexed_set::IdxSetBuf;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::fx::FxHashSet;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::middle::const_val::ConstVal;
@@ -30,6 +31,7 @@ use rustc::mir::visit::{PlaceContext, Visitor};
 use rustc::middle::lang_items;
 use syntax::abi::Abi;
 use syntax::attr;
+use syntax::ast::LitKind;
 use syntax::feature_gate::UnstableFeatures;
 use syntax_pos::{Span, DUMMY_SP};
 
@@ -407,7 +409,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
                         _ => {}
                     }
                 }
-                Candidate::ShuffleIndices(_) => {}
+                Candidate::Argument { .. } => {}
             }
         }
 
@@ -730,8 +732,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
             self.visit_operand(func, location);
 
             let fn_ty = func.ty(self.mir, self.tcx);
+            let mut callee_def_id = None;
             let (mut is_shuffle, mut is_const_fn) = (false, None);
             if let ty::TyFnDef(def_id, _) = fn_ty.sty {
+                callee_def_id = Some(def_id);
                 match self.tcx.fn_sig(def_id).abi() {
                     Abi::RustIntrinsic |
                     Abi::PlatformIntrinsic => {
@@ -754,17 +758,39 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 }
             }
 
+            let constant_arguments = callee_def_id.and_then(|id| {
+                args_required_const(self.tcx, id)
+            });
             for (i, arg) in args.iter().enumerate() {
                 self.nest(|this| {
                     this.visit_operand(arg, location);
-                    if is_shuffle && i == 2 && this.mode == Mode::Fn {
-                        let candidate = Candidate::ShuffleIndices(bb);
+                    if this.mode != Mode::Fn {
+                        return
+                    }
+                    let candidate = Candidate::Argument { bb, index: i };
+                    if is_shuffle && i == 2 {
                         if this.can_promote() {
                             this.promotion_candidates.push(candidate);
                         } else {
                             span_err!(this.tcx.sess, this.span, E0526,
                                       "shuffle indices are not constant");
                         }
+                        return
+                    }
+
+                    let constant_arguments = match constant_arguments.as_ref() {
+                        Some(s) => s,
+                        None => return,
+                    };
+                    if !constant_arguments.contains(&i) {
+                        return
+                    }
+                    if this.can_promote() {
+                        this.promotion_candidates.push(candidate);
+                    } else {
+                        this.tcx.sess.span_err(this.span,
+                            &format!("argument {} is required to be a constant",
+                                     i + 1));
                     }
                 });
             }
@@ -1085,3 +1111,16 @@ impl MirPass for QualifyAndPromoteConstants {
         }
     }
 }
+
+fn args_required_const(tcx: TyCtxt, def_id: DefId) -> Option<FxHashSet<usize>> {
+    let attrs = tcx.get_attrs(def_id);
+    let attr = attrs.iter().find(|a| a.check_name("rustc_args_required_const"))?;
+    let mut ret = FxHashSet();
+    for meta in attr.meta_item_list()? {
+        match meta.literal()?.node {
+            LitKind::Int(a, _) => { ret.insert(a as usize); }
+            _ => return None,
+        }
+    }
+    Some(ret)
+}
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 206c73b0174..ded9a296817 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -759,7 +759,10 @@ unsafe fn codegen(cgcx: &CodegenContext,
 
         if asm2wasm && config.emit_obj {
             let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
-            binaryen_assemble(cgcx, diag_handler, &assembly, &obj_out);
+            let suffix = ".wasm.map"; // FIXME use target suffix
+            let map = cgcx.output_filenames.path(OutputType::Exe)
+                .with_extension(&suffix[1..]);
+            binaryen_assemble(cgcx, diag_handler, &assembly, &obj_out, &map);
             timeline.record("binaryen");
 
             if !config.emit_asm {
@@ -814,7 +817,8 @@ unsafe fn codegen(cgcx: &CodegenContext,
 fn binaryen_assemble(cgcx: &CodegenContext,
                      handler: &Handler,
                      assembly: &Path,
-                     object: &Path) {
+                     object: &Path,
+                     map: &Path) {
     use rustc_binaryen::{Module, ModuleOptions};
 
     let input = fs::read(&assembly).and_then(|contents| {
@@ -823,6 +827,8 @@ fn binaryen_assemble(cgcx: &CodegenContext,
     let mut options = ModuleOptions::new();
     if cgcx.debuginfo != config::NoDebugInfo {
         options.debuginfo(true);
+        let map_file_name = map.file_name().unwrap();
+        options.source_map_url(map_file_name.to_str().unwrap());
     }
 
     options.stack(1024 * 1024);
@@ -832,7 +838,13 @@ fn binaryen_assemble(cgcx: &CodegenContext,
             .map_err(|e| io::Error::new(io::ErrorKind::Other, e))
     });
     let err = assembled.and_then(|binary| {
-        fs::write(&object, binary.data())
+        fs::write(&object, binary.data()).and_then(|()| {
+            if cgcx.debuginfo != config::NoDebugInfo {
+                fs::write(map, binary.source_map())
+            } else {
+                Ok(())
+            }
+        })
     });
     if let Err(e) = err {
         handler.err(&format!("failed to run binaryen assembler: {}", e));
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index c88bbd03af8..e8c3966f23f 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -326,13 +326,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     if reached_raw_pointer
                     && !self.tcx.sess.features.borrow().arbitrary_self_types {
                         // this case used to be allowed by the compiler,
-                        // so we do a future-compat lint here
+                        // so we do a future-compat lint here for the 2015 epoch
                         // (see https://github.com/rust-lang/rust/issues/46906)
-                        self.tcx.lint_node(
-                            lint::builtin::TYVAR_BEHIND_RAW_POINTER,
-                            scope_expr_id,
-                            span,
-                            &format!("the type of this value must be known in this context"));
+                        if self.tcx.sess.rust_2018() {
+                          span_err!(self.tcx.sess, span, E0908,
+                                    "the type of this value must be known \
+                                     to call a method on a raw pointer on it");
+                        } else {
+                            self.tcx.lint_node(
+                                lint::builtin::TYVAR_BEHIND_RAW_POINTER,
+                                scope_expr_id,
+                                span,
+                                &format!("the type of this value must be known in this context"));
+                        }
                     } else {
                         let t = self.structurally_resolved_type(span, final_ty);
                         assert_eq!(t, self.tcx.types.err);
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 363d4a9dc0c..f044b2c711e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2925,7 +2925,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         let rcvr = &args[0];
         let rcvr_t = self.check_expr_with_needs(&rcvr, needs);
         // no need to check for bot/err -- callee does that
-        let rcvr_t = self.structurally_resolved_type(expr.span, rcvr_t);
+        let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
 
         let method = match self.lookup_method(rcvr_t,
                                               segment,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 7a91827faef..d5328a18c22 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -355,41 +355,35 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 }
 
-fn ensure_no_ty_param_bounds(tcx: TyCtxt,
-                             span: Span,
-                             generics: &hir::Generics,
-                             thing: &'static str) {
+fn ensure_no_param_bounds(tcx: TyCtxt,
+                          span: Span,
+                          generics: &hir::Generics,
+                          thing: &'static str) {
     let mut warn = false;
 
     for ty_param in generics.ty_params() {
-        for bound in ty_param.bounds.iter() {
-            match *bound {
-                hir::TraitTyParamBound(..) => {
-                    warn = true;
-                }
-                hir::RegionTyParamBound(..) => { }
-            }
+        if !ty_param.bounds.is_empty() {
+            warn = true;
         }
     }
 
-    for predicate in generics.where_clause.predicates.iter() {
-        match *predicate {
-            hir::WherePredicate::BoundPredicate(..) => {
-                warn = true;
-            }
-            hir::WherePredicate::RegionPredicate(..) => { }
-            hir::WherePredicate::EqPredicate(..) => { }
+    for lft_param in generics.lifetimes() {
+        if !lft_param.bounds.is_empty() {
+            warn = true;
         }
     }
 
+    if !generics.where_clause.predicates.is_empty() {
+        warn = true;
+    }
+
     if warn {
         // According to accepted RFC #XXX, we should
         // eventually accept these, but it will not be
         // part of this PR. Still, convert to warning to
         // make bootstrapping easier.
         span_warn!(tcx.sess, span, E0122,
-                   "trait bounds are not (yet) enforced \
-                   in {} definitions",
+                   "generic bounds are ignored in {}",
                    thing);
     }
 }
@@ -455,7 +449,7 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
             }
         },
         hir::ItemTy(_, ref generics) => {
-            ensure_no_ty_param_bounds(tcx, it.span, generics, "type");
+            ensure_no_param_bounds(tcx, it.span, generics, "type aliases");
             tcx.generics_of(def_id);
             tcx.type_of(def_id);
             tcx.predicates_of(def_id);
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index ac7f54250d3..f59948e9fc4 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -4698,6 +4698,55 @@ element type `T`. Also note that the error is conservatively reported even when
 the alignment of the zero-sized type is less than or equal to the data field's
 alignment.
 "##,
+
+
+E0908: r##"
+A method was called on a raw pointer whose inner type wasn't completely known.
+
+For example, you may have done something like:
+
+```compile_fail
+# #![deny(warnings)]
+let foo = &1;
+let bar = foo as *const _;
+if bar.is_null() {
+    // ...
+}
+```
+
+Here, the type of `bar` isn't known; it could be a pointer to anything. Instead,
+specify a type for the pointer (preferably something that makes sense for the
+thing you're pointing to):
+
+```
+let foo = &1;
+let bar = foo as *const i32;
+if bar.is_null() {
+    // ...
+}
+```
+
+Even though `is_null()` exists as a method on any raw pointer, Rust shows this
+error because  Rust allows for `self` to have arbitrary types (behind the
+arbitrary_self_types feature flag).
+
+This means that someone can specify such a function:
+
+```ignore (cannot-doctest-feature-doesnt-exist-yet)
+impl Foo {
+    fn is_null(self: *const Self) -> bool {
+        // do something else
+    }
+}
+```
+
+and now when you call `.is_null()` on a raw pointer to `Foo`, there's ambiguity.
+
+Given that we don't know what type the pointer is, and there's potential
+ambiguity for some types, we disallow calling methods on raw pointers when
+the type is unknown.
+"##,
+
 }
 
 register_diagnostics! {
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 0f9e7001c15..ba9bcb7af7a 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -47,6 +47,8 @@
     // 2 for "In Return Types"
     var currentTab = 0;
 
+    var themesWidth = null;
+
     function hasClass(elem, className) {
         if (elem && className && elem.className) {
             var elemClass = elem.className;
@@ -121,10 +123,25 @@
                 sidebar.appendChild(div);
             }
         }
+        var themeChoices = document.getElementById("theme-choices");
+        if (themeChoices) {
+            if (!themesWidth) {
+                var savedState = themeChoices.style.display;
+                themeChoices.style.display = 'block';
+                themesWidth = themeChoices.offsetWidth + 'px';
+                themeChoices.style.display = savedState;
+            }
+            themeChoices.style.position = "fixed";
+            themeChoices.style.width = themesWidth;
+            themeChoices.style.top = '78px';
+            themeChoices.style.left = '250px';
+        }
         document.getElementsByTagName("body")[0].style.marginTop = '45px';
         var themePicker = document.getElementById("theme-picker");
         if (themePicker) {
             themePicker.style.position = "fixed";
+            themePicker.style.top = "50px";
+            themePicker.style.left = "250px";
         }
     }
 
@@ -143,6 +160,15 @@
         var themePicker = document.getElementById("theme-picker");
         if (themePicker) {
             themePicker.style.position = "absolute";
+            themePicker.style.top = null;
+            themePicker.style.left = null;
+        }
+        var themeChoices = document.getElementById("theme-choices");
+        if (themeChoices) {
+            themeChoices.style.position = 'absolute';
+            themeChoices.style.width = null;
+            themeChoices.style.top = null;
+            themeChoices.style.left = null;
         }
     }
 
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 2b1f920bba0..53d57b67230 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -870,6 +870,7 @@ span.since {
 		display: block;
 		border-bottom: 1px solid;
 		border-right: 1px solid;
+		height: 45px;
 	}
 
 	.sidebar-elems {
@@ -889,13 +890,19 @@ span.since {
 	}
 
 	nav.sub {
-		margin: 0 auto;
+		width: calc(100% - 32px);
+		float: right;
 	}
 
 	.content {
 		margin-left: 0px;
 	}
 
+	#main {
+		margin-top: 50px;
+		padding: 0;
+	}
+
 	.content .in-band {
 		width: 100%;
 	}
@@ -1042,6 +1049,24 @@ h4 > .important-traits {
 
 	.show-it {
 		display: block;
+		width: 246px;
+	}
+
+	.show-it > .block.items {
+		margin: 8px 0;
+	}
+
+	.show-it > .block.items > ul {
+		margin: 0;
+	}
+
+	.show-it > .block.items > ul > li {
+		text-align: center;
+		margin: 2px 0;
+	}
+
+	.show-it > .block.items > ul > li > a {
+		font-size: 21px;
 	}
 
 	/* Because of ios, we need to actually have a full height sidebar title so the
@@ -1198,8 +1223,8 @@ kbd {
 
 @media (max-width: 700px) {
 	.theme-picker {
-		left: 109px;
-		top: 7px;
+		left: 10px;
+		top: 54px;
 		z-index: 1;
 	}
 }
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index 4c6bcab72b7..907a6e4fcb4 100644
--- a/src/librustdoc/html/static/themes/dark.css
+++ b/src/librustdoc/html/static/themes/dark.css
@@ -383,6 +383,6 @@ kbd {
 
 @media (max-width: 700px) {
 	#theme-picker {
-		background: #353535;
+		background: #f0f0f0;
 	}
 }
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 560876006d3..112e1106093 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -198,7 +198,7 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
 impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
 #[unstable(feature = "ptr_internals", issue = "0")]
 impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {}
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: ?Sized> UnwindSafe for Mutex<T> {}
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 764b3d0a848..dc3745fc4a3 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -761,6 +761,18 @@ impl<'a> Parser<'a> {
         })
     }
 
+    fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
+        let mut err = self.struct_span_err(self.span,
+                                           &format!("expected identifier, found {}",
+                                                    self.this_token_descr()));
+        if let Some(token_descr) = self.token_descr() {
+            err.span_label(self.span, format!("expected identifier, found {}", token_descr));
+        } else {
+            err.span_label(self.span, "expected identifier");
+        }
+        err
+    }
+
     pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
         self.parse_ident_common(true)
     }
@@ -769,15 +781,7 @@ impl<'a> Parser<'a> {
         match self.token {
             token::Ident(i) => {
                 if self.token.is_reserved_ident() {
-                    let mut err = self.struct_span_err(self.span,
-                                                       &format!("expected identifier, found {}",
-                                                                self.this_token_descr()));
-                    if let Some(token_descr) = self.token_descr() {
-                        err.span_label(self.span, format!("expected identifier, found {}",
-                                                          token_descr));
-                    } else {
-                        err.span_label(self.span, "expected identifier");
-                    }
+                    let mut err = self.expected_ident_found();
                     if recover {
                         err.emit();
                     } else {
@@ -791,14 +795,7 @@ impl<'a> Parser<'a> {
                 Err(if self.prev_token_kind == PrevTokenKind::DocComment {
                         self.span_fatal_err(self.prev_span, Error::UselessDocComment)
                     } else {
-                        let mut err = self.fatal(&format!("expected identifier, found `{}`",
-                                                          self.this_token_to_string()));
-                        if let Some(token_descr) = self.token_descr() {
-                            err.span_label(self.span, format!("expected identifier, found {}",
-                                                              token_descr));
-                        } else {
-                            err.span_label(self.span, "expected identifier");
-                        }
+                        let mut err = self.expected_ident_found();
                         if self.token == token::Underscore {
                             err.note("`_` is a wildcard pattern, not an identifier");
                         }
diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs
new file mode 100644
index 00000000000..43872f15d51
--- /dev/null
+++ b/src/test/codegen/repeat-trusted-len.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+// compile-flags: -O
+// ignore-tidy-linelength
+
+#![crate_type = "lib"]
+
+use std::iter;
+
+// CHECK-LABEL: @repeat_take_collect
+#[no_mangle]
+pub fn repeat_take_collect() -> Vec<u8> {
+// CHECK: call void @llvm.memset.p0i8
+    iter::repeat(42).take(100000).collect()
+}
diff --git a/src/test/compile-fail/const-eval-overflow-4b.rs b/src/test/compile-fail/const-eval-overflow-4b.rs
index 02072e9a1a1..6028df18839 100644
--- a/src/test/compile-fail/const-eval-overflow-4b.rs
+++ b/src/test/compile-fail/const-eval-overflow-4b.rs
@@ -22,7 +22,7 @@ const A_I8_T
     : [u32; (i8::MAX as i8 + 1u8) as usize]
     //~^ ERROR mismatched types
     //~| expected i8, found u8
-    //~| ERROR the trait bound `i8: std::ops::Add<u8>` is not satisfied
+    //~| ERROR cannot add `u8` to `i8`
     = [0; (i8::MAX as usize) + 1];
 
 
diff --git a/src/test/compile-fail/dst-bad-assign-3.rs b/src/test/compile-fail/dst-bad-assign-3.rs
index 1c3bad5ba56..759da7b2bde 100644
--- a/src/test/compile-fail/dst-bad-assign-3.rs
+++ b/src/test/compile-fail/dst-bad-assign-3.rs
@@ -13,7 +13,7 @@
 #![feature(unsized_tuple_coercion)]
 
 type Fat<T: ?Sized> = (isize, &'static str, T);
-//~^ WARNING trait bounds are not (yet) enforced
+//~^ WARNING bounds are ignored
 
 #[derive(PartialEq,Eq)]
 struct Bar;
diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs b/src/test/compile-fail/epoch-raw-pointer-method-2015.rs
new file mode 100644
index 00000000000..a71db040b50
--- /dev/null
+++ b/src/test/compile-fail/epoch-raw-pointer-method-2015.rs
@@ -0,0 +1,23 @@
+// Copyright 2012 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.
+
+// ignore-tidy-linelength
+// compile-flags: -Zepoch=2015 -Zunstable-options
+
+// tests that epochs work with the tyvar warning-turned-error
+
+#[deny(warnings)]
+fn main() {
+    let x = 0;
+    let y = &x as *const _;
+    let _ = y.is_null();
+    //~^ error: the type of this value must be known in this context [tyvar_behind_raw_pointer]
+    //~^^ warning: this was previously accepted
+}
diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs b/src/test/compile-fail/epoch-raw-pointer-method-2018.rs
new file mode 100644
index 00000000000..c4815de2306
--- /dev/null
+++ b/src/test/compile-fail/epoch-raw-pointer-method-2018.rs
@@ -0,0 +1,22 @@
+// Copyright 2012 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.
+
+// ignore-tidy-linelength
+// compile-flags: -Zepoch=2018 -Zunstable-options
+
+// tests that epochs work with the tyvar warning-turned-error
+
+#[deny(warnings)]
+fn main() {
+    let x = 0;
+    let y = &x as *const _;
+    let _ = y.is_null();
+    //~^ error: the type of this value must be known to call a method on a raw pointer on it [E0908]
+}
diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs
index dfcf4dc01b8..aa91ce27c37 100644
--- a/src/test/compile-fail/private-in-public-warn.rs
+++ b/src/test/compile-fail/private-in-public-warn.rs
@@ -58,7 +58,7 @@ mod traits {
     pub trait PubTr {}
 
     pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
-    //~^ WARN trait bounds are not (yet) enforced in type definitions
+    //~^ WARN bounds are ignored in type aliases
     //~| WARNING hard error
     pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface
     //~^ WARNING hard error
diff --git a/src/test/compile-fail/rustc-args-required-const.rs b/src/test/compile-fail/rustc-args-required-const.rs
new file mode 100644
index 00000000000..aac9299eaaf
--- /dev/null
+++ b/src/test/compile-fail/rustc-args-required-const.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 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(attr_literals, rustc_attrs, const_fn)]
+
+#[rustc_args_required_const(0)]
+fn foo(_a: i32) {
+}
+
+#[rustc_args_required_const(1)]
+fn bar(_a: i32, _b: i32) {
+}
+
+const A: i32 = 3;
+
+const fn baz() -> i32 {
+    3
+}
+
+fn main() {
+    foo(2);
+    foo(2 + 3);
+    foo(baz());
+    let a = 4;
+    foo(A);
+    foo(a); //~ ERROR: argument 1 is required to be a constant
+    bar(a, 3);
+    bar(a, a); //~ ERROR: argument 2 is required to be a constant
+}
diff --git a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs
index 94a98b1582a..caf510071bd 100644
--- a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs
+++ b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs
@@ -12,7 +12,7 @@ use std::ops::Add;
 
 fn main() {
     <i32 as Add<u32>>::add(1, 2);
-    //~^ ERROR `i32: std::ops::Add<u32>` is not satisfied
+    //~^ ERROR cannot add `u32` to `i32`
     <i32 as Add<i32>>::add(1u32, 2);
     //~^ ERROR mismatched types
     <i32 as Add<i32>>::add(1, 2u32);
diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs
index 36df4f0eb4d..9d9d4cef311 100644
--- a/src/test/ui/impl-trait/equality.rs
+++ b/src/test/ui/impl-trait/equality.rs
@@ -32,7 +32,7 @@ fn sum_to(n: u32) -> impl Foo {
         0
     } else {
         n + sum_to(n - 1)
-        //~^ ERROR the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
+        //~^ ERROR cannot add `impl Foo` to `u32`
     }
 }
 
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index 3fc08a0900f..8ec81903803 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -7,7 +7,7 @@ error[E0308]: mismatched types
    = note: expected type `i32`
               found type `u32`
 
-error[E0277]: the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
+error[E0277]: cannot add `impl Foo` to `u32`
   --> $DIR/equality.rs:34:11
    |
 34 |         n + sum_to(n - 1)
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
new file mode 100644
index 00000000000..a68b4f76352
--- /dev/null
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+
+// must-compile-successfully
+
+#![warn(unused)] // UI tests pass `-A unused` (#43896)
+
+struct SoulHistory {
+    corridors_of_light: usize,
+    hours_are_suns: bool,
+    endless_and_singing: bool
+}
+
+fn main() {
+    let i_think_continually = 2;
+    let who_from_the_womb_remembered = SoulHistory {
+        corridors_of_light: 5,
+        hours_are_suns: true,
+        endless_and_singing: true
+    };
+
+    if let SoulHistory { corridors_of_light,
+                         mut hours_are_suns,
+                         endless_and_singing: true } = who_from_the_womb_remembered {
+        hours_are_suns = false;
+    }
+}
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
new file mode 100644
index 00000000000..694fe69e016
--- /dev/null
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -0,0 +1,40 @@
+warning: unused variable: `i_think_continually`
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:22:9
+   |
+22 |     let i_think_continually = 2;
+   |         ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
+   |
+note: lint level defined here
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
+   |
+13 | #![warn(unused)] // UI tests pass `-A unused` (#43896)
+   |         ^^^^^^
+   = note: #[warn(unused_variables)] implied by #[warn(unused)]
+
+warning: unused variable: `corridors_of_light`
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:29:26
+   |
+29 |     if let SoulHistory { corridors_of_light,
+   |                          ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
+
+warning: variable `hours_are_suns` is assigned to, but never used
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:30:26
+   |
+30 |                          mut hours_are_suns,
+   |                          ^^^^^^^^^^^^^^^^^^
+   |
+   = note: consider using `_hours_are_suns` instead
+
+warning: value assigned to `hours_are_suns` is never read
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:32:9
+   |
+32 |         hours_are_suns = false;
+   |         ^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
+   |
+13 | #![warn(unused)] // UI tests pass `-A unused` (#43896)
+   |         ^^^^^^
+   = note: #[warn(unused_assignments)] implied by #[warn(unused)]
+
diff --git a/src/test/ui/mismatched_types/binops.rs b/src/test/ui/mismatched_types/binops.rs
index e45616cd67a..5144b59955c 100644
--- a/src/test/ui/mismatched_types/binops.rs
+++ b/src/test/ui/mismatched_types/binops.rs
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 fn main() {
-    1 + Some(1); //~ ERROR is not satisfied
-    2 as usize - Some(1); //~ ERROR is not satisfied
-    3 * (); //~ ERROR is not satisfied
-    4 / ""; //~ ERROR is not satisfied
+    1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
+    2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
+    3 * (); //~ ERROR cannot multiply `()` to `{integer}`
+    4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
     5 < String::new(); //~ ERROR is not satisfied
     6 == Ok(1); //~ ERROR is not satisfied
 }
diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr
index 8541ad52e01..1b7fba05063 100644
--- a/src/test/ui/mismatched_types/binops.stderr
+++ b/src/test/ui/mismatched_types/binops.stderr
@@ -1,31 +1,31 @@
-error[E0277]: the trait bound `{integer}: std::ops::Add<std::option::Option<{integer}>>` is not satisfied
+error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}`
   --> $DIR/binops.rs:12:7
    |
-12 |     1 + Some(1); //~ ERROR is not satisfied
+12 |     1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
    |       ^ no implementation for `{integer} + std::option::Option<{integer}>`
    |
    = help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
 
-error[E0277]: the trait bound `usize: std::ops::Sub<std::option::Option<{integer}>>` is not satisfied
+error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize`
   --> $DIR/binops.rs:13:16
    |
-13 |     2 as usize - Some(1); //~ ERROR is not satisfied
+13 |     2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
    |                ^ no implementation for `usize - std::option::Option<{integer}>`
    |
    = help: the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize`
 
-error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied
+error[E0277]: cannot multiply `()` to `{integer}`
   --> $DIR/binops.rs:14:7
    |
-14 |     3 * (); //~ ERROR is not satisfied
+14 |     3 * (); //~ ERROR cannot multiply `()` to `{integer}`
    |       ^ no implementation for `{integer} * ()`
    |
    = help: the trait `std::ops::Mul<()>` is not implemented for `{integer}`
 
-error[E0277]: the trait bound `{integer}: std::ops::Div<&str>` is not satisfied
+error[E0277]: cannot divide `{integer}` by `&str`
   --> $DIR/binops.rs:15:7
    |
-15 |     4 / ""; //~ ERROR is not satisfied
+15 |     4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
    |       ^ no implementation for `{integer} / &str`
    |
    = help: the trait `std::ops::Div<&str>` is not implemented for `{integer}`
diff --git a/src/test/ui/on-unimplemented/auxiliary/no_debug.rs b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs
new file mode 100644
index 00000000000..0f833c62637
--- /dev/null
+++ b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs
@@ -0,0 +1,14 @@
+// Copyright 2018 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.
+// ignore-tidy-linelength
+
+#![crate_type = "lib"]
+
+pub struct Bar;
diff --git a/src/test/ui/on-unimplemented/no-debug.rs b/src/test/ui/on-unimplemented/no-debug.rs
new file mode 100644
index 00000000000..fff6122c6b3
--- /dev/null
+++ b/src/test/ui/on-unimplemented/no-debug.rs
@@ -0,0 +1,27 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:no_debug.rs
+
+extern crate no_debug;
+
+use no_debug::Bar;
+
+struct Foo;
+
+fn main() {
+    println!("{:?} {:?}", Foo, Bar);
+    println!("{} {}", Foo, Bar);
+}
+//~^^^ ERROR `Foo` doesn't implement `std::fmt::Debug`
+//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Debug`
+//~^^^^ ERROR `Foo` doesn't implement `std::fmt::Display`
+//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Display`
+
diff --git a/src/test/ui/on-unimplemented/no-debug.stderr b/src/test/ui/on-unimplemented/no-debug.stderr
new file mode 100644
index 00000000000..af5b1e91211
--- /dev/null
+++ b/src/test/ui/on-unimplemented/no-debug.stderr
@@ -0,0 +1,38 @@
+error[E0277]: `Foo` doesn't implement `std::fmt::Debug`
+  --> $DIR/no-debug.rs:20:27
+   |
+20 |     println!("{:?} {:?}", Foo, Bar);
+   |                           ^^^ `Foo` cannot be formatted using `:?`; add `#[derive(Debug)]` or manually implement `std::fmt::Debug`
+   |
+   = help: the trait `std::fmt::Debug` is not implemented for `Foo`
+   = note: required by `std::fmt::Debug::fmt`
+
+error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Debug`
+  --> $DIR/no-debug.rs:20:32
+   |
+20 |     println!("{:?} {:?}", Foo, Bar);
+   |                                ^^^ `no_debug::Bar` cannot be formatted using `:?` because it doesn't implement `std::fmt::Debug`
+   |
+   = help: the trait `std::fmt::Debug` is not implemented for `no_debug::Bar`
+   = note: required by `std::fmt::Debug::fmt`
+
+error[E0277]: `Foo` doesn't implement `std::fmt::Display`
+  --> $DIR/no-debug.rs:21:23
+   |
+21 |     println!("{} {}", Foo, Bar);
+   |                       ^^^ `Foo` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `Foo`
+   = note: required by `std::fmt::Display::fmt`
+
+error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Display`
+  --> $DIR/no-debug.rs:21:28
+   |
+21 |     println!("{} {}", Foo, Bar);
+   |                            ^^^ `no_debug::Bar` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `no_debug::Bar`
+   = note: required by `std::fmt::Display::fmt`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/param-bounds-ignored.rs b/src/test/ui/param-bounds-ignored.rs
new file mode 100644
index 00000000000..9e09102f2d4
--- /dev/null
+++ b/src/test/ui/param-bounds-ignored.rs
@@ -0,0 +1,33 @@
+// Copyright 2014 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.
+
+// must-compile-successfully
+
+use std::rc::Rc;
+
+type SVec<T: Send> = Vec<T>;
+type VVec<'b, 'a: 'b> = Vec<&'a i32>;
+type WVec<'b, T: 'b> = Vec<T>;
+
+fn foo<'a>(y: &'a i32) {
+    // If the bounds above would matter, the code below would be rejected.
+    let mut x : SVec<_> = Vec::new();
+    x.push(Rc::new(42));
+
+    let mut x : VVec<'static, 'a> = Vec::new();
+    x.push(y);
+
+    let mut x : WVec<'static, & 'a i32> = Vec::new();
+    x.push(y);
+}
+
+fn main() {
+    foo(&42);
+}
diff --git a/src/test/ui/param-bounds-ignored.stderr b/src/test/ui/param-bounds-ignored.stderr
new file mode 100644
index 00000000000..19aa9c5d6e5
--- /dev/null
+++ b/src/test/ui/param-bounds-ignored.stderr
@@ -0,0 +1,18 @@
+warning[E0122]: generic bounds are ignored in type aliases
+  --> $DIR/param-bounds-ignored.rs:15:1
+   |
+15 | type SVec<T: Send> = Vec<T>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning[E0122]: generic bounds are ignored in type aliases
+  --> $DIR/param-bounds-ignored.rs:16:1
+   |
+16 | type VVec<'b, 'a: 'b> = Vec<&'a i32>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning[E0122]: generic bounds are ignored in type aliases
+  --> $DIR/param-bounds-ignored.rs:17:1
+   |
+17 | type WVec<'b, T: 'b> = Vec<T>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr
index 7e19c7492ce..31728dbf08d 100644
--- a/src/test/ui/span/issue-24690.stderr
+++ b/src/test/ui/span/issue-24690.stderr
@@ -2,7 +2,7 @@ warning: unused variable: `theOtherTwo`
   --> $DIR/issue-24690.rs:23:9
    |
 23 |     let theOtherTwo = 2; //~ WARN should have a snake case name
-   |         ^^^^^^^^^^^
+   |         ^^^^^^^^^^^ help: consider using `_theOtherTwo` instead
    |
 note: lint level defined here
   --> $DIR/issue-24690.rs:18:9
@@ -10,7 +10,6 @@ note: lint level defined here
 18 | #![warn(unused)]
    |         ^^^^^^
    = note: #[warn(unused_variables)] implied by #[warn(unused)]
-   = note: to avoid this warning, consider using `_theOtherTwo` instead
 
 warning: variable `theTwo` should have a snake case name such as `the_two`
   --> $DIR/issue-24690.rs:22:9
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.rs b/src/test/ui/span/issue-42234-unknown-receiver-type.rs
new file mode 100644
index 00000000000..d9cdd99c245
--- /dev/null
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.rs
@@ -0,0 +1,27 @@
+// Copyright 2018 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.
+
+// When the type of a method call's receiver is unknown, the span should point
+// to the receiver (and not the entire call, as was previously the case before
+// the fix of which this tests).
+
+fn shines_a_beacon_through_the_darkness() {
+    let x: Option<_> = None;
+    x.unwrap().method_that_could_exist_on_some_type();
+    //~^ ERROR 17:5: 17:15: the type of this value must be known in this context
+}
+
+fn courier_to_des_moines_and_points_west(data: &[u32]) -> String {
+    data.iter() //~ ERROR 22:5: 23:20: the type of this value must be known in this context
+        .sum::<_>()
+        .to_string()
+}
+
+fn main() {}
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
new file mode 100644
index 00000000000..ed756cdc553
--- /dev/null
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
@@ -0,0 +1,15 @@
+error[E0619]: the type of this value must be known in this context
+  --> $DIR/issue-42234-unknown-receiver-type.rs:17:5
+   |
+17 |     x.unwrap().method_that_could_exist_on_some_type();
+   |     ^^^^^^^^^^
+
+error[E0619]: the type of this value must be known in this context
+  --> $DIR/issue-42234-unknown-receiver-type.rs:22:5
+   |
+22 | /     data.iter() //~ ERROR 22:5: 23:20: the type of this value must be known in this context
+23 | |         .sum::<_>()
+   | |___________________^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/span/multiline-span-simple.rs b/src/test/ui/span/multiline-span-simple.rs
index f8e4cbcbf19..dd09534480e 100644
--- a/src/test/ui/span/multiline-span-simple.rs
+++ b/src/test/ui/span/multiline-span-simple.rs
@@ -20,7 +20,7 @@ fn main() {
     let x = 1;
     let y = 2;
     let z = 3;
-    foo(1 as u32 + //~ ERROR not satisfied
+    foo(1 as u32 + //~ ERROR cannot add `()` to `u32`
 
         bar(x,
 
diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr
index b068798630e..a18dfeb31d9 100644
--- a/src/test/ui/span/multiline-span-simple.stderr
+++ b/src/test/ui/span/multiline-span-simple.stderr
@@ -1,7 +1,7 @@
-error[E0277]: the trait bound `u32: std::ops::Add<()>` is not satisfied
+error[E0277]: cannot add `()` to `u32`
   --> $DIR/multiline-span-simple.rs:23:18
    |
-23 |     foo(1 as u32 + //~ ERROR not satisfied
+23 |     foo(1 as u32 + //~ ERROR cannot add `()` to `u32`
    |                  ^ no implementation for `u32 + ()`
    |
    = help: the trait `std::ops::Add<()>` is not implemented for `u32`
diff --git a/src/test/ui/suggestions/for-c-in-str.stderr b/src/test/ui/suggestions/for-c-in-str.stderr
index 7a6dc9a5040..88a7b1b49d6 100644
--- a/src/test/ui/suggestions/for-c-in-str.stderr
+++ b/src/test/ui/suggestions/for-c-in-str.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied
   --> $DIR/for-c-in-str.rs:14:14
    |
 14 |     for c in "asdf" {
-   |              ^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method
+   |              ^^^^^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()`
    |
    = help: the trait `std::iter::Iterator` is not implemented for `&str`
    = note: required by `std::iter::IntoIterator::into_iter`