From 5f8c571e50f1e0e98bb225e1dc909e73251a69be Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 16 Sep 2021 17:48:06 -0700 Subject: [PATCH] Move malformed attribute code to a function and fix inner attribute suggestion. Moving to a dedicated function in preparation for other validation. The suggestion given didn't consider if it was an inner attribute. --- compiler/rustc_parse/src/validate_attr.rs | 119 +++++++++--------- .../attributes/register-attr-tool-fail.stderr | 4 +- src/test/ui/gated-bad-feature.stderr | 4 +- src/test/ui/invalid_crate_type_syntax.stderr | 2 +- src/test/ui/lint/lint-malformed.stderr | 2 +- .../ui/malformed/malformed-plugin-1.stderr | 2 +- .../ui/malformed/malformed-plugin-2.stderr | 2 +- src/test/ui/no_crate_type.stderr | 2 +- 8 files changed, 69 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 67695dc2850..6e798fc5c20 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -91,69 +91,11 @@ pub fn check_builtin_attribute( // Some special attributes like `cfg` must be checked // before the generic check, so we skip them here. let should_skip = |name| name == sym::cfg; - // Some of previously accepted forms were used in practice, - // report them as warnings for now. - let should_warn = |name| { - name == sym::doc - || name == sym::ignore - || name == sym::inline - || name == sym::link - || name == sym::test - || name == sym::bench - }; match parse_meta(sess, attr) { Ok(meta) => { if !should_skip(name) && !is_attr_template_compatible(&template, &meta.kind) { - 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; - 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; - 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 "); - } - let code = format!("#[{} = \"{}\"]", name, descr); - msg.push_str(&format!("`{}`", &code)); - suggestions.push(code); - } - if should_warn(name) { - sess.buffer_lint( - &ILL_FORMED_ATTRIBUTE_INPUT, - meta.span, - ast::CRATE_NODE_ID, - &msg, - ); - } else { - 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(); - } + emit_malformed_attribute(sess, attr, name, template); } } Err(mut err) => { @@ -161,3 +103,62 @@ pub fn check_builtin_attribute( } } } + +fn emit_malformed_attribute( + sess: &ParseSess, + attr: &Attribute, + name: Symbol, + template: AttributeTemplate, +) { + // Some of previously accepted forms were used in practice, + // report them as warnings for now. + let should_warn = |name| { + matches!(name, sym::doc | sym::ignore | sym::inline | sym::link | sym::test | sym::bench) + }; + + 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; + let inner = if attr.style == ast::AttrStyle::Inner { "!" } else { "" }; + if template.word { + first = false; + let code = format!("#{}[{}]", inner, name); + msg.push_str(&format!("`{}`", &code)); + suggestions.push(code); + } + if let Some(descr) = template.list { + if !first { + msg.push_str(" or "); + } + first = false; + let code = format!("#{}[{}({})]", inner, name, descr); + msg.push_str(&format!("`{}`", &code)); + suggestions.push(code); + } + if let Some(descr) = template.name_value_str { + if !first { + msg.push_str(" or "); + } + let code = format!("#{}[{} = \"{}\"]", inner, name, descr); + msg.push_str(&format!("`{}`", &code)); + suggestions.push(code); + } + if should_warn(name) { + sess.buffer_lint(&ILL_FORMED_ATTRIBUTE_INPUT, attr.span, ast::CRATE_NODE_ID, &msg); + } else { + sess.span_diagnostic + .struct_span_err(attr.span, &error_msg) + .span_suggestions( + attr.span, + if suggestions.len() == 1 { + "must be of the form" + } else { + "the following are the possible correct uses" + }, + suggestions.into_iter(), + Applicability::HasPlaceholders, + ) + .emit(); + } +} diff --git a/src/test/ui/attributes/register-attr-tool-fail.stderr b/src/test/ui/attributes/register-attr-tool-fail.stderr index 77acfcd87cf..8f6977cb55f 100644 --- a/src/test/ui/attributes/register-attr-tool-fail.stderr +++ b/src/test/ui/attributes/register-attr-tool-fail.stderr @@ -30,13 +30,13 @@ error: malformed `register_attr` attribute input --> $DIR/register-attr-tool-fail.rs:4:1 | LL | #![register_attr] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[register_attr(attr1, attr2, ...)]` + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![register_attr(attr1, attr2, ...)]` error: malformed `register_tool` attribute input --> $DIR/register-attr-tool-fail.rs:5:1 | LL | #![register_tool] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[register_tool(tool1, tool2, ...)]` + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![register_tool(tool1, tool2, ...)]` error: aborting due to 6 previous errors diff --git a/src/test/ui/gated-bad-feature.stderr b/src/test/ui/gated-bad-feature.stderr index 79e59f76311..a8ec9391523 100644 --- a/src/test/ui/gated-bad-feature.stderr +++ b/src/test/ui/gated-bad-feature.stderr @@ -20,13 +20,13 @@ error: malformed `feature` attribute input --> $DIR/gated-bad-feature.rs:5:1 | LL | #![feature] - | ^^^^^^^^^^^ help: must be of the form: `#[feature(name1, name1, ...)]` + | ^^^^^^^^^^^ help: must be of the form: `#![feature(name1, name1, ...)]` error: malformed `feature` attribute input --> $DIR/gated-bad-feature.rs:6:1 | LL | #![feature = "foo"] - | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[feature(name1, name1, ...)]` + | ^^^^^^^^^^^^^^^^^^^ 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.stderr b/src/test/ui/invalid_crate_type_syntax.stderr index 92bed231586..4072a2fa162 100644 --- a/src/test/ui/invalid_crate_type_syntax.stderr +++ b/src/test/ui/invalid_crate_type_syntax.stderr @@ -2,7 +2,7 @@ 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|..."]` + | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]` error: aborting due to previous error diff --git a/src/test/ui/lint/lint-malformed.stderr b/src/test/ui/lint/lint-malformed.stderr index b3a41a786c1..91b4e509b26 100644 --- a/src/test/ui/lint/lint-malformed.stderr +++ b/src/test/ui/lint/lint-malformed.stderr @@ -14,7 +14,7 @@ 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 = "...")]` + | ^^^^^^^^^^^^^^^^ help: must be of the form: `#![deny(lint1, lint2, ..., /*opt*/ reason = "...")]` error[E0452]: malformed lint attribute input --> $DIR/lint-malformed.rs:2:10 diff --git a/src/test/ui/malformed/malformed-plugin-1.stderr b/src/test/ui/malformed/malformed-plugin-1.stderr index 98744434d4f..505f6b6f140 100644 --- a/src/test/ui/malformed/malformed-plugin-1.stderr +++ b/src/test/ui/malformed/malformed-plugin-1.stderr @@ -2,7 +2,7 @@ error: malformed `plugin` attribute input --> $DIR/malformed-plugin-1.rs:2:1 | LL | #![plugin] - | ^^^^^^^^^^ help: must be of the form: `#[plugin(name)]` + | ^^^^^^^^^^ help: must be of the form: `#![plugin(name)]` warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/malformed-plugin-1.rs:2:1 diff --git a/src/test/ui/malformed/malformed-plugin-2.stderr b/src/test/ui/malformed/malformed-plugin-2.stderr index 9bf0bf9345c..52bbd82a389 100644 --- a/src/test/ui/malformed/malformed-plugin-2.stderr +++ b/src/test/ui/malformed/malformed-plugin-2.stderr @@ -2,7 +2,7 @@ error: malformed `plugin` attribute input --> $DIR/malformed-plugin-2.rs:2:1 | LL | #![plugin="bleh"] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[plugin(name)]` + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![plugin(name)]` warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/malformed-plugin-2.rs:2:1 diff --git a/src/test/ui/no_crate_type.stderr b/src/test/ui/no_crate_type.stderr index f34df4e2dd1..93da7c3e0dd 100644 --- a/src/test/ui/no_crate_type.stderr +++ b/src/test/ui/no_crate_type.stderr @@ -2,7 +2,7 @@ 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|..."]` + | ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]` error: aborting due to previous error