diff options
| author | Stuart Cook <Zalathar@users.noreply.github.com> | 2025-09-29 21:06:44 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-29 21:06:44 +1000 |
| commit | cf07cce1fb79d9d9444fdf34a7c0c3b296a8be6f (patch) | |
| tree | 873c80284ba8d8eec34c2e4d43e1eb5ce82aa695 | |
| parent | 7af913fc90968844286e5ff6675ab66afa98cdc6 (diff) | |
| parent | b3631e1174e222bf1dadf1549cfd0f717ebf6d64 (diff) | |
| download | rust-cf07cce1fb79d9d9444fdf34a7c0c3b296a8be6f.tar.gz rust-cf07cce1fb79d9d9444fdf34a7c0c3b296a8be6f.zip | |
Rollup merge of #146653 - jdonszelmann:empty-attr-diags, r=nnethercote
improve diagnostics for empty attributes Adds a note about them not having any effect. This was previously done for `feature` attributes but no other attributes. In [converting the `feature` parser](https://github.com/rust-lang/rust/pull/146652) I removed that note. This PR adds it back in and makes it so all attributes benefit from it. Not blocked on rust-lang/rust#146652, either can merge first
| -rw-r--r-- | compiler/rustc_attr_parsing/messages.ftl | 10 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/context.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/lints.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/session_diagnostics.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/lints.rs | 15 | ||||
| -rw-r--r-- | tests/ui/attributes/empty-repr.stderr | 1 | ||||
| -rw-r--r-- | tests/ui/empty/empty-attributes.stderr | 4 | ||||
| -rw-r--r-- | tests/ui/macros/macro-use-all-and-none.stderr | 3 | ||||
| -rw-r--r-- | tests/ui/repr/repr-empty-packed.stderr | 1 |
9 files changed, 46 insertions, 16 deletions
diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 81ec17077c1..6c5346e8355 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -8,7 +8,15 @@ attr_parsing_deprecated_item_suggestion = attr_parsing_empty_attribute = unused attribute - .suggestion = remove this attribute + .suggestion = {$valid_without_list -> + [true] remove these parentheses + *[other] remove this attribute + } + .note = {$valid_without_list -> + [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all + *[other] using `{$attr_path}` with an empty list has no effect + } + attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target} .help = `#[{$name}]` can {$only}be applied to {$applied} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index d7ccf3c7806..e8bb4caa416 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -597,7 +597,12 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { } pub(crate) fn warn_empty_attribute(&mut self, span: Span) { - self.emit_lint(AttributeLintKind::EmptyAttribute { first_span: span }, span); + let attr_path = self.attr_path.clone(); + let valid_without_list = self.template.word; + self.emit_lint( + AttributeLintKind::EmptyAttribute { first_span: span, attr_path, valid_without_list }, + span, + ); } } diff --git a/compiler/rustc_attr_parsing/src/lints.rs b/compiler/rustc_attr_parsing/src/lints.rs index ab8ba0daf1f..3a2a3704669 100644 --- a/compiler/rustc_attr_parsing/src/lints.rs +++ b/compiler/rustc_attr_parsing/src/lints.rs @@ -43,12 +43,18 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emi ), }, ), - AttributeLintKind::EmptyAttribute { first_span } => lint_emitter.emit_node_span_lint( - rustc_session::lint::builtin::UNUSED_ATTRIBUTES, - *id, - *first_span, - session_diagnostics::EmptyAttributeList { attr_span: *first_span }, - ), + AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => { + lint_emitter.emit_node_span_lint( + rustc_session::lint::builtin::UNUSED_ATTRIBUTES, + *id, + *first_span, + session_diagnostics::EmptyAttributeList { + attr_span: *first_span, + attr_path: attr_path.clone(), + valid_without_list: *valid_without_list, + }, + ) + } AttributeLintKind::InvalidTarget { name, target, applied, only } => lint_emitter .emit_node_span_lint( // This check is here because `deprecated` had its own lint group and removing this would be a breaking change diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 2c2b14c8a68..1194ac5872c 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -503,9 +503,12 @@ pub(crate) struct EmptyConfusables { #[derive(LintDiagnostic)] #[diag(attr_parsing_empty_attribute)] +#[note] pub(crate) struct EmptyAttributeList { #[suggestion(code = "", applicability = "machine-applicable")] pub attr_span: Span, + pub attr_path: AttrPath, + pub valid_without_list: bool, } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_hir/src/lints.rs b/compiler/rustc_hir/src/lints.rs index b7a0a6a0c19..c9de6f6b5d5 100644 --- a/compiler/rustc_hir/src/lints.rs +++ b/compiler/rustc_hir/src/lints.rs @@ -31,6 +31,12 @@ pub struct AttributeLint<Id> { #[derive(Clone, Debug, HashStable_Generic)] pub enum AttributeLintKind { + /// Copy of `IllFormedAttributeInput` + /// specifically for the `invalid_macro_export_arguments` lint until that is removed, + /// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663> + InvalidMacroExportArguments { + suggestions: Vec<String>, + }, UnusedDuplicate { this: Span, other: Span, @@ -41,13 +47,8 @@ pub enum AttributeLintKind { }, EmptyAttribute { first_span: Span, - }, - - /// Copy of `IllFormedAttributeInput` - /// specifically for the `invalid_macro_export_arguments` lint until that is removed, - /// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663> - InvalidMacroExportArguments { - suggestions: Vec<String>, + attr_path: AttrPath, + valid_without_list: bool, }, InvalidTarget { name: AttrPath, diff --git a/tests/ui/attributes/empty-repr.stderr b/tests/ui/attributes/empty-repr.stderr index 92901fa170c..6dfa2df75b7 100644 --- a/tests/ui/attributes/empty-repr.stderr +++ b/tests/ui/attributes/empty-repr.stderr @@ -4,6 +4,7 @@ error: unused attribute LL | #[repr()] | ^^^^^^^^^ help: remove this attribute | + = note: using `repr` with an empty list has no effect note: the lint level is defined here --> $DIR/empty-repr.rs:4:9 | diff --git a/tests/ui/empty/empty-attributes.stderr b/tests/ui/empty/empty-attributes.stderr index f0be56ddc6a..41dc790737d 100644 --- a/tests/ui/empty/empty-attributes.stderr +++ b/tests/ui/empty/empty-attributes.stderr @@ -56,12 +56,16 @@ error: unused attribute | LL | #[repr()] | ^^^^^^^^^ help: remove this attribute + | + = note: using `repr` with an empty list has no effect error: unused attribute --> $DIR/empty-attributes.rs:12:1 | LL | #[target_feature()] | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | + = note: using `target_feature` with an empty list has no effect error: aborting due to 8 previous errors diff --git a/tests/ui/macros/macro-use-all-and-none.stderr b/tests/ui/macros/macro-use-all-and-none.stderr index a5efb065a21..b4c05adcb33 100644 --- a/tests/ui/macros/macro-use-all-and-none.stderr +++ b/tests/ui/macros/macro-use-all-and-none.stderr @@ -2,8 +2,9 @@ warning: unused attribute --> $DIR/macro-use-all-and-none.rs:7:12 | LL | #[macro_use()] - | ^^ help: remove this attribute + | ^^ help: remove these parentheses | + = note: using `macro_use` with an empty list is equivalent to not using a list at all note: the lint level is defined here --> $DIR/macro-use-all-and-none.rs:4:9 | diff --git a/tests/ui/repr/repr-empty-packed.stderr b/tests/ui/repr/repr-empty-packed.stderr index 6565b2e8c1d..adf32c95529 100644 --- a/tests/ui/repr/repr-empty-packed.stderr +++ b/tests/ui/repr/repr-empty-packed.stderr @@ -15,6 +15,7 @@ error: unused attribute LL | #[repr()] | ^^^^^^^^^ help: remove this attribute | + = note: using `repr` with an empty list has no effect note: the lint level is defined here --> $DIR/repr-empty-packed.rs:2:9 | |
