about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/lint/levels.rs33
-rw-r--r--src/librustc_plugin/load.rs8
-rw-r--r--src/librustc_typeck/collect.rs33
-rw-r--r--src/libsyntax/attr/builtin.rs10
-rw-r--r--src/libsyntax/config.rs16
-rw-r--r--src/libsyntax/ext/derive.rs10
-rw-r--r--src/libsyntax/feature_gate.rs50
-rw-r--r--src/test/ui/deprecation/deprecated_no_stack_check.stderr2
-rw-r--r--src/test/ui/deprecation/invalid-literal.rs2
-rw-r--r--src/test/ui/deprecation/invalid-literal.stderr10
-rw-r--r--src/test/ui/error-codes/E0452.stderr4
-rw-r--r--src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs2
-rw-r--r--src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr8
-rw-r--r--src/test/ui/gated-bad-feature.rs14
-rw-r--r--src/test/ui/gated-bad-feature.stderr32
-rw-r--r--src/test/ui/invalid_crate_type_syntax.rs2
-rw-r--r--src/test/ui/invalid_crate_type_syntax.stderr4
-rw-r--r--src/test/ui/issues/issue-43988.rs4
-rw-r--r--src/test/ui/issues/issue-43988.stderr8
-rw-r--r--src/test/ui/lint/lint-malformed.rs2
-rw-r--r--src/test/ui/lint/lint-malformed.stderr8
-rw-r--r--src/test/ui/lint/reasons-erroneous.rs12
-rw-r--r--src/test/ui/lint/reasons-erroneous.stderr46
-rw-r--r--src/test/ui/malformed/malformed-derive-entry.rs2
-rw-r--r--src/test/ui/malformed/malformed-derive-entry.stderr4
-rw-r--r--src/test/ui/malformed/malformed-plugin-1.rs2
-rw-r--r--src/test/ui/malformed/malformed-plugin-1.stderr4
-rw-r--r--src/test/ui/malformed/malformed-plugin-2.rs2
-rw-r--r--src/test/ui/malformed/malformed-plugin-2.stderr4
-rw-r--r--src/test/ui/malformed/malformed-plugin-3.rs2
-rw-r--r--src/test/ui/malformed/malformed-plugin-3.stderr4
-rw-r--r--src/test/ui/malformed/malformed-special-attrs.rs6
-rw-r--r--src/test/ui/malformed/malformed-special-attrs.stderr14
-rw-r--r--src/test/ui/malformed/malformed-unwind-1.rs6
-rw-r--r--src/test/ui/malformed/malformed-unwind-1.stderr10
-rw-r--r--src/test/ui/malformed/malformed-unwind-2.rs4
-rw-r--r--src/test/ui/malformed/malformed-unwind-2.stderr20
-rw-r--r--src/test/ui/marker_trait_attr/marker-attribute-with-values.rs9
-rw-r--r--src/test/ui/marker_trait_attr/marker-attribute-with-values.stderr16
-rw-r--r--src/test/ui/no_crate_type.rs2
-rw-r--r--src/test/ui/no_crate_type.stderr4
-rw-r--r--src/test/ui/on-unimplemented/bad-annotation.rs2
-rw-r--r--src/test/ui/on-unimplemented/bad-annotation.stderr8
-rw-r--r--src/test/ui/proc-macro/attribute.rs10
-rw-r--r--src/test/ui/proc-macro/attribute.stderr42
-rw-r--r--src/test/ui/proc-macro/invalid-attributes.rs12
-rw-r--r--src/test/ui/proc-macro/invalid-attributes.stderr24
-rw-r--r--src/test/ui/repr.rs9
-rw-r--r--src/test/ui/repr.stderr16
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs2
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr4
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity-4.rs12
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity-4.stderr24
-rw-r--r--src/test/ui/target-feature-wrong.rs16
-rw-r--r--src/test/ui/target-feature-wrong.stderr31
55 files changed, 375 insertions, 272 deletions
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 9c926dff325..139f4343117 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -191,7 +191,7 @@ impl<'a> LintLevelsBuilder<'a> {
         let store = self.sess.lint_store.borrow();
         let sess = self.sess;
         let bad_attr = |span| {
-            struct_span_err!(sess, span, E0452, "malformed lint attribute")
+            struct_span_err!(sess, span, E0452, "malformed lint attribute input")
         };
         for attr in attrs {
             let level = match Level::from_symbol(attr.name_or_empty()) {
@@ -238,18 +238,20 @@ impl<'a> LintLevelsBuilder<'a> {
                                 }
                                 reason = Some(rationale);
                             } else {
-                                let mut err = bad_attr(name_value.span);
-                                err.help("reason must be a string literal");
-                                err.emit();
+                                bad_attr(name_value.span)
+                                    .span_label(name_value.span, "reason must be a string literal")
+                                    .emit();
                             }
                         } else {
-                            let mut err = bad_attr(item.span);
-                            err.emit();
+                            bad_attr(item.span)
+                                .span_label(item.span, "bad attribute argument")
+                                .emit();
                         }
                     },
                     ast::MetaItemKind::List(_) => {
-                        let mut err = bad_attr(item.span);
-                        err.emit();
+                        bad_attr(item.span)
+                            .span_label(item.span, "bad attribute argument")
+                            .emit();
                     }
                 }
             }
@@ -258,14 +260,20 @@ impl<'a> LintLevelsBuilder<'a> {
                 let meta_item = match li.meta_item() {
                     Some(meta_item) if meta_item.is_word() => meta_item,
                     _ => {
-                        let mut err = bad_attr(li.span());
+                        let sp = li.span();
+                        let mut err = bad_attr(sp);
+                        let mut add_label = true;
                         if let Some(item) = li.meta_item() {
                             if let ast::MetaItemKind::NameValue(_) = item.node {
                                 if item.path == sym::reason {
-                                    err.help("reason in lint attribute must come last");
+                                    err.span_label(sp, "reason in lint attribute must come last");
+                                    add_label = false;
                                 }
                             }
                         }
+                        if add_label {
+                            err.span_label(sp, "bad attribute argument");
+                        }
                         err.emit();
                         continue;
                     }
@@ -318,15 +326,14 @@ impl<'a> LintLevelsBuilder<'a> {
                                      Also `cfg_attr(cargo-clippy)` won't be necessary anymore",
                                     name
                                 );
-                                let mut err = lint::struct_lint_level(
+                                lint::struct_lint_level(
                                     self.sess,
                                     lint,
                                     lvl,
                                     src,
                                     Some(li.span().into()),
                                     &msg,
-                                );
-                                err.span_suggestion(
+                                ).span_suggestion(
                                     li.span(),
                                     "change it to",
                                     new_lint_name.to_string(),
diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs
index 46cd66fe585..4481892bcf2 100644
--- a/src/librustc_plugin/load.rs
+++ b/src/librustc_plugin/load.rs
@@ -10,7 +10,7 @@ use std::env;
 use std::mem;
 use std::path::PathBuf;
 use syntax::ast;
-use syntax::span_err;
+use syntax::struct_span_err;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax_pos::{Span, DUMMY_SP};
 
@@ -29,8 +29,10 @@ struct PluginLoader<'a> {
     plugins: Vec<PluginRegistrar>,
 }
 
-fn call_malformed_plugin_attribute(a: &Session, b: Span) {
-    span_err!(a, b, E0498, "malformed plugin attribute");
+fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
+    struct_span_err!(sess, span, E0498, "malformed `plugin` attribute")
+        .span_label(span, "malformed attribute")
+        .emit();
 }
 
 /// Read plugin metadata and dynamically load registrar functions.
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 45380d757b9..00990a5c5b5 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -48,6 +48,8 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc::hir::GenericParamKind;
 use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
 
+use errors::Applicability;
+
 use std::iter;
 
 struct OnlySelfBounds(bool);
@@ -2400,13 +2402,18 @@ fn from_target_feature(
         Some(list) => list,
         None => return,
     };
+    let bad_item = |span| {
+        let msg = "malformed `target_feature` attribute input";
+        let code = "enable = \"..\"".to_owned();
+        tcx.sess.struct_span_err(span, &msg)
+            .span_suggestion(span, "must be of the form", code, Applicability::HasPlaceholders)
+            .emit();
+    };
     let rust_features = tcx.features();
     for item in list {
         // Only `enable = ...` is accepted in the meta item list
         if !item.check_name(sym::enable) {
-            let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
-                       currently";
-            tcx.sess.span_err(item.span(), &msg);
+            bad_item(item.span());
             continue;
         }
 
@@ -2414,9 +2421,7 @@ fn from_target_feature(
         let value = match item.value_str() {
             Some(value) => value,
             None => {
-                let msg = "#[target_feature] attribute must be of the form \
-                           #[target_feature(enable = \"..\")]";
-                tcx.sess.span_err(item.span(), &msg);
+                bad_item(item.span());
                 continue;
             }
         };
@@ -2428,12 +2433,14 @@ fn from_target_feature(
                 Some(g) => g,
                 None => {
                     let msg = format!(
-                        "the feature named `{}` is not valid for \
-                         this target",
+                        "the feature named `{}` is not valid for this target",
                         feature
                     );
                     let mut err = tcx.sess.struct_span_err(item.span(), &msg);
-
+                    err.span_label(
+                        item.span(),
+                        format!("`{}` is not valid for this target", feature),
+                    );
                     if feature.starts_with("+") {
                         let valid = whitelist.contains_key(&feature[1..]);
                         if valid {
@@ -2571,9 +2578,11 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
             }
         } else if attr.check_name(sym::target_feature) {
             if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
-                let msg = "#[target_feature(..)] can only be applied to \
-                           `unsafe` function";
-                tcx.sess.span_err(attr.span, msg);
+                let msg = "#[target_feature(..)] can only be applied to `unsafe` functions";
+                tcx.sess.struct_span_err(attr.span, msg)
+                    .span_label(attr.span, "can only be applied to `unsafe` functions")
+                    .span_label(tcx.def_span(id), "not an `unsafe` function")
+                    .emit();
             }
             from_target_feature(
                 tcx,
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 65ca96afab1..b96f13335b2 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -92,7 +92,15 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
                     }
 
                     diagnostic.map(|d| {
-                        span_err!(d, attr.span, E0633, "malformed `#[unwind]` attribute");
+                        struct_span_err!(d, attr.span, E0633, "malformed `unwind` attribute input")
+                            .span_label(attr.span, "invalid argument")
+                            .span_suggestions(
+                                attr.span,
+                                "the allowed arguments are `allowed` and `aborts`",
+                                (vec!["allowed", "aborts"]).into_iter()
+                                    .map(|s| format!("#[unwind({})]", s)),
+                                Applicability::MachineApplicable,
+                            ).emit();
                     });
                 }
             }
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index c82936afa3d..fc413caa428 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -94,6 +94,22 @@ impl<'a> StripUnconfigured<'a> {
         if !attr.check_name(sym::cfg_attr) {
             return vec![attr];
         }
+        if attr.tokens.len() == 0 {
+            self.sess.span_diagnostic
+                .struct_span_err(
+                    attr.span,
+                    "malformed `cfg_attr` attribute input",
+                ).span_suggestion(
+                    attr.span,
+                    "missing condition and attribute",
+                    "#[cfg_attr(condition, attribute, other_attribute, ...)]".to_owned(),
+                    Applicability::HasPlaceholders,
+                ).note("for more information, visit \
+                       <https://doc.rust-lang.org/reference/conditional-compilation.html\
+                       #the-cfg_attr-attribute>")
+                .emit();
+            return Vec::new();
+        }
 
         let (cfg_predicate, expanded_attrs) = match attr.parse(self.sess, |parser| {
             parser.expect(&token::OpenDelim(token::Paren))?;
diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs
index c47224ca0ce..a2cf4a2a82d 100644
--- a/src/libsyntax/ext/derive.rs
+++ b/src/libsyntax/ext/derive.rs
@@ -5,6 +5,7 @@ use crate::ext::base::ExtCtxt;
 use crate::ext::build::AstBuilder;
 use crate::parse::parser::PathStyle;
 use crate::symbol::{Symbol, sym};
+use crate::errors::Applicability;
 
 use syntax_pos::Span;
 
@@ -17,8 +18,13 @@ pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) ->
             return true;
         }
         if !attr.is_meta_item_list() {
-            cx.span_err(attr.span,
-                        "attribute must be of the form `#[derive(Trait1, Trait2, ...)]`");
+            cx.struct_span_err(attr.span, "malformed `derive` attribute input")
+                .span_suggestion(
+                    attr.span,
+                    "missing traits to be derived",
+                    "#[derive(Trait1, Trait2, ...)]".to_owned(),
+                    Applicability::HasPlaceholders,
+                ).emit();
             return false;
         }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 6a049b80aca..b2646efe3e4 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -25,7 +25,7 @@ use crate::parse::{token, ParseSess};
 use crate::symbol::{Symbol, kw, sym};
 use crate::tokenstream::TokenTree;
 
-use errors::{DiagnosticBuilder, Handler};
+use errors::{Applicability, DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP};
@@ -1422,7 +1422,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         Normal,
         template!(
             Word,
-            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason"#,
+            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
             NameValueStr: "reason"
         ),
         Ungated
@@ -1858,24 +1858,32 @@ impl<'a> PostExpansionVisitor<'a> {
 
         match attr.parse_meta(self.context.parse_sess) {
             Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) {
+                let error_msg = format!("malformed `{}` attribute input", name);
                 let mut msg = "attribute must be of the form ".to_owned();
+                let mut suggestions = vec![];
                 let mut first = true;
                 if template.word {
                     first = false;
-                    msg.push_str(&format!("`#[{}{}]`", name, ""));
+                    let code = format!("#[{}]", name);
+                    msg.push_str(&format!("`{}`", &code));
+                    suggestions.push(code);
                 }
                 if let Some(descr) = template.list {
                     if !first {
                         msg.push_str(" or ");
                     }
                     first = false;
-                    msg.push_str(&format!("`#[{}({})]`", name, descr));
+                    let code = format!("#[{}({})]", name, descr);
+                    msg.push_str(&format!("`{}`", &code));
+                    suggestions.push(code);
                 }
                 if let Some(descr) = template.name_value_str {
                     if !first {
                         msg.push_str(" or ");
                     }
-                    msg.push_str(&format!("`#[{} = \"{}\"]`", name, descr));
+                    let code = format!("#[{} = \"{}\"]", name, descr);
+                    msg.push_str(&format!("`{}`", &code));
+                    suggestions.push(code);
                 }
                 if should_warn(name) {
                     self.context.parse_sess.buffer_lint(
@@ -1885,7 +1893,17 @@ impl<'a> PostExpansionVisitor<'a> {
                         &msg,
                     );
                 } else {
-                    self.context.parse_sess.span_diagnostic.span_err(meta.span, &msg);
+                    self.context.parse_sess.span_diagnostic.struct_span_err(meta.span, &error_msg)
+                        .span_suggestions(
+                            meta.span,
+                            if suggestions.len() == 1 {
+                                "must be of the form"
+                            } else {
+                                "the following are the possible correct uses"
+                            },
+                            suggestions.into_iter(),
+                            Applicability::HasPlaceholders,
+                        ).emit();
                 }
             }
             Err(mut err) => err.emit(),
@@ -2298,6 +2316,8 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
         let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
         if let Some(reason) = reason {
             err.span_note(span, reason);
+        } else {
+            err.span_label(span, "feature has been removed");
         }
         err.emit();
     }
@@ -2379,12 +2399,24 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
             None => continue,
         };
 
+        let bad_input = |span| {
+            struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
+        };
+
         for mi in list {
             let name = match mi.ident() {
                 Some(ident) if mi.is_word() => ident.name,
-                _ => {
-                    span_err!(span_handler, mi.span(), E0556,
-                            "malformed feature, expected just one word");
+                Some(ident) => {
+                    bad_input(mi.span()).span_suggestion(
+                        mi.span(),
+                        "expected just one word",
+                        format!("{}", ident.name),
+                        Applicability::MaybeIncorrect,
+                    ).emit();
+                    continue
+                }
+                None => {
+                    bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
                     continue
                 }
             };
diff --git a/src/test/ui/deprecation/deprecated_no_stack_check.stderr b/src/test/ui/deprecation/deprecated_no_stack_check.stderr
index c936a550b3a..141664c1092 100644
--- a/src/test/ui/deprecation/deprecated_no_stack_check.stderr
+++ b/src/test/ui/deprecation/deprecated_no_stack_check.stderr
@@ -2,7 +2,7 @@ error[E0557]: feature has been removed
   --> $DIR/deprecated_no_stack_check.rs:2:12
    |
 LL | #![feature(no_stack_check)]
-   |            ^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^ feature has been removed
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/deprecation/invalid-literal.rs b/src/test/ui/deprecation/invalid-literal.rs
index 7e0d8cdfc2f..fbdfbd1600d 100644
--- a/src/test/ui/deprecation/invalid-literal.rs
+++ b/src/test/ui/deprecation/invalid-literal.rs
@@ -1,4 +1,4 @@
-#[deprecated = b"test"] //~ ERROR attribute must be of the form
+#[deprecated = b"test"] //~ ERROR malformed `deprecated` attribute
 fn foo() {}
 
 fn main() {}
diff --git a/src/test/ui/deprecation/invalid-literal.stderr b/src/test/ui/deprecation/invalid-literal.stderr
index 28bc2e2c2d8..a82eed24814 100644
--- a/src/test/ui/deprecation/invalid-literal.stderr
+++ b/src/test/ui/deprecation/invalid-literal.stderr
@@ -1,8 +1,16 @@
-error: attribute must be of the form `#[deprecated]` or `#[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason)]` or `#[deprecated = "reason"]`
+error: malformed `deprecated` attribute input
   --> $DIR/invalid-literal.rs:1:1
    |
 LL | #[deprecated = b"test"]
    | ^^^^^^^^^^^^^^^^^^^^^^^
+help: the following are the possible correct uses
+   |
+LL | #[deprecated]
+   | ^^^^^^^^^^^^^
+LL | #[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[deprecated = "reason"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0452.stderr b/src/test/ui/error-codes/E0452.stderr
index 7c3093309f9..7f074168f8e 100644
--- a/src/test/ui/error-codes/E0452.stderr
+++ b/src/test/ui/error-codes/E0452.stderr
@@ -1,8 +1,8 @@
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/E0452.rs:1:10
    |
 LL | #![allow(foo = "")]
-   |          ^^^^^^^^
+   |          ^^^^^^^^ bad attribute argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs
index 725f2e0b9d0..4ced941aad5 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs
@@ -13,7 +13,7 @@ mod macro_escape {
     //~^ ERROR arguments to macro_use are not allowed here
 
     #[macro_use = "2700"] struct S;
-    //~^ ERROR attribute must be of the form
+    //~^ ERROR malformed `macro_use` attribute
 
     #[macro_use] fn f() { }
 
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr
index 8074528c0e0..665fe288087 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr
@@ -16,11 +16,17 @@ error: arguments to macro_use are not allowed here
 LL |     mod inner { #![macro_use(my_macro)] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: attribute must be of the form `#[macro_use]` or `#[macro_use(name1, name2, ...)]`
+error: malformed `macro_use` attribute input
   --> $DIR/issue-43106-gating-of-macro_use.rs:15:5
    |
 LL |     #[macro_use = "2700"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^
+help: the following are the possible correct uses
+   |
+LL |     #[macro_use] struct S;
+   |     ^^^^^^^^^^^^
+LL |     #[macro_use(name1, name2, ...)] struct S;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/gated-bad-feature.rs b/src/test/ui/gated-bad-feature.rs
index fb4cc94f779..f8aa23d95e5 100644
--- a/src/test/ui/gated-bad-feature.rs
+++ b/src/test/ui/gated-bad-feature.rs
@@ -1,13 +1,9 @@
-#![feature(
-    foo_bar_baz,
-    foo(bar),
-    foo = "baz"
-)]
-//~^^^ ERROR: malformed feature
-//~^^^ ERROR: malformed feature
+#![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
+//~^ ERROR malformed `feature`
+//~| ERROR malformed `feature`
 
-#![feature] //~ ERROR: attribute must be of the form
-#![feature = "foo"] //~ ERROR: attribute must be of the form
+#![feature] //~ ERROR malformed `feature` attribute
+#![feature = "foo"] //~ ERROR malformed `feature` attribute
 
 #![feature(test_removed_feature)] //~ ERROR: feature has been removed
 
diff --git a/src/test/ui/gated-bad-feature.stderr b/src/test/ui/gated-bad-feature.stderr
index 5a3cfc962e0..ff6780e66a8 100644
--- a/src/test/ui/gated-bad-feature.stderr
+++ b/src/test/ui/gated-bad-feature.stderr
@@ -1,32 +1,32 @@
-error[E0556]: malformed feature, expected just one word
-  --> $DIR/gated-bad-feature.rs:3:5
+error[E0556]: malformed `feature` attribute input
+  --> $DIR/gated-bad-feature.rs:1:25
    |
-LL |     foo(bar),
-   |     ^^^^^^^^
+LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
+   |                         ^^^^^^^^ help: expected just one word: `foo`
 
-error[E0556]: malformed feature, expected just one word
-  --> $DIR/gated-bad-feature.rs:4:5
+error[E0556]: malformed `feature` attribute input
+  --> $DIR/gated-bad-feature.rs:1:35
    |
-LL |     foo = "baz"
-   |     ^^^^^^^^^^^
+LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
+   |                                   ^^^^^^^^^^^ help: expected just one word: `foo`
 
 error[E0557]: feature has been removed
-  --> $DIR/gated-bad-feature.rs:12:12
+  --> $DIR/gated-bad-feature.rs:8:12
    |
 LL | #![feature(test_removed_feature)]
-   |            ^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^^^ feature has been removed
 
-error: attribute must be of the form `#[feature(name1, name1, ...)]`
-  --> $DIR/gated-bad-feature.rs:9:1
+error: malformed `feature` attribute input
+  --> $DIR/gated-bad-feature.rs:5:1
    |
 LL | #![feature]
-   | ^^^^^^^^^^^
+   | ^^^^^^^^^^^ help: must be of the form: `#[feature(name1, name1, ...)]`
 
-error: attribute must be of the form `#[feature(name1, name1, ...)]`
-  --> $DIR/gated-bad-feature.rs:10:1
+error: malformed `feature` attribute input
+  --> $DIR/gated-bad-feature.rs:6:1
    |
 LL | #![feature = "foo"]
-   | ^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[feature(name1, name1, ...)]`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/invalid_crate_type_syntax.rs b/src/test/ui/invalid_crate_type_syntax.rs
index 8157ccdcbf0..621587af35e 100644
--- a/src/test/ui/invalid_crate_type_syntax.rs
+++ b/src/test/ui/invalid_crate_type_syntax.rs
@@ -1,5 +1,5 @@
 // regression test for issue 16974
-#![crate_type(lib)]  //~ ERROR attribute must be of the form
+#![crate_type(lib)]  //~ ERROR malformed `crate_type` attribute input
 
 fn my_lib_fn() {}
 
diff --git a/src/test/ui/invalid_crate_type_syntax.stderr b/src/test/ui/invalid_crate_type_syntax.stderr
index cb3faedfedb..92bed231586 100644
--- a/src/test/ui/invalid_crate_type_syntax.stderr
+++ b/src/test/ui/invalid_crate_type_syntax.stderr
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[crate_type = "bin|lib|..."]`
+error: malformed `crate_type` attribute input
   --> $DIR/invalid_crate_type_syntax.rs:2:1
    |
 LL | #![crate_type(lib)]
-   | ^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "bin|lib|..."]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-43988.rs b/src/test/ui/issues/issue-43988.rs
index 74667d74334..b80907560c3 100644
--- a/src/test/ui/issues/issue-43988.rs
+++ b/src/test/ui/issues/issue-43988.rs
@@ -24,7 +24,7 @@ fn main() {
     #[repr]
     let _y = "123";
     //~^^ ERROR attribute should not be applied to a statement
-    //~| ERROR attribute must be of the form
+    //~| ERROR malformed `repr` attribute
 
     fn foo() {}
 
@@ -34,5 +34,5 @@ fn main() {
 
     let _z = #[repr] 1;
     //~^ ERROR attribute should not be applied to an expression
-    //~| ERROR attribute must be of the form
+    //~| ERROR malformed `repr` attribute
 }
diff --git a/src/test/ui/issues/issue-43988.stderr b/src/test/ui/issues/issue-43988.stderr
index c72e3eab853..c2f0cc6f0ff 100644
--- a/src/test/ui/issues/issue-43988.stderr
+++ b/src/test/ui/issues/issue-43988.stderr
@@ -1,14 +1,14 @@
-error: attribute must be of the form `#[repr(C, packed, ...)]`
+error: malformed `repr` attribute input
   --> $DIR/issue-43988.rs:24:5
    |
 LL |     #[repr]
-   |     ^^^^^^^
+   |     ^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
-error: attribute must be of the form `#[repr(C, packed, ...)]`
+error: malformed `repr` attribute input
   --> $DIR/issue-43988.rs:35:14
    |
 LL |     let _z = #[repr] 1;
-   |              ^^^^^^^
+   |              ^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
 error[E0518]: attribute should be applied to function or closure
   --> $DIR/issue-43988.rs:5:5
diff --git a/src/test/ui/lint/lint-malformed.rs b/src/test/ui/lint/lint-malformed.rs
index c97a4320f1d..0d327677d54 100644
--- a/src/test/ui/lint/lint-malformed.rs
+++ b/src/test/ui/lint/lint-malformed.rs
@@ -1,4 +1,4 @@
-#![deny = "foo"] //~ ERROR attribute must be of the form
+#![deny = "foo"] //~ ERROR malformed `deny` attribute input
 #![allow(bar = "baz")] //~ ERROR malformed lint attribute
 
 fn main() { }
diff --git a/src/test/ui/lint/lint-malformed.stderr b/src/test/ui/lint/lint-malformed.stderr
index f5b9e2b0a0f..f4876290ddb 100644
--- a/src/test/ui/lint/lint-malformed.stderr
+++ b/src/test/ui/lint/lint-malformed.stderr
@@ -1,14 +1,14 @@
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/lint-malformed.rs:2:10
    |
 LL | #![allow(bar = "baz")]
-   |          ^^^^^^^^^^^
+   |          ^^^^^^^^^^^ bad attribute argument
 
-error: attribute must be of the form `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]`
+error: malformed `deny` attribute input
   --> $DIR/lint-malformed.rs:1:1
    |
 LL | #![deny = "foo"]
-   | ^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/reasons-erroneous.rs b/src/test/ui/lint/reasons-erroneous.rs
index e42b329338b..84db885ac09 100644
--- a/src/test/ui/lint/reasons-erroneous.rs
+++ b/src/test/ui/lint/reasons-erroneous.rs
@@ -2,23 +2,27 @@
 
 #![warn(absolute_paths_not_starting_with_crate, reason = 0)]
 //~^ ERROR malformed lint attribute
-//~| HELP reason must be a string literal
+//~| NOTE reason must be a string literal
 #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
 //~^ ERROR malformed lint attribute
-//~| HELP reason must be a string literal
+//~| NOTE reason must be a string literal
 #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
 //~^ ERROR malformed lint attribute
+//~| NOTE bad attribute argument
 #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
 //~^ ERROR malformed lint attribute
+//~| NOTE bad attribute argument
 #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
 //~^ ERROR malformed lint attribute
+//~| NOTE bad attribute argument
 #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
 //~^ ERROR malformed lint attribute
-//~| HELP reason in lint attribute must come last
+//~| NOTE reason in lint attribute must come last
 #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
 //~^ ERROR malformed lint attribute
-//~| HELP reason in lint attribute must come last
+//~| NOTE reason in lint attribute must come last
 #![warn(missing_copy_implementations, reason)]
 //~^ WARN unknown lint
+//~| NOTE #[warn(unknown_lints)] on by default
 
 fn main() {}
diff --git a/src/test/ui/lint/reasons-erroneous.stderr b/src/test/ui/lint/reasons-erroneous.stderr
index 6842686ecba..ff4a0f36bbd 100644
--- a/src/test/ui/lint/reasons-erroneous.stderr
+++ b/src/test/ui/lint/reasons-erroneous.stderr
@@ -1,55 +1,47 @@
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/reasons-erroneous.rs:3:58
    |
 LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)]
-   |                                                          ^
-   |
-   = help: reason must be a string literal
+   |                                                          ^ reason must be a string literal
 
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/reasons-erroneous.rs:6:40
    |
 LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: reason must be a string literal
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
 
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/reasons-erroneous.rs:9:29
    |
 LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
-error[E0452]: malformed lint attribute
-  --> $DIR/reasons-erroneous.rs:11:23
+error[E0452]: malformed lint attribute input
+  --> $DIR/reasons-erroneous.rs:12:23
    |
 LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
-error[E0452]: malformed lint attribute
-  --> $DIR/reasons-erroneous.rs:13:36
+error[E0452]: malformed lint attribute input
+  --> $DIR/reasons-erroneous.rs:15:36
    |
 LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
-error[E0452]: malformed lint attribute
-  --> $DIR/reasons-erroneous.rs:15:44
+error[E0452]: malformed lint attribute input
+  --> $DIR/reasons-erroneous.rs:18:44
    |
 LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: reason in lint attribute must come last
+   |                                            ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
 
-error[E0452]: malformed lint attribute
-  --> $DIR/reasons-erroneous.rs:18:25
+error[E0452]: malformed lint attribute input
+  --> $DIR/reasons-erroneous.rs:21:25
    |
 LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: reason in lint attribute must come last
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
 
 warning: unknown lint: `reason`
-  --> $DIR/reasons-erroneous.rs:21:39
+  --> $DIR/reasons-erroneous.rs:24:39
    |
 LL | #![warn(missing_copy_implementations, reason)]
    |                                       ^^^^^^
diff --git a/src/test/ui/malformed/malformed-derive-entry.rs b/src/test/ui/malformed/malformed-derive-entry.rs
index 36cc58f7e26..3e53e15601b 100644
--- a/src/test/ui/malformed/malformed-derive-entry.rs
+++ b/src/test/ui/malformed/malformed-derive-entry.rs
@@ -7,7 +7,7 @@ struct Test2;
 #[derive()] //~ WARNING empty trait list
 struct Test3;
 
-#[derive] //~ ERROR attribute must be of the form `#[derive(Trait1, Trait2, ...)]`
+#[derive] //~ ERROR malformed `derive` attribute input
 struct Test4;
 
 fn main() {}
diff --git a/src/test/ui/malformed/malformed-derive-entry.stderr b/src/test/ui/malformed/malformed-derive-entry.stderr
index 0dc18f68111..dfbc5faedac 100644
--- a/src/test/ui/malformed/malformed-derive-entry.stderr
+++ b/src/test/ui/malformed/malformed-derive-entry.stderr
@@ -16,11 +16,11 @@ warning: empty trait list in `derive`
 LL | #[derive()]
    | ^^^^^^^^^^^
 
-error: attribute must be of the form `#[derive(Trait1, Trait2, ...)]`
+error: malformed `derive` attribute input
   --> $DIR/malformed-derive-entry.rs:10:1
    |
 LL | #[derive]
-   | ^^^^^^^^^
+   | ^^^^^^^^^ help: missing traits to be derived: `#[derive(Trait1, Trait2, ...)]`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/malformed/malformed-plugin-1.rs b/src/test/ui/malformed/malformed-plugin-1.rs
index 16e7a952ef2..28f6c8e7a6f 100644
--- a/src/test/ui/malformed/malformed-plugin-1.rs
+++ b/src/test/ui/malformed/malformed-plugin-1.rs
@@ -1,4 +1,4 @@
 #![feature(plugin)]
-#![plugin] //~ ERROR attribute must be of the form
+#![plugin] //~ ERROR malformed `plugin` attribute
 
 fn main() {}
diff --git a/src/test/ui/malformed/malformed-plugin-1.stderr b/src/test/ui/malformed/malformed-plugin-1.stderr
index cc0ac182d70..a863cd48596 100644
--- a/src/test/ui/malformed/malformed-plugin-1.stderr
+++ b/src/test/ui/malformed/malformed-plugin-1.stderr
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[plugin(name|name(args))]`
+error: malformed `plugin` attribute input
   --> $DIR/malformed-plugin-1.rs:2:1
    |
 LL | #![plugin]
-   | ^^^^^^^^^^
+   | ^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/malformed/malformed-plugin-2.rs b/src/test/ui/malformed/malformed-plugin-2.rs
index 70a1d7f85e8..8ec7a71da29 100644
--- a/src/test/ui/malformed/malformed-plugin-2.rs
+++ b/src/test/ui/malformed/malformed-plugin-2.rs
@@ -1,4 +1,4 @@
 #![feature(plugin)]
-#![plugin="bleh"] //~ ERROR attribute must be of the form
+#![plugin="bleh"] //~ ERROR malformed `plugin` attribute
 
 fn main() {}
diff --git a/src/test/ui/malformed/malformed-plugin-2.stderr b/src/test/ui/malformed/malformed-plugin-2.stderr
index 617b13b2654..6eb0c50ca93 100644
--- a/src/test/ui/malformed/malformed-plugin-2.stderr
+++ b/src/test/ui/malformed/malformed-plugin-2.stderr
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[plugin(name|name(args))]`
+error: malformed `plugin` attribute input
   --> $DIR/malformed-plugin-2.rs:2:1
    |
 LL | #![plugin="bleh"]
-   | ^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/malformed/malformed-plugin-3.rs b/src/test/ui/malformed/malformed-plugin-3.rs
index 1b70ff3bdb7..c4713616b62 100644
--- a/src/test/ui/malformed/malformed-plugin-3.rs
+++ b/src/test/ui/malformed/malformed-plugin-3.rs
@@ -1,4 +1,4 @@
 #![feature(plugin)]
-#![plugin(foo="bleh")] //~ ERROR malformed plugin attribute
+#![plugin(foo="bleh")] //~ ERROR malformed `plugin` attribute
 
 fn main() {}
diff --git a/src/test/ui/malformed/malformed-plugin-3.stderr b/src/test/ui/malformed/malformed-plugin-3.stderr
index bcbbcd48c66..f93fa0f65e8 100644
--- a/src/test/ui/malformed/malformed-plugin-3.stderr
+++ b/src/test/ui/malformed/malformed-plugin-3.stderr
@@ -1,8 +1,8 @@
-error[E0498]: malformed plugin attribute
+error[E0498]: malformed `plugin` attribute
   --> $DIR/malformed-plugin-3.rs:2:1
    |
 LL | #![plugin(foo="bleh")]
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^ malformed attribute
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/malformed/malformed-special-attrs.rs b/src/test/ui/malformed/malformed-special-attrs.rs
index 4d00755aea0..e67fbdd5ddd 100644
--- a/src/test/ui/malformed/malformed-special-attrs.rs
+++ b/src/test/ui/malformed/malformed-special-attrs.rs
@@ -1,13 +1,13 @@
-#[cfg_attr] //~ ERROR expected `(`, found end of attribute
+#[cfg_attr] //~ ERROR malformed `cfg_attr` attribute
 struct S1;
 
 #[cfg_attr = ""] //~ ERROR expected `(`, found `=`
 struct S2;
 
-#[derive] //~ ERROR attribute must be of the form
+#[derive] //~ ERROR malformed `derive` attribute
 struct S3;
 
-#[derive = ""] //~ ERROR attribute must be of the form
+#[derive = ""] //~ ERROR malformed `derive` attribute
 struct S4;
 
 fn main() {}
diff --git a/src/test/ui/malformed/malformed-special-attrs.stderr b/src/test/ui/malformed/malformed-special-attrs.stderr
index a93f03589e3..319c05eadbf 100644
--- a/src/test/ui/malformed/malformed-special-attrs.stderr
+++ b/src/test/ui/malformed/malformed-special-attrs.stderr
@@ -1,8 +1,10 @@
-error: expected `(`, found end of attribute
+error: malformed `cfg_attr` attribute input
   --> $DIR/malformed-special-attrs.rs:1:1
    |
 LL | #[cfg_attr]
-   | ^ expected `(`
+   | ^^^^^^^^^^^ help: missing condition and attribute: `#[cfg_attr(condition, attribute, other_attribute, ...)]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
 
 error: expected `(`, found `=`
   --> $DIR/malformed-special-attrs.rs:4:12
@@ -10,17 +12,17 @@ error: expected `(`, found `=`
 LL | #[cfg_attr = ""]
    |            ^ expected `(`
 
-error: attribute must be of the form `#[derive(Trait1, Trait2, ...)]`
+error: malformed `derive` attribute input
   --> $DIR/malformed-special-attrs.rs:7:1
    |
 LL | #[derive]
-   | ^^^^^^^^^
+   | ^^^^^^^^^ help: missing traits to be derived: `#[derive(Trait1, Trait2, ...)]`
 
-error: attribute must be of the form `#[derive(Trait1, Trait2, ...)]`
+error: malformed `derive` attribute input
   --> $DIR/malformed-special-attrs.rs:10:1
    |
 LL | #[derive = ""]
-   | ^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^ help: missing traits to be derived: `#[derive(Trait1, Trait2, ...)]`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/malformed/malformed-unwind-1.rs b/src/test/ui/malformed/malformed-unwind-1.rs
index e34c288c027..009695b177f 100644
--- a/src/test/ui/malformed/malformed-unwind-1.rs
+++ b/src/test/ui/malformed/malformed-unwind-1.rs
@@ -1,11 +1,9 @@
 #![feature(unwind_attributes)]
 
-#[unwind]
-//~^ ERROR attribute must be of the form
+#[unwind] //~ ERROR malformed `unwind` attribute
 extern "C" fn f1() {}
 
-#[unwind = ""]
-//~^ ERROR attribute must be of the form
+#[unwind = ""] //~ ERROR malformed `unwind` attribute
 extern "C" fn f2() {}
 
 fn main() {}
diff --git a/src/test/ui/malformed/malformed-unwind-1.stderr b/src/test/ui/malformed/malformed-unwind-1.stderr
index 852136eed91..0a553e8a245 100644
--- a/src/test/ui/malformed/malformed-unwind-1.stderr
+++ b/src/test/ui/malformed/malformed-unwind-1.stderr
@@ -1,14 +1,14 @@
-error: attribute must be of the form `#[unwind(allowed|aborts)]`
+error: malformed `unwind` attribute input
   --> $DIR/malformed-unwind-1.rs:3:1
    |
 LL | #[unwind]
-   | ^^^^^^^^^
+   | ^^^^^^^^^ help: must be of the form: `#[unwind(allowed|aborts)]`
 
-error: attribute must be of the form `#[unwind(allowed|aborts)]`
-  --> $DIR/malformed-unwind-1.rs:7:1
+error: malformed `unwind` attribute input
+  --> $DIR/malformed-unwind-1.rs:6:1
    |
 LL | #[unwind = ""]
-   | ^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^ help: must be of the form: `#[unwind(allowed|aborts)]`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/malformed/malformed-unwind-2.rs b/src/test/ui/malformed/malformed-unwind-2.rs
index d4955b43309..9aafc7ca9b8 100644
--- a/src/test/ui/malformed/malformed-unwind-2.rs
+++ b/src/test/ui/malformed/malformed-unwind-2.rs
@@ -1,11 +1,11 @@
 #![feature(unwind_attributes)]
 
 #[unwind(allowed, aborts)]
-//~^ ERROR malformed `#[unwind]` attribute
+//~^ ERROR malformed `unwind` attribute
 extern "C" fn f1() {}
 
 #[unwind(unsupported)]
-//~^ ERROR malformed `#[unwind]` attribute
+//~^ ERROR malformed `unwind` attribute
 extern "C" fn f2() {}
 
 fn main() {}
diff --git a/src/test/ui/malformed/malformed-unwind-2.stderr b/src/test/ui/malformed/malformed-unwind-2.stderr
index 88fc4e00a2f..ed88b9afd87 100644
--- a/src/test/ui/malformed/malformed-unwind-2.stderr
+++ b/src/test/ui/malformed/malformed-unwind-2.stderr
@@ -1,14 +1,26 @@
-error[E0633]: malformed `#[unwind]` attribute
+error[E0633]: malformed `unwind` attribute input
   --> $DIR/malformed-unwind-2.rs:3:1
    |
 LL | #[unwind(allowed, aborts)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid argument
+help: the allowed arguments are `allowed` and `aborts`
+   |
+LL | #[unwind(allowed)]
+   |
+LL | #[unwind(aborts)]
+   |
 
-error[E0633]: malformed `#[unwind]` attribute
+error[E0633]: malformed `unwind` attribute input
   --> $DIR/malformed-unwind-2.rs:7:1
    |
 LL | #[unwind(unsupported)]
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^ invalid argument
+help: the allowed arguments are `allowed` and `aborts`
+   |
+LL | #[unwind(allowed)]
+   |
+LL | #[unwind(aborts)]
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/marker_trait_attr/marker-attribute-with-values.rs b/src/test/ui/marker_trait_attr/marker-attribute-with-values.rs
index f8bcec78650..9e07f0eaeea 100644
--- a/src/test/ui/marker_trait_attr/marker-attribute-with-values.rs
+++ b/src/test/ui/marker_trait_attr/marker-attribute-with-values.rs
@@ -1,15 +1,12 @@
 #![feature(marker_trait_attr)]
 
-#[marker(always)]
+#[marker(always)] //~ ERROR malformed `marker` attribute
 trait Marker1 {}
-//~^^ ERROR attribute must be of the form
 
-#[marker("never")]
+#[marker("never")] //~ ERROR malformed `marker` attribute
 trait Marker2 {}
-//~^^ ERROR attribute must be of the form
 
-#[marker(key = "value")]
+#[marker(key = "value")] //~ ERROR malformed `marker` attribute
 trait Marker3 {}
-//~^^ ERROR attribute must be of the form `#[marker]`
 
 fn main() {}
diff --git a/src/test/ui/marker_trait_attr/marker-attribute-with-values.stderr b/src/test/ui/marker_trait_attr/marker-attribute-with-values.stderr
index 2b31dcb4760..6f9c9508e7e 100644
--- a/src/test/ui/marker_trait_attr/marker-attribute-with-values.stderr
+++ b/src/test/ui/marker_trait_attr/marker-attribute-with-values.stderr
@@ -1,20 +1,20 @@
-error: attribute must be of the form `#[marker]`
+error: malformed `marker` attribute input
   --> $DIR/marker-attribute-with-values.rs:3:1
    |
 LL | #[marker(always)]
-   | ^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]`
 
-error: attribute must be of the form `#[marker]`
-  --> $DIR/marker-attribute-with-values.rs:7:1
+error: malformed `marker` attribute input
+  --> $DIR/marker-attribute-with-values.rs:6:1
    |
 LL | #[marker("never")]
-   | ^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]`
 
-error: attribute must be of the form `#[marker]`
-  --> $DIR/marker-attribute-with-values.rs:11:1
+error: malformed `marker` attribute input
+  --> $DIR/marker-attribute-with-values.rs:9:1
    |
 LL | #[marker(key = "value")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/no_crate_type.rs b/src/test/ui/no_crate_type.rs
index 392c6fd0dfa..d8e687e04a7 100644
--- a/src/test/ui/no_crate_type.rs
+++ b/src/test/ui/no_crate_type.rs
@@ -1,5 +1,5 @@
 // regression test for issue 11256
-#![crate_type]  //~ ERROR attribute must be of the form
+#![crate_type]  //~ ERROR malformed `crate_type` attribute
 
 fn main() {
     return
diff --git a/src/test/ui/no_crate_type.stderr b/src/test/ui/no_crate_type.stderr
index ec79420d4dd..f34df4e2dd1 100644
--- a/src/test/ui/no_crate_type.stderr
+++ b/src/test/ui/no_crate_type.stderr
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[crate_type = "bin|lib|..."]`
+error: malformed `crate_type` attribute input
   --> $DIR/no_crate_type.rs:2:1
    |
 LL | #![crate_type]
-   | ^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "bin|lib|..."]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/on-unimplemented/bad-annotation.rs b/src/test/ui/on-unimplemented/bad-annotation.rs
index 846db63024c..5357c3bff9a 100644
--- a/src/test/ui/on-unimplemented/bad-annotation.rs
+++ b/src/test/ui/on-unimplemented/bad-annotation.rs
@@ -15,7 +15,7 @@ trait MyFromIterator<A> {
 }
 
 #[rustc_on_unimplemented]
-//~^ ERROR attribute must be of the form
+//~^ ERROR malformed `rustc_on_unimplemented` attribute
 trait BadAnnotation1
 {}
 
diff --git a/src/test/ui/on-unimplemented/bad-annotation.stderr b/src/test/ui/on-unimplemented/bad-annotation.stderr
index abbe9f0fcd4..20b2169f458 100644
--- a/src/test/ui/on-unimplemented/bad-annotation.stderr
+++ b/src/test/ui/on-unimplemented/bad-annotation.stderr
@@ -1,8 +1,14 @@
-error: attribute must be of the form `#[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")]` or `#[rustc_on_unimplemented = "message"]`
+error: malformed `rustc_on_unimplemented` attribute input
   --> $DIR/bad-annotation.rs:17:1
    |
 LL | #[rustc_on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: the following are the possible correct uses
+   |
+LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")]
+   |
+LL | #[rustc_on_unimplemented = "message"]
+   |
 
 error[E0230]: there is no parameter `C` on trait `BadAnnotation2`
   --> $DIR/bad-annotation.rs:22:1
diff --git a/src/test/ui/proc-macro/attribute.rs b/src/test/ui/proc-macro/attribute.rs
index ac7d0b4c2b6..04c88dcef50 100644
--- a/src/test/ui/proc-macro/attribute.rs
+++ b/src/test/ui/proc-macro/attribute.rs
@@ -6,20 +6,18 @@
 extern crate proc_macro;
 use proc_macro::*;
 
-#[proc_macro_derive]
-//~^ ERROR: attribute must be of the form
+#[proc_macro_derive] //~ ERROR malformed `proc_macro_derive` attribute
 pub fn foo1(input: TokenStream) -> TokenStream { input }
 
-#[proc_macro_derive = ""]
-//~^ ERROR: attribute must be of the form
+#[proc_macro_derive = ""] //~ ERROR malformed `proc_macro_derive` attribute
 pub fn foo2(input: TokenStream) -> TokenStream { input }
 
 #[proc_macro_derive(d3, a, b)]
-//~^ ERROR: attribute must have either one or two arguments
+//~^ ERROR attribute must have either one or two arguments
 pub fn foo3(input: TokenStream) -> TokenStream { input }
 
 #[proc_macro_derive(d4, attributes(a), b)]
-//~^ ERROR: attribute must have either one or two arguments
+//~^ ERROR attribute must have either one or two arguments
 pub fn foo4(input: TokenStream) -> TokenStream { input }
 
 #[proc_macro_derive("a")]
diff --git a/src/test/ui/proc-macro/attribute.stderr b/src/test/ui/proc-macro/attribute.stderr
index cc17d383569..e632875cb16 100644
--- a/src/test/ui/proc-macro/attribute.stderr
+++ b/src/test/ui/proc-macro/attribute.stderr
@@ -1,110 +1,110 @@
 error: attribute must have either one or two arguments
-  --> $DIR/attribute.rs:17:1
+  --> $DIR/attribute.rs:15:1
    |
 LL | #[proc_macro_derive(d3, a, b)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: attribute must have either one or two arguments
-  --> $DIR/attribute.rs:21:1
+  --> $DIR/attribute.rs:19:1
    |
 LL | #[proc_macro_derive(d4, attributes(a), b)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: not a meta item
-  --> $DIR/attribute.rs:25:21
+  --> $DIR/attribute.rs:23:21
    |
 LL | #[proc_macro_derive("a")]
    |                     ^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:29:21
+  --> $DIR/attribute.rs:27:21
    |
 LL | #[proc_macro_derive(d6 = "")]
    |                     ^^^^^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:33:21
+  --> $DIR/attribute.rs:31:21
    |
 LL | #[proc_macro_derive(m::d7)]
    |                     ^^^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:37:21
+  --> $DIR/attribute.rs:35:21
    |
 LL | #[proc_macro_derive(d8(a))]
    |                     ^^^^^
 
 error: `self` cannot be a name of derive macro
-  --> $DIR/attribute.rs:41:21
+  --> $DIR/attribute.rs:39:21
    |
 LL | #[proc_macro_derive(self)]
    |                     ^^^^
 
 error: cannot override a built-in derive macro
-  --> $DIR/attribute.rs:45:21
+  --> $DIR/attribute.rs:43:21
    |
 LL | #[proc_macro_derive(PartialEq)]
    |                     ^^^^^^^^^
 
 error: second argument must be `attributes`
-  --> $DIR/attribute.rs:49:26
+  --> $DIR/attribute.rs:47:26
    |
 LL | #[proc_macro_derive(d11, a)]
    |                          ^
 
 error: attribute must be of form: `attributes(foo, bar)`
-  --> $DIR/attribute.rs:49:26
+  --> $DIR/attribute.rs:47:26
    |
 LL | #[proc_macro_derive(d11, a)]
    |                          ^
 
 error: attribute must be of form: `attributes(foo, bar)`
-  --> $DIR/attribute.rs:54:26
+  --> $DIR/attribute.rs:52:26
    |
 LL | #[proc_macro_derive(d12, attributes)]
    |                          ^^^^^^^^^^
 
 error: not a meta item
-  --> $DIR/attribute.rs:58:37
+  --> $DIR/attribute.rs:56:37
    |
 LL | #[proc_macro_derive(d13, attributes("a"))]
    |                                     ^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:62:37
+  --> $DIR/attribute.rs:60:37
    |
 LL | #[proc_macro_derive(d14, attributes(a = ""))]
    |                                     ^^^^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:66:37
+  --> $DIR/attribute.rs:64:37
    |
 LL | #[proc_macro_derive(d15, attributes(m::a))]
    |                                     ^^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:70:37
+  --> $DIR/attribute.rs:68:37
    |
 LL | #[proc_macro_derive(d16, attributes(a(b)))]
    |                                     ^^^^
 
 error: `self` cannot be a name of derive helper attribute
-  --> $DIR/attribute.rs:74:37
+  --> $DIR/attribute.rs:72:37
    |
 LL | #[proc_macro_derive(d17, attributes(self))]
    |                                     ^^^^
 
-error: attribute must be of the form `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
+error: malformed `proc_macro_derive` attribute input
   --> $DIR/attribute.rs:9:1
    |
 LL | #[proc_macro_derive]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
 
-error: attribute must be of the form `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
-  --> $DIR/attribute.rs:13:1
+error: malformed `proc_macro_derive` attribute input
+  --> $DIR/attribute.rs:12:1
    |
 LL | #[proc_macro_derive = ""]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
 
 error: aborting due to 18 previous errors
 
diff --git a/src/test/ui/proc-macro/invalid-attributes.rs b/src/test/ui/proc-macro/invalid-attributes.rs
index c5ec4925e43..6bbe022c690 100644
--- a/src/test/ui/proc-macro/invalid-attributes.rs
+++ b/src/test/ui/proc-macro/invalid-attributes.rs
@@ -7,20 +7,20 @@ extern crate proc_macro;
 
 use proc_macro::TokenStream;
 
-#[proc_macro = "test"] //~ ERROR attribute must be of the form
+#[proc_macro = "test"] //~ ERROR malformed `proc_macro` attribute
 pub fn a(a: TokenStream) -> TokenStream { a }
 
-#[proc_macro()] //~ ERROR attribute must be of the form
+#[proc_macro()] //~ ERROR malformed `proc_macro` attribute
 pub fn c(a: TokenStream) -> TokenStream { a }
 
-#[proc_macro(x)] //~ ERROR attribute must be of the form
+#[proc_macro(x)] //~ ERROR malformed `proc_macro` attribute
 pub fn d(a: TokenStream) -> TokenStream { a }
 
-#[proc_macro_attribute = "test"] //~ ERROR attribute must be of the form
+#[proc_macro_attribute = "test"] //~ ERROR malformed `proc_macro_attribute` attribute
 pub fn e(_: TokenStream, a: TokenStream) -> TokenStream { a }
 
-#[proc_macro_attribute()] //~ ERROR attribute must be of the form
+#[proc_macro_attribute()] //~ ERROR malformed `proc_macro_attribute` attribute
 pub fn g(_: TokenStream, a: TokenStream) -> TokenStream { a }
 
-#[proc_macro_attribute(x)] //~ ERROR attribute must be of the form
+#[proc_macro_attribute(x)] //~ ERROR malformed `proc_macro_attribute` attribute
 pub fn h(_: TokenStream, a: TokenStream) -> TokenStream { a }
diff --git a/src/test/ui/proc-macro/invalid-attributes.stderr b/src/test/ui/proc-macro/invalid-attributes.stderr
index 8dff60d0dc5..fe411fa5e1f 100644
--- a/src/test/ui/proc-macro/invalid-attributes.stderr
+++ b/src/test/ui/proc-macro/invalid-attributes.stderr
@@ -1,38 +1,38 @@
-error: attribute must be of the form `#[proc_macro]`
+error: malformed `proc_macro` attribute input
   --> $DIR/invalid-attributes.rs:10:1
    |
 LL | #[proc_macro = "test"]
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]`
 
-error: attribute must be of the form `#[proc_macro]`
+error: malformed `proc_macro` attribute input
   --> $DIR/invalid-attributes.rs:13:1
    |
 LL | #[proc_macro()]
-   | ^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]`
 
-error: attribute must be of the form `#[proc_macro]`
+error: malformed `proc_macro` attribute input
   --> $DIR/invalid-attributes.rs:16:1
    |
 LL | #[proc_macro(x)]
-   | ^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]`
 
-error: attribute must be of the form `#[proc_macro_attribute]`
+error: malformed `proc_macro_attribute` attribute input
   --> $DIR/invalid-attributes.rs:19:1
    |
 LL | #[proc_macro_attribute = "test"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]`
 
-error: attribute must be of the form `#[proc_macro_attribute]`
+error: malformed `proc_macro_attribute` attribute input
   --> $DIR/invalid-attributes.rs:22:1
    |
 LL | #[proc_macro_attribute()]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]`
 
-error: attribute must be of the form `#[proc_macro_attribute]`
+error: malformed `proc_macro_attribute` attribute input
   --> $DIR/invalid-attributes.rs:25:1
    |
 LL | #[proc_macro_attribute(x)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]`
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/repr.rs b/src/test/ui/repr.rs
index 9d844745f42..564d6732601 100644
--- a/src/test/ui/repr.rs
+++ b/src/test/ui/repr.rs
@@ -1,13 +1,10 @@
-#[repr]
-//~^ ERROR attribute must be of the form
+#[repr] //~ ERROR malformed `repr` attribute
 struct _A {}
 
-#[repr = "B"]
-//~^ ERROR attribute must be of the form
+#[repr = "B"] //~ ERROR malformed `repr` attribute
 struct _B {}
 
-#[repr = "C"]
-//~^ ERROR attribute must be of the form
+#[repr = "C"] //~ ERROR malformed `repr` attribute
 struct _C {}
 
 #[repr(C)]
diff --git a/src/test/ui/repr.stderr b/src/test/ui/repr.stderr
index 7ebfe083ddd..e756510a437 100644
--- a/src/test/ui/repr.stderr
+++ b/src/test/ui/repr.stderr
@@ -1,20 +1,20 @@
-error: attribute must be of the form `#[repr(C, packed, ...)]`
+error: malformed `repr` attribute input
   --> $DIR/repr.rs:1:1
    |
 LL | #[repr]
-   | ^^^^^^^
+   | ^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
-error: attribute must be of the form `#[repr(C, packed, ...)]`
-  --> $DIR/repr.rs:5:1
+error: malformed `repr` attribute input
+  --> $DIR/repr.rs:4:1
    |
 LL | #[repr = "B"]
-   | ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
-error: attribute must be of the form `#[repr(C, packed, ...)]`
-  --> $DIR/repr.rs:9:1
+error: malformed `repr` attribute input
+  --> $DIR/repr.rs:7:1
    |
 LL | #[repr = "C"]
-   | ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs b/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs
index 3375210fc59..b7938e1afa3 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs
+++ b/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs
@@ -1,7 +1,7 @@
 #![feature(non_exhaustive)]
 
 #[non_exhaustive(anything)]
-//~^ ERROR attribute must be of the form
+//~^ ERROR malformed `non_exhaustive` attribute
 struct Foo;
 
 #[non_exhaustive]
diff --git a/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr b/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr
index ff082e6fc42..21dc340d212 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[non_exhaustive]`
+error: malformed `non_exhaustive` attribute input
   --> $DIR/invalid-attribute.rs:3:1
    |
 LL | #[non_exhaustive(anything)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]`
 
 error[E0701]: attribute can only be applied to a struct or enum
   --> $DIR/invalid-attribute.rs:7:1
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity-4.rs b/src/test/ui/stability-attribute/stability-attribute-sanity-4.rs
index 3fd54bc02e4..c64899c1e92 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity-4.rs
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity-4.rs
@@ -5,24 +5,24 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 mod bogus_attribute_types_2 {
-    #[unstable] //~ ERROR attribute must be of the form
+    #[unstable] //~ ERROR malformed `unstable` attribute
     fn f1() { }
 
-    #[unstable = "b"] //~ ERROR attribute must be of the form
+    #[unstable = "b"] //~ ERROR malformed `unstable` attribute
     fn f2() { }
 
-    #[stable] //~ ERROR attribute must be of the form
+    #[stable] //~ ERROR malformed `stable` attribute
     fn f3() { }
 
-    #[stable = "a"] //~ ERROR attribute must be of the form
+    #[stable = "a"] //~ ERROR malformed `stable` attribute
     fn f4() { }
 
     #[stable(feature = "a", since = "b")]
-    #[rustc_deprecated] //~ ERROR attribute must be of the form
+    #[rustc_deprecated] //~ ERROR malformed `rustc_deprecated` attribute
     fn f5() { }
 
     #[stable(feature = "a", since = "b")]
-    #[rustc_deprecated = "a"] //~ ERROR attribute must be of the form
+    #[rustc_deprecated = "a"] //~ ERROR malformed `rustc_deprecated` attribute
     fn f6() { }
 }
 
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity-4.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity-4.stderr
index d85b628c3c3..9d23b344ed1 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity-4.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity-4.stderr
@@ -1,38 +1,38 @@
-error: attribute must be of the form `#[unstable(feature = "name", reason = "...", issue = "N")]`
+error: malformed `unstable` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:8:5
    |
 LL |     #[unstable]
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]`
 
-error: attribute must be of the form `#[unstable(feature = "name", reason = "...", issue = "N")]`
+error: malformed `unstable` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:11:5
    |
 LL |     #[unstable = "b"]
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]`
 
-error: attribute must be of the form `#[stable(feature = "name", since = "version")]`
+error: malformed `stable` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:14:5
    |
 LL |     #[stable]
-   |     ^^^^^^^^^
+   |     ^^^^^^^^^ help: must be of the form: `#[stable(feature = "name", since = "version")]`
 
-error: attribute must be of the form `#[stable(feature = "name", since = "version")]`
+error: malformed `stable` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:17:5
    |
 LL |     #[stable = "a"]
-   |     ^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^ help: must be of the form: `#[stable(feature = "name", since = "version")]`
 
-error: attribute must be of the form `#[rustc_deprecated(since = "version", reason = "...")]`
+error: malformed `rustc_deprecated` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:21:5
    |
 LL |     #[rustc_deprecated]
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_deprecated(since = "version", reason = "...")]`
 
-error: attribute must be of the form `#[rustc_deprecated(since = "version", reason = "...")]`
+error: malformed `rustc_deprecated` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:25:5
    |
 LL |     #[rustc_deprecated = "a"]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_deprecated(since = "version", reason = "...")]`
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/target-feature-wrong.rs b/src/test/ui/target-feature-wrong.rs
index ddae8870905..ac02c9cc648 100644
--- a/src/test/ui/target-feature-wrong.rs
+++ b/src/test/ui/target-feature-wrong.rs
@@ -14,22 +14,26 @@
 #![feature(target_feature)]
 
 #[target_feature = "+sse2"]
-//~^ ERROR: must be of the form
+//~^ ERROR malformed `target_feature` attribute
 #[target_feature(enable = "foo")]
-//~^ ERROR: not valid for this target
+//~^ ERROR not valid for this target
+//~| NOTE `foo` is not valid for this target
 #[target_feature(bar)]
-//~^ ERROR: only accepts sub-keys
+//~^ ERROR malformed `target_feature` attribute
 #[target_feature(disable = "baz")]
-//~^ ERROR: only accepts sub-keys
+//~^ ERROR malformed `target_feature` attribute
 unsafe fn foo() {}
 
 #[target_feature(enable = "sse2")]
-//~^ ERROR: can only be applied to `unsafe` function
+//~^ ERROR #[target_feature(..)] can only be applied to `unsafe` functions
+//~| NOTE can only be applied to `unsafe` functions
 fn bar() {}
+//~^ NOTE not an `unsafe` function
 
 #[target_feature(enable = "sse2")]
-//~^ ERROR: should be applied to a function
+//~^ ERROR attribute should be applied to a function
 mod another {}
+//~^ NOTE not a function
 
 #[inline(always)]
 //~^ ERROR: cannot use #[inline(always)]
diff --git a/src/test/ui/target-feature-wrong.stderr b/src/test/ui/target-feature-wrong.stderr
index 3662ea976a4..ff9678efddd 100644
--- a/src/test/ui/target-feature-wrong.stderr
+++ b/src/test/ui/target-feature-wrong.stderr
@@ -1,35 +1,38 @@
-error: attribute must be of the form `#[target_feature(enable = "name")]`
+error: malformed `target_feature` attribute input
   --> $DIR/target-feature-wrong.rs:16:1
    |
 LL | #[target_feature = "+sse2"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]`
 
 error: the feature named `foo` is not valid for this target
   --> $DIR/target-feature-wrong.rs:18:18
    |
 LL | #[target_feature(enable = "foo")]
-   |                  ^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^ `foo` is not valid for this target
 
-error: #[target_feature(..)] only accepts sub-keys of `enable` currently
-  --> $DIR/target-feature-wrong.rs:20:18
+error: malformed `target_feature` attribute input
+  --> $DIR/target-feature-wrong.rs:21:18
    |
 LL | #[target_feature(bar)]
-   |                  ^^^
+   |                  ^^^ help: must be of the form: `enable = ".."`
 
-error: #[target_feature(..)] only accepts sub-keys of `enable` currently
-  --> $DIR/target-feature-wrong.rs:22:18
+error: malformed `target_feature` attribute input
+  --> $DIR/target-feature-wrong.rs:23:18
    |
 LL | #[target_feature(disable = "baz")]
-   |                  ^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
 
-error: #[target_feature(..)] can only be applied to `unsafe` function
-  --> $DIR/target-feature-wrong.rs:26:1
+error: #[target_feature(..)] can only be applied to `unsafe` functions
+  --> $DIR/target-feature-wrong.rs:27:1
    |
 LL | #[target_feature(enable = "sse2")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions
+...
+LL | fn bar() {}
+   | ----------- not an `unsafe` function
 
 error: attribute should be applied to a function
-  --> $DIR/target-feature-wrong.rs:30:1
+  --> $DIR/target-feature-wrong.rs:33:1
    |
 LL | #[target_feature(enable = "sse2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -38,7 +41,7 @@ LL | mod another {}
    | -------------- not a function
 
 error: cannot use #[inline(always)] with #[target_feature]
-  --> $DIR/target-feature-wrong.rs:34:1
+  --> $DIR/target-feature-wrong.rs:38:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^