about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-01-19 19:57:10 -0800
committerEsteban Küber <esteban@kuber.com.ar>2018-02-01 15:06:20 -0800
commitc1383e4dc4bd6598f5d73d2d6b1054f61b2b99d4 (patch)
treeedf364f3770e1626b806a05c569ca8b57c3107cf /src
parent56733bc9f8302409a2b6110f422512923c878154 (diff)
downloadrust-c1383e4dc4bd6598f5d73d2d6b1054f61b2b99d4.tar.gz
rust-c1383e4dc4bd6598f5d73d2d6b1054f61b2b99d4.zip
Add filtering options to `rustc_on_unimplemented`
 - filter error on the evaluated value of `Self`
 - filter error on the evaluated value of the type arguments
 - add argument to include custom note in diagnostic
 - allow the parser to parse `Self` when processing attributes
 - add custom message to binops
Diffstat (limited to 'src')
-rw-r--r--src/libcore/ops/arith.rs115
-rw-r--r--src/libcore/ops/bit.rs30
-rw-r--r--src/librustc/traits/error_reporting.rs32
-rw-r--r--src/librustc/traits/on_unimplemented.rs34
-rw-r--r--src/libsyntax/parse/attr.rs2
-rw-r--r--src/libsyntax/parse/parser.rs16
-rw-r--r--src/test/ui/anonymous-higher-ranked-lifetime.stderr66
-rw-r--r--src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr18
-rw-r--r--src/test/ui/did_you_mean/recursion_limit.stderr6
-rw-r--r--src/test/ui/feature-gate-abi_unadjusted.stderr2
-rw-r--r--src/test/ui/feature-gate-catch_expr.stderr2
-rw-r--r--src/test/ui/feature-gate-i128_type2.stderr10
-rw-r--r--src/test/ui/feature-gate-intrinsics.stderr4
-rw-r--r--src/test/ui/feature-gate-non_ascii_idents.stderr26
-rw-r--r--src/test/ui/feature-gate-repr128.stderr2
-rw-r--r--src/test/ui/feature-gate-unboxed-closures.stderr2
-rw-r--r--src/test/ui/feature-gate-untagged_unions.stderr6
-rw-r--r--src/test/ui/fmt/send-sync.stderr12
-rw-r--r--src/test/ui/generator/not-send-sync.stderr6
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.stderr12
-rw-r--r--src/test/ui/impl-trait/equality.stderr2
-rw-r--r--src/test/ui/issue-24424.stderr6
-rw-r--r--src/test/ui/lint/suggestions.stderr32
-rw-r--r--src/test/ui/lint/use_suggestion_json.stderr67
-rw-r--r--src/test/ui/macros/format-foreign.stderr10
-rw-r--r--src/test/ui/macros/format-unused-lables.stderr52
-rw-r--r--src/test/ui/mismatched_types/E0631.stderr24
-rw-r--r--src/test/ui/mismatched_types/binops.stderr8
-rw-r--r--src/test/ui/mismatched_types/closure-arg-count.stderr6
-rw-r--r--src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr12
-rw-r--r--src/test/ui/mismatched_types/closure-mismatch.stderr12
-rw-r--r--src/test/ui/mismatched_types/fn-variance-1.stderr12
-rw-r--r--src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr13
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.stderr18
-rw-r--r--src/test/ui/on-unimplemented/on-impl.stderr6
-rw-r--r--src/test/ui/on-unimplemented/on-trait.stderr12
-rw-r--r--src/test/ui/span/issue-29595.stderr6
-rw-r--r--src/test/ui/span/multiline-span-simple.stderr2
-rw-r--r--src/test/ui/suggestions/try-operator-on-main.stderr6
-rw-r--r--src/test/ui/type-check/issue-40294.stderr6
40 files changed, 312 insertions, 403 deletions
diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs
index 8b3d662a6db..59a18d6cb75 100644
--- a/src/libcore/ops/arith.rs
+++ b/src/libcore/ops/arith.rs
@@ -75,7 +75,93 @@
 /// ```
 #[lang = "add"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} + {RHS}`"]
+#[rustc_on_unimplemented(
+    on(
+        any(
+            all(_Self="i128", RHS="i64"),
+            all(_Self="i128", RHS="i32"),
+            all(_Self="i128", RHS="i16"),
+            all(_Self="i128", RHS="i8"),
+            all(_Self="i64",  RHS="i32"),
+            all(_Self="i64",  RHS="i16"),
+            all(_Self="i64",  RHS="i8"),
+            all(_Self="i32",  RHS="i16"),
+            all(_Self="i32",  RHS="i8"),
+            all(_Self="i16",  RHS="i8"),
+            all(_Self="u128", RHS="u64"),
+            all(_Self="u128", RHS="u32"),
+            all(_Self="u128", RHS="u16"),
+            all(_Self="u128", RHS="u8"),
+            all(_Self="u64",  RHS="u32"),
+            all(_Self="u64",  RHS="u16"),
+            all(_Self="u64",  RHS="u8"),
+            all(_Self="u32",  RHS="u16"),
+            all(_Self="u32",  RHS="u8"),
+            all(_Self="u16",  RHS="u8"),
+            all(_Self="f64",  RHS="i32"),
+            all(_Self="f64",  RHS="i16"),
+            all(_Self="f64",  RHS="i8"),
+            all(_Self="f64",  RHS="u32"),
+            all(_Self="f64",  RHS="u16"),
+            all(_Self="f64",  RHS="u8"),
+            all(_Self="f32",  RHS="i16"),
+            all(_Self="f32",  RHS="i8"),
+            all(_Self="f32",  RHS="u16"),
+            all(_Self="f32",  RHS="u8"),
+        ),
+        message="cannot add `{RHS}` to `{Self}`",
+        label="no implementation for `{Self} + {RHS}`, but you can safely cast \
+               `{RHS}` into `{Self}` using `as {Self}`",
+    ),
+    on(
+        any(
+            all(RHS="i128", _Self="i64"),
+            all(RHS="i128", _Self="i32"),
+            all(RHS="i128", _Self="i16"),
+            all(RHS="i128", _Self="i8"),
+            all(RHS="i64",  _Self="i32"),
+            all(RHS="i64",  _Self="i16"),
+            all(RHS="i64",  _Self="i8"),
+            all(RHS="i32",  _Self="i16"),
+            all(RHS="i32",  _Self="i8"),
+            all(RHS="i16",  _Self="i8"),
+            all(RHS="u128", _Self="u64"),
+            all(RHS="u128", _Self="u32"),
+            all(RHS="u128", _Self="u16"),
+            all(RHS="u128", _Self="u8"),
+            all(RHS="u64",  _Self="u32"),
+            all(RHS="u64",  _Self="u16"),
+            all(RHS="u64",  _Self="u8"),
+            all(RHS="u32",  _Self="u16"),
+            all(RHS="u32",  _Self="u8"),
+            all(RHS="u16",  _Self="u8"),
+            all(RHS="f64",  _Self="i32"),
+            all(RHS="f64",  _Self="i16"),
+            all(RHS="f64",  _Self="i8"),
+            all(RHS="f64",  _Self="u32"),
+            all(RHS="f64",  _Self="u16"),
+            all(RHS="f64",  _Self="u8"),
+            all(RHS="f32",  _Self="i16"),
+            all(RHS="f32",  _Self="i8"),
+            all(RHS="f32",  _Self="u16"),
+            all(RHS="f32",  _Self="u8"),
+        ),
+        message="cannot add `{RHS}` to `{Self}`",
+        label="no implementation for `{Self} + {RHS}`, but you can safely turn \
+               `{Self}` into `{RHS}` using `as {RHS}`",
+    ),
+    on(
+        all(_Self="{integer}", RHS="{float}"),
+        message="cannot add a float to an integer",
+        label="no implementation for `{Self} + {RHS}`",
+    ),
+    on(
+        all(_Self="{float}", RHS="{integer}"),
+        message="cannot add an integer to a float",
+        label="no implementation for `{Self} + {RHS}`",
+    ),
+    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 +256,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 +374,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 +496,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 +579,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 +737,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 +791,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 +836,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 +881,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 +929,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/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index d65becb912a..f5ff1226685 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,35 @@ 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();
+        // FIXME: remove once `Self` is accepted by the compiler
+        flags.push(("_Self".to_string(), Some(self_ty_str.clone())));
+        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 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 +563,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 +592,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..a493b7f0bb6 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,21 @@ 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;
+        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 +209,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/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 053746b579d..b01f479895b 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -235,7 +235,7 @@ impl<'a> Parser<'a> {
         }
 
         let lo = self.span;
-        let ident = self.parse_ident()?;
+        let ident = self.parse_ident_attr()?;
         let node = self.parse_meta_item_kind()?;
         Ok(ast::MetaItem { name: ident.name, node: node, span: lo.to(self.prev_span) })
     }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index b3c485a85c0..9e8c4d3de22 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -762,13 +762,19 @@ impl<'a> Parser<'a> {
     }
 
     pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
-        self.parse_ident_common(true)
+        self.parse_ident_common(true, false)
     }
 
-    fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
+    pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> {
+        self.parse_ident_common(true, true)
+    }
+
+    fn parse_ident_common(&mut self, recover: bool, accept_self: bool) -> PResult<'a, ast::Ident> {
         match self.token {
             token::Ident(i) => {
-                if self.token.is_reserved_ident() {
+                if self.token.is_reserved_ident()
+                    && !(accept_self && i.name == keywords::SelfType.name())
+                {
                     let mut err = self.struct_span_err(self.span,
                                                        &format!("expected identifier, found {}",
                                                                 self.this_token_descr()));
@@ -2111,7 +2117,7 @@ impl<'a> Parser<'a> {
             self.bump();
             Ok(Ident::with_empty_ctxt(name))
         } else {
-            self.parse_ident_common(false)
+            self.parse_ident_common(false, false)
         }
     }
 
@@ -2128,7 +2134,7 @@ impl<'a> Parser<'a> {
             hi = self.prev_span;
             (fieldname, self.parse_expr()?, false)
         } else {
-            let fieldname = self.parse_ident_common(false)?;
+            let fieldname = self.parse_ident_common(false, false)?;
             hi = self.prev_span;
 
             // Mimic `x: x` for the `x` field shorthand.
diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
index 4bd3b684b7b..e364a4d8b14 100644
--- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr
+++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
@@ -6,11 +6,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _`
    |
-note: required by `f1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:26:1
-   |
-26 | fn f1<F>(_: F) where F: Fn(&(), &()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `f1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:13:5
@@ -20,11 +16,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _`
    |
-note: required by `f2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1
-   |
-27 | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `f2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
@@ -34,11 +26,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r> fn(&(), &'r ()) -> _`
    |
-note: required by `f3`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1
-   |
-28 | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `f3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:15:5
@@ -48,11 +36,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _`
    |
-note: required by `f4`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1
-   |
-29 | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `f4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
@@ -62,11 +46,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r> fn(&'r (), &'r ()) -> _`
    |
-note: required by `f5`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1
-   |
-30 | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `f5`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:17:5
@@ -76,11 +56,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>) -> _`
    |
-note: required by `g1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:33:1
-   |
-33 | fn g1<F>(_: F) where F: Fn(&(), Box<Fn(&())>) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `g1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
@@ -90,11 +66,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _`
    |
-note: required by `g2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1
-   |
-34 | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `g2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:19:5
@@ -104,11 +76,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'s> fn(&'s (), std::boxed::Box<for<'r> std::ops::Fn(&'r ()) + 'static>) -> _`
    |
-note: required by `g3`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1
-   |
-35 | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<Fn(&())>) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `g3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
@@ -118,11 +86,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _`
    |
-note: required by `g4`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1
-   |
-36 | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `g4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:21:5
@@ -132,11 +96,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<for<'t0> std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
    |
-note: required by `h1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:39:1
-   |
-39 | fn h1<F>(_: F) where F: Fn(&(), Box<Fn(&())>, &(), fn(&(), &())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `h1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
@@ -146,11 +106,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
    |
-note: required by `h2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1
-   |
-40 | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<Fn(&())>, &'t0 (), fn(&(), &())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `h2`
 
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index 7ca3e8728fd..d5c4add34b5 100644
--- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -10,11 +10,7 @@ error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied
              <i8 as Foo<u32>>
              <i8 as Foo<u64>>
              <i8 as Foo<bool>>
-note: required by `Foo::bar`
-  --> $DIR/issue-39802-show-5-trait-impls.rs:12:5
-   |
-12 |     fn bar(&self){}
-   |     ^^^^^^^^^^^^^
+   = note: required by `Foo::bar`
 
 error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:35:5
@@ -27,11 +23,7 @@ error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
              <u8 as Foo<u32>>
              <u8 as Foo<u64>>
              <u8 as Foo<bool>>
-note: required by `Foo::bar`
-  --> $DIR/issue-39802-show-5-trait-impls.rs:12:5
-   |
-12 |     fn bar(&self){}
-   |     ^^^^^^^^^^^^^
+   = note: required by `Foo::bar`
 
 error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:36:5
@@ -45,11 +37,7 @@ error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
              <bool as Foo<u32>>
              <bool as Foo<u64>>
            and 2 others
-note: required by `Foo::bar`
-  --> $DIR/issue-39802-show-5-trait-impls.rs:12:5
-   |
-12 |     fn bar(&self){}
-   |     ^^^^^^^^^^^^^
+   = note: required by `Foo::bar`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr
index 2bc7e9e46e7..7fac604ba49 100644
--- a/src/test/ui/did_you_mean/recursion_limit.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit.stderr
@@ -15,11 +15,7 @@ error[E0275]: overflow evaluating the requirement `K: std::marker::Send`
    = note: required because it appears within the type `C`
    = note: required because it appears within the type `B`
    = note: required because it appears within the type `A`
-note: required by `is_send`
-  --> $DIR/recursion_limit.rs:41:1
-   |
-41 | fn is_send<T:Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^
+   = note: required by `is_send`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gate-abi_unadjusted.stderr b/src/test/ui/feature-gate-abi_unadjusted.stderr
index b3f7cd218d3..3cc43847156 100644
--- a/src/test/ui/feature-gate-abi_unadjusted.stderr
+++ b/src/test/ui/feature-gate-abi_unadjusted.stderr
@@ -1,4 +1,4 @@
-error[E0658]: unadjusted ABI is an implementation detail and perma-unstable
+error: unadjusted ABI is an implementation detail and perma-unstable
   --> $DIR/feature-gate-abi_unadjusted.rs:11:1
    |
 11 | / extern "unadjusted" fn foo() {
diff --git a/src/test/ui/feature-gate-catch_expr.stderr b/src/test/ui/feature-gate-catch_expr.stderr
index 4b3bfbbe27a..f486373d225 100644
--- a/src/test/ui/feature-gate-catch_expr.stderr
+++ b/src/test/ui/feature-gate-catch_expr.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `catch` expression is experimental (see issue #31436)
+error: `catch` expression is experimental (see issue #31436)
   --> $DIR/feature-gate-catch_expr.rs:12:24
    |
 12 |       let catch_result = do catch { //~ ERROR `catch` expression is experimental
diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr
index ee81a269214..26653a5739b 100644
--- a/src/test/ui/feature-gate-i128_type2.stderr
+++ b/src/test/ui/feature-gate-i128_type2.stderr
@@ -1,4 +1,4 @@
-error[E0658]: 128-bit type is unstable (see issue #35118)
+error: 128-bit type is unstable (see issue #35118)
   --> $DIR/feature-gate-i128_type2.rs:13:15
    |
 13 | fn test1() -> i128 { //~ ERROR 128-bit type is unstable
@@ -6,7 +6,7 @@ error[E0658]: 128-bit type is unstable (see issue #35118)
    |
    = help: add #![feature(i128_type)] to the crate attributes to enable
 
-error[E0658]: 128-bit type is unstable (see issue #35118)
+error: 128-bit type is unstable (see issue #35118)
   --> $DIR/feature-gate-i128_type2.rs:17:17
    |
 17 | fn test1_2() -> u128 { //~ ERROR 128-bit type is unstable
@@ -14,7 +14,7 @@ error[E0658]: 128-bit type is unstable (see issue #35118)
    |
    = help: add #![feature(i128_type)] to the crate attributes to enable
 
-error[E0658]: 128-bit type is unstable (see issue #35118)
+error: 128-bit type is unstable (see issue #35118)
   --> $DIR/feature-gate-i128_type2.rs:22:12
    |
 22 |     let x: i128 = 0; //~ ERROR 128-bit type is unstable
@@ -22,7 +22,7 @@ error[E0658]: 128-bit type is unstable (see issue #35118)
    |
    = help: add #![feature(i128_type)] to the crate attributes to enable
 
-error[E0658]: 128-bit type is unstable (see issue #35118)
+error: 128-bit type is unstable (see issue #35118)
   --> $DIR/feature-gate-i128_type2.rs:26:12
    |
 26 |     let x: u128 = 0; //~ ERROR 128-bit type is unstable
@@ -32,7 +32,7 @@ error[E0658]: 128-bit type is unstable (see issue #35118)
 
 error[E0601]: main function not found
 
-error[E0658]: repr with 128-bit type is unstable (see issue #35118)
+error: repr with 128-bit type is unstable (see issue #35118)
   --> $DIR/feature-gate-i128_type2.rs:30:1
    |
 30 | / enum A { //~ ERROR 128-bit type is unstable
diff --git a/src/test/ui/feature-gate-intrinsics.stderr b/src/test/ui/feature-gate-intrinsics.stderr
index 918c749504a..5382122e30e 100644
--- a/src/test/ui/feature-gate-intrinsics.stderr
+++ b/src/test/ui/feature-gate-intrinsics.stderr
@@ -1,4 +1,4 @@
-error[E0658]: intrinsics are subject to change
+error: intrinsics are subject to change
   --> $DIR/feature-gate-intrinsics.rs:11:1
    |
 11 | / extern "rust-intrinsic" {   //~ ERROR intrinsics are subject to change
@@ -8,7 +8,7 @@ error[E0658]: intrinsics are subject to change
    |
    = help: add #![feature(intrinsics)] to the crate attributes to enable
 
-error[E0658]: intrinsics are subject to change
+error: intrinsics are subject to change
   --> $DIR/feature-gate-intrinsics.rs:15:1
    |
 15 | / extern "rust-intrinsic" fn baz() {  //~ ERROR intrinsics are subject to change
diff --git a/src/test/ui/feature-gate-non_ascii_idents.stderr b/src/test/ui/feature-gate-non_ascii_idents.stderr
index deb707752b0..90d0b8daee7 100644
--- a/src/test/ui/feature-gate-non_ascii_idents.stderr
+++ b/src/test/ui/feature-gate-non_ascii_idents.stderr
@@ -1,4 +1,4 @@
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:11:1
    |
 11 | extern crate core as bäz; //~ ERROR non-ascii idents
@@ -6,7 +6,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:13:5
    |
 13 | use föö::bar; //~ ERROR non-ascii idents
@@ -14,7 +14,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:15:1
    |
 15 | mod föö { //~ ERROR non-ascii idents
@@ -22,7 +22,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:19:1
    |
 19 | / fn bär( //~ ERROR non-ascii idents
@@ -36,7 +36,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:20:5
    |
 20 |     bäz: isize //~ ERROR non-ascii idents
@@ -44,7 +44,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:22:9
    |
 22 |     let _ö: isize; //~ ERROR non-ascii idents
@@ -52,7 +52,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:25:10
    |
 25 |         (_ä, _) => {} //~ ERROR non-ascii idents
@@ -60,7 +60,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:29:1
    |
 29 | struct Föö { //~ ERROR non-ascii idents
@@ -68,7 +68,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:30:5
    |
 30 |     föö: isize //~ ERROR non-ascii idents
@@ -76,7 +76,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:33:1
    |
 33 | enum Bär { //~ ERROR non-ascii idents
@@ -84,7 +84,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:34:5
    |
 34 |     Bäz { //~ ERROR non-ascii idents
@@ -92,7 +92,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:35:9
    |
 35 |         qüx: isize //~ ERROR non-ascii idents
@@ -100,7 +100,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
+error: non-ascii idents are not fully supported. (see issue #28979)
   --> $DIR/feature-gate-non_ascii_idents.rs:40:5
    |
 40 |     fn qüx();  //~ ERROR non-ascii idents
diff --git a/src/test/ui/feature-gate-repr128.stderr b/src/test/ui/feature-gate-repr128.stderr
index 982ebb01016..c59964887b5 100644
--- a/src/test/ui/feature-gate-repr128.stderr
+++ b/src/test/ui/feature-gate-repr128.stderr
@@ -1,4 +1,4 @@
-error[E0658]: repr with 128-bit type is unstable (see issue #35118)
+error: repr with 128-bit type is unstable (see issue #35118)
   --> $DIR/feature-gate-repr128.rs:12:1
    |
 12 | / enum A { //~ ERROR repr with 128-bit type is unstable
diff --git a/src/test/ui/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gate-unboxed-closures.stderr
index ca8a5924946..b79165147e5 100644
--- a/src/test/ui/feature-gate-unboxed-closures.stderr
+++ b/src/test/ui/feature-gate-unboxed-closures.stderr
@@ -1,4 +1,4 @@
-error[E0658]: rust-call ABI is subject to change (see issue #29625)
+error: rust-call ABI is subject to change (see issue #29625)
   --> $DIR/feature-gate-unboxed-closures.rs:16:5
    |
 16 | /     extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 {
diff --git a/src/test/ui/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gate-untagged_unions.stderr
index 14b66cb5c81..26b698912bc 100644
--- a/src/test/ui/feature-gate-untagged_unions.stderr
+++ b/src/test/ui/feature-gate-untagged_unions.stderr
@@ -1,4 +1,4 @@
-error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836)
+error: unions with non-`Copy` fields are unstable (see issue #32836)
   --> $DIR/feature-gate-untagged_unions.rs:19:1
    |
 19 | / union U3 { //~ ERROR unions with non-`Copy` fields are unstable
@@ -8,7 +8,7 @@ error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836)
    |
    = help: add #![feature(untagged_unions)] to the crate attributes to enable
 
-error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836)
+error: unions with non-`Copy` fields are unstable (see issue #32836)
   --> $DIR/feature-gate-untagged_unions.rs:23:1
    |
 23 | / union U4<T> { //~ ERROR unions with non-`Copy` fields are unstable
@@ -18,7 +18,7 @@ error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836)
    |
    = help: add #![feature(untagged_unions)] to the crate attributes to enable
 
-error[E0658]: unions with `Drop` implementations are unstable (see issue #32836)
+error: unions with `Drop` implementations are unstable (see issue #32836)
   --> $DIR/feature-gate-untagged_unions.rs:27:1
    |
 27 | / union U5 { //~ ERROR unions with `Drop` implementations are unstable
diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr
index 4ec5c9ebd27..9e0e563c35f 100644
--- a/src/test/ui/fmt/send-sync.stderr
+++ b/src/test/ui/fmt/send-sync.stderr
@@ -12,11 +12,7 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync`
    = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]`
    = note: required because it appears within the type `std::fmt::Arguments<'_>`
-note: required by `send`
-  --> $DIR/send-sync.rs:11:1
-   |
-11 | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `send`
 
 error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>`
   --> $DIR/send-sync.rs:19:5
@@ -32,11 +28,7 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync`
    = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]`
    = note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]`
    = note: required because it appears within the type `std::fmt::Arguments<'_>`
-note: required by `sync`
-  --> $DIR/send-sync.rs:12:1
-   |
-12 | fn sync<T: Sync>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `sync`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index e65c8f1546e..fd8f3b8e646 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -7,11 +7,7 @@ error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not s
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::Cell<i32>`
    = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:26:17: 30:6 a:&std::cell::Cell<i32> _]`
-note: required by `main::assert_send`
-  --> $DIR/not-send-sync.rs:17:5
-   |
-17 |     fn assert_send<T: Send>(_: T) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `main::assert_send`
 
 error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 {std::cell::Cell<i32>, ()}]`
   --> $DIR/not-send-sync.rs:19:5
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index 838a3002e3a..ffd6a3fe4ff 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -7,11 +7,7 @@ error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::S
    = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
    = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:21:5: 21:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
    = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
-note: required by `send`
-  --> $DIR/auto-trait-leak.rs:24:1
-   |
-24 | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `send`
 
 error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
   --> $DIR/auto-trait-leak.rs:30:5
@@ -22,11 +18,7 @@ error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::S
    = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
    = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:38:5: 38:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
    = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
-note: required by `send`
-  --> $DIR/auto-trait-leak.rs:24:1
-   |
-24 | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `send`
 
 error[E0391]: unsupported cyclic reference between types/traits detected
   --> $DIR/auto-trait-leak.rs:44:1
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/issue-24424.stderr b/src/test/ui/issue-24424.stderr
index 55af26dd91e..acdf348791b 100644
--- a/src/test/ui/issue-24424.stderr
+++ b/src/test/ui/issue-24424.stderr
@@ -4,11 +4,7 @@ error[E0283]: type annotations required: cannot resolve `T0: Trait0<'l0>`
 14 | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: required by `Trait0`
-  --> $DIR/issue-24424.rs:12:1
-   |
-12 | trait Trait0<'l0>  {}
-   | ^^^^^^^^^^^^^^^^^
+   = note: required by `Trait0`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr
index 8b30f552d37..701a9522218 100644
--- a/src/test/ui/lint/suggestions.stderr
+++ b/src/test/ui/lint/suggestions.stderr
@@ -1,7 +1,7 @@
 warning: unnecessary parentheses around assigned value
-  --> $DIR/suggestions.rs:46:21
+  --> $DIR/suggestions.rs:36:21
    |
-46 |         let mut a = (1); // should suggest no `mut`, no parens
+36 |         let mut a = (1); // should suggest no `mut`, no parens
    |                     ^^^ help: remove these parentheses
    |
 note: lint level defined here
@@ -11,17 +11,17 @@ note: lint level defined here
    |                     ^^^^^^^^^^^^^
 
 warning: use of deprecated attribute `no_debug`: the `#[no_debug]` attribute was an experimental feature that has been deprecated due to lack of demand. See https://github.com/rust-lang/rust/issues/29721
-  --> $DIR/suggestions.rs:41:1
+  --> $DIR/suggestions.rs:31:1
    |
-41 | #[no_debug] // should suggest removal of deprecated attribute
+31 | #[no_debug] // should suggest removal of deprecated attribute
    | ^^^^^^^^^^^ help: remove this attribute
    |
    = note: #[warn(deprecated)] on by default
 
 warning: variable does not need to be mutable
-  --> $DIR/suggestions.rs:46:13
+  --> $DIR/suggestions.rs:36:13
    |
-46 |         let mut a = (1); // should suggest no `mut`, no parens
+36 |         let mut a = (1); // should suggest no `mut`, no parens
    |             ---^^
    |             |
    |             help: remove this `mut`
@@ -72,30 +72,18 @@ warning: function is marked #[no_mangle], but not exported
    |
    = note: #[warn(private_no_mangle_fns)] on by default
 
-warning: static is marked #[no_mangle], but not exported
-  --> $DIR/suggestions.rs:31:18
-   |
-31 |     #[no_mangle] pub static DAUNTLESS: bool = true;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: function is marked #[no_mangle], but not exported
-  --> $DIR/suggestions.rs:33:18
-   |
-33 |     #[no_mangle] pub fn val_jean() {}
-   |                  ^^^^^^^^^^^^^^^^^^^^
-
 warning: denote infinite loops with `loop { ... }`
-  --> $DIR/suggestions.rs:44:5
+  --> $DIR/suggestions.rs:34:5
    |
-44 |     while true { // should suggest `loop`
+34 |     while true { // should suggest `loop`
    |     ^^^^^^^^^^ help: use `loop`
    |
    = note: #[warn(while_true)] on by default
 
 warning: the `warp_factor:` in this pattern is redundant
-  --> $DIR/suggestions.rs:51:23
+  --> $DIR/suggestions.rs:41:23
    |
-51 |             Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
+41 |             Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
    |                       ------------^^^^^^^^^^^^
    |                       |
    |                       help: remove this
diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr
index 86c2ad4c0e7..abbf3da513a 100644
--- a/src/test/ui/lint/use_suggestion_json.stderr
+++ b/src/test/ui/lint/use_suggestion_json.stderr
@@ -2,72 +2,7 @@
   "message": "cannot find type `Iter` in this scope",
   "code": {
     "code": "E0412",
-    "explanation": "
-The type name used is not in scope.
-
-Erroneous code examples:
-
-```compile_fail,E0412
-impl Something {} // error: type name `Something` is not in scope
-
-// or:
-
-trait Foo {
-    fn bar(N); // error: type name `N` is not in scope
-}
-
-// or:
-
-fn foo(x: T) {} // type name `T` is not in scope
-```
-
-To fix this error, please verify you didn't misspell the type name, you did
-declare it or imported it into the scope. Examples:
-
-```
-struct Something;
-
-impl Something {} // ok!
-
-// or:
-
-trait Foo {
-    type N;
-
-    fn bar(_: Self::N); // ok!
-}
-
-// or:
-
-fn foo<T>(x: T) {} // ok!
-```
-
-Another case that causes this error is when a type is imported into a parent
-module. To fix this, you can follow the suggestion and use File directly or
-`use super::File;` which will import the types from the parent namespace. An
-example that causes this error is below:
-
-```compile_fail,E0412
-use std::fs::File;
-
-mod foo {
-    fn some_function(f: File) {}
-}
-```
-
-```
-use std::fs::File;
-
-mod foo {
-    // either
-    use super::File;
-    // or
-    // use std::fs::File;
-    fn foo(f: File) {}
-}
-# fn main() {} // don't insert it for us; that'll break imports
-```
-"
+    "explanation": null
   },
   "level": "error",
   "spans": [
diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr
index f9852c54773..d0229957b68 100644
--- a/src/test/ui/macros/format-foreign.stderr
+++ b/src/test/ui/macros/format-foreign.stderr
@@ -1,8 +1,12 @@
 error: multiple unused formatting arguments
-  --> $DIR/format-foreign.rs:12:30
+  --> $DIR/format-foreign.rs:12:5
    |
-12 |     println!("%.*3$s %s!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
-   |     -------------------------^^^^^^^^--^^^^^^^--^-- multiple unused arguments in this statement
+12 |     println!("%.*3$s %s!/n", "Hello,", "World", 4);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^--------^^-------^^-^^
+   |                              |         |        |
+   |                              |         |        unused
+   |                              |         unused
+   |                              unused
    |
    = help: `%.*3$s` should be written as `{:.2$}`
    = help: `%s` should be written as `{}`
diff --git a/src/test/ui/macros/format-unused-lables.stderr b/src/test/ui/macros/format-unused-lables.stderr
index 64ea5626c1d..9efdca12dea 100644
--- a/src/test/ui/macros/format-unused-lables.stderr
+++ b/src/test/ui/macros/format-unused-lables.stderr
@@ -1,43 +1,49 @@
 error: multiple unused formatting arguments
-  --> $DIR/format-unused-lables.rs:12:22
+  --> $DIR/format-unused-lables.rs:12:5
    |
 12 |     println!("Test", 123, 456, 789);
-   |     -----------------^^^--^^^--^^^-- multiple unused arguments in this statement
+   |     ^^^^^^^^^^^^^^^^^---^^---^^---^^
+   |                      |    |    |
+   |                      |    |    unused
+   |                      |    unused
+   |                      unused
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
 error: multiple unused formatting arguments
-  --> $DIR/format-unused-lables.rs:16:9
+  --> $DIR/format-unused-lables.rs:14:5
    |
-15 | /     println!("Test2",
-16 | |         123,  //~ ERROR multiple unused formatting arguments
-   | |         ^^^
-17 | |         456,
-   | |         ^^^
-18 | |         789
-   | |         ^^^
-19 | |     );
-   | |______- multiple unused arguments in this statement
+14 | /     println!("Test2",
+15 | |         123,
+   | |         --- unused
+16 | |         456,
+   | |         --- unused
+17 | |         789
+   | |         --- unused
+18 | |     );
+   | |______^
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
 error: named argument never used
-  --> $DIR/format-unused-lables.rs:21:35
+  --> $DIR/format-unused-lables.rs:20:35
    |
-21 |     println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used
+20 |     println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used
    |                                   ^^^^^^
 
 error: multiple unused formatting arguments
-  --> $DIR/format-unused-lables.rs:24:9
+  --> $DIR/format-unused-lables.rs:22:5
    |
-23 | /     println!("Some more $STUFF",
-24 | |         "woo!",  //~ ERROR multiple unused formatting arguments
-   | |         ^^^^^^
-25 | |             STUFF=
-26 | |        "things"
-   | |        ^^^^^^^^
-27 | |              , UNUSED="args");
-   | |_______________________^^^^^^_- multiple unused arguments in this statement
+22 | /     println!("Some more $STUFF",
+23 | |         "woo!",
+   | |         ------ unused
+24 | |             STUFF=
+25 | |        "things"
+   | |        -------- unused
+26 | |              , UNUSED="args");
+   | |_______________________------_^
+   |                         |
+   |                         unused
    |
    = help: `$STUFF` should be written as `{STUFF}`
    = note: shell formatting not supported; see the documentation for `std::fmt`
diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr
index 53f2f54325d..442900e0a83 100644
--- a/src/test/ui/mismatched_types/E0631.stderr
+++ b/src/test/ui/mismatched_types/E0631.stderr
@@ -6,11 +6,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `fn(usize) -> _`
    |
-note: required by `foo`
-  --> $DIR/E0631.rs:13:1
-   |
-13 | fn foo<F: Fn(usize)>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `foo`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/E0631.rs:18:5
@@ -20,11 +16,7 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `fn(usize) -> _`
    |
-note: required by `bar`
-  --> $DIR/E0631.rs:14:1
-   |
-14 | fn bar<F: Fn<usize>>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `bar`
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:19:5
@@ -35,11 +27,7 @@ error[E0631]: type mismatch in function arguments
 19 |     foo(f); //~ ERROR type mismatch
    |     ^^^ expected signature of `fn(usize) -> _`
    |
-note: required by `foo`
-  --> $DIR/E0631.rs:13:1
-   |
-13 | fn foo<F: Fn(usize)>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `foo`
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:20:5
@@ -50,11 +38,7 @@ error[E0631]: type mismatch in function arguments
 20 |     bar(f); //~ ERROR type mismatch
    |     ^^^ expected signature of `fn(usize) -> _`
    |
-note: required by `bar`
-  --> $DIR/E0631.rs:14:1
-   |
-14 | fn bar<F: Fn<usize>>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `bar`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr
index 8541ad52e01..57e66794a58 100644
--- a/src/test/ui/mismatched_types/binops.stderr
+++ b/src/test/ui/mismatched_types/binops.stderr
@@ -1,4 +1,4 @@
-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
@@ -6,7 +6,7 @@ error[E0277]: the trait bound `{integer}: std::ops::Add<std::option::Option<{int
    |
    = 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
@@ -14,7 +14,7 @@ error[E0277]: the trait bound `usize: std::ops::Sub<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
@@ -22,7 +22,7 @@ error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied
    |
    = 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
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index be00ee4d74e..d904831ba4e 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -46,11 +46,7 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
    |     |
    |     expected closure that takes 1 argument
    |
-note: required by `f`
-  --> $DIR/closure-arg-count.rs:13:1
-   |
-13 | fn f<F: Fn<usize>>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `f`
 
 error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
   --> $DIR/closure-arg-count.rs:26:53
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
index dfd02fe23b6..77d3a332767 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -31,11 +31,7 @@ error[E0631]: type mismatch in function arguments
    |     expected signature of `for<'r> fn(*mut &'r u32) -> _`
    |     found signature of `fn(*mut &'a u32) -> _`
    |
-note: required by `baz`
-  --> $DIR/closure-arg-type-mismatch.rs:18:1
-   |
-18 | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `baz`
 
 error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::FnOnce<(*mut &'r u32,)>>::Output == ()`
   --> $DIR/closure-arg-type-mismatch.rs:20:5
@@ -43,11 +39,7 @@ error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::Fn
 20 |     baz(f); //~ ERROR type mismatch
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
    |
-note: required by `baz`
-  --> $DIR/closure-arg-type-mismatch.rs:18:1
-   |
-18 | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `baz`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr
index 01de7e07495..99767ba1afa 100644
--- a/src/test/ui/mismatched_types/closure-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-mismatch.stderr
@@ -5,11 +5,7 @@ error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.r
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
    |
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]`
-note: required by `baz`
-  --> $DIR/closure-mismatch.rs:15:1
-   |
-15 | fn baz<T: Foo>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^
+   = note: required by `baz`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/closure-mismatch.rs:18:5
@@ -20,11 +16,7 @@ error[E0631]: type mismatch in closure arguments
    |     expected signature of `for<'r> fn(&'r ()) -> _`
    |
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]`
-note: required by `baz`
-  --> $DIR/closure-mismatch.rs:15:1
-   |
-15 | fn baz<T: Foo>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^
+   = note: required by `baz`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr
index 64c260c30ed..2a27ffd1062 100644
--- a/src/test/ui/mismatched_types/fn-variance-1.stderr
+++ b/src/test/ui/mismatched_types/fn-variance-1.stderr
@@ -7,11 +7,7 @@ error[E0631]: type mismatch in function arguments
 21 |     apply(&3, takes_mut);
    |     ^^^^^ expected signature of `fn(&{integer}) -> _`
    |
-note: required by `apply`
-  --> $DIR/fn-variance-1.rs:15:1
-   |
-15 | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `apply`
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/fn-variance-1.rs:25:5
@@ -22,11 +18,7 @@ error[E0631]: type mismatch in function arguments
 25 |     apply(&mut 3, takes_imm);
    |     ^^^^^ expected signature of `fn(&mut {integer}) -> _`
    |
-note: required by `apply`
-  --> $DIR/fn-variance-1.rs:15:1
-   |
-15 | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `apply`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
index 9c9bbd19c75..8539c8818c0 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
@@ -1,17 +1,12 @@
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/unboxed-closures-vtable-mismatch.rs:25:13
+  --> $DIR/unboxed-closures-vtable-mismatch.rs:23:13
    |
-23 |     let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
+22 |     let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
    |                       ----------------------------- found signature of `fn(usize, isize) -> _`
-24 |     //~^ NOTE found signature of `fn(usize, isize) -> _`
-25 |     let z = call_it(3, f);
+23 |     let z = call_it(3, f);
    |             ^^^^^^^ expected signature of `fn(isize, isize) -> _`
    |
-note: required by `call_it`
-  --> $DIR/unboxed-closures-vtable-mismatch.rs:17:1
-   |
-17 | fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `call_it`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr
index cfac3981be2..1f71be446ef 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.stderr
+++ b/src/test/ui/on-unimplemented/multiple-impls.stderr
@@ -5,11 +5,7 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
    |     ^^^^^^^^^^^^ trait message
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
-note: required by `Index::index`
-  --> $DIR/multiple-impls.rs:22:5
-   |
-22 |     fn index(&self, index: Idx) -> &Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `Index::index`
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:43:5
@@ -26,11 +22,7 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
    |     ^^^^^^^^^^^^ on impl for Foo
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
-note: required by `Index::index`
-  --> $DIR/multiple-impls.rs:22:5
-   |
-22 |     fn index(&self, index: Idx) -> &Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `Index::index`
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:46:5
@@ -47,11 +39,7 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
    |     ^^^^^^^^^^^^ on impl for Bar
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
-note: required by `Index::index`
-  --> $DIR/multiple-impls.rs:22:5
-   |
-22 |     fn index(&self, index: Idx) -> &Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `Index::index`
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:49:5
diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr
index ed2da68f081..c8c06bf44fd 100644
--- a/src/test/ui/on-unimplemented/on-impl.stderr
+++ b/src/test/ui/on-unimplemented/on-impl.stderr
@@ -5,11 +5,7 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
    |     ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
-note: required by `Index::index`
-  --> $DIR/on-impl.rs:19:5
-   |
-19 |     fn index(&self, index: Idx) -> &Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `Index::index`
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:32:5
diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr
index 028200a5558..cde56022fae 100644
--- a/src/test/ui/on-unimplemented/on-trait.stderr
+++ b/src/test/ui/on-unimplemented/on-trait.stderr
@@ -5,11 +5,7 @@ error[E0277]: the trait bound `std::option::Option<std::vec::Vec<u8>>: MyFromIte
    |                              ^^^^^^^ a collection of type `std::option::Option<std::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
    |
    = help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option<std::vec::Vec<u8>>`
-note: required by `collect`
-  --> $DIR/on-trait.rs:31:1
-   |
-31 | fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `collect`
 
 error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not satisfied
   --> $DIR/on-trait.rs:40:21
@@ -18,11 +14,7 @@ error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not
    |                     ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo`
    |
    = help: the trait `Bar::Foo<u8, _, u32>` is not implemented for `std::string::String`
-note: required by `foobar`
-  --> $DIR/on-trait.rs:21:1
-   |
-21 | fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `foobar`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr
index 9046b90f0e9..81ba0057d71 100644
--- a/src/test/ui/span/issue-29595.stderr
+++ b/src/test/ui/span/issue-29595.stderr
@@ -4,11 +4,7 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied
 17 |     let a: u8 = Tr::C; //~ ERROR the trait bound `u8: Tr` is not satisfied
    |                 ^^^^^ the trait `Tr` is not implemented for `u8`
    |
-note: required by `Tr::C`
-  --> $DIR/issue-29595.rs:13:5
-   |
-13 |     const C: Self;
-   |     ^^^^^^^^^^^^^^
+   = note: required by `Tr::C`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr
index b068798630e..b6182825fc2 100644
--- a/src/test/ui/span/multiline-span-simple.stderr
+++ b/src/test/ui/span/multiline-span-simple.stderr
@@ -1,4 +1,4 @@
-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
diff --git a/src/test/ui/suggestions/try-operator-on-main.stderr b/src/test/ui/suggestions/try-operator-on-main.stderr
index e97823a3d5d..36cdd558b0f 100644
--- a/src/test/ui/suggestions/try-operator-on-main.stderr
+++ b/src/test/ui/suggestions/try-operator-on-main.stderr
@@ -22,11 +22,7 @@ error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
 25 |     try_trait_generic::<()>(); //~ ERROR the trait bound
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()`
    |
-note: required by `try_trait_generic`
-  --> $DIR/try-operator-on-main.rs:30:1
-   |
-30 | fn try_trait_generic<T: Try>() -> T {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: required by `try_trait_generic`
 
 error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
   --> $DIR/try-operator-on-main.rs:32:5
diff --git a/src/test/ui/type-check/issue-40294.stderr b/src/test/ui/type-check/issue-40294.stderr
index cf270afdeb1..2ca97aa3ef0 100644
--- a/src/test/ui/type-check/issue-40294.stderr
+++ b/src/test/ui/type-check/issue-40294.stderr
@@ -10,11 +10,7 @@ error[E0283]: type annotations required: cannot resolve `&'a T: Foo`
 21 | | }
    | |_^
    |
-note: required by `Foo`
-  --> $DIR/issue-40294.rs:11:1
-   |
-11 | trait Foo: Sized {
-   | ^^^^^^^^^^^^^^^^
+   = note: required by `Foo`
 
 error: aborting due to previous error